Additional functions of policy and resource management.
[profile/ivi/ico-uxf-homescreen.git] / lib / system-controller / CicoSCSysResourceController.cpp
1 /*
2  * Copyright (c) 2013, TOYOTA MOTOR CORPORATION.
3  *
4  * This program is licensed under the terms and conditions of the
5  * Apache License, version 2.0.  The full text of the Apache License is at
6  * http://www.apache.org/licenses/LICENSE-2.0
7  *
8  */
9 #include <memory>
10 #include <iostream>
11 #include <fstream>
12 #include <cstdlib>
13 #include <cstdio>
14
15 #include <dirent.h>
16 #include <sys/types.h>
17 #include <sys/stat.h>
18
19 #include "CicoLog.h"
20 #include "CicoEvent.h"
21 #include "CicoEventInfo.h"
22 #include "CicoStateCore.h"
23 #include "CicoState.h"
24 #include "CicoHistoryState.h"
25 #include "CicoFinalState.h"
26 #include "CicoStateMachine.h"
27 #include "CicoStateMachineCreator.h"
28 #include "CicoSCSysResourceMonitor.h"
29 #include "CicoSCLifeCycleController.h"
30 #include "CicoSCSysResourceController.h"
31 #include "CicoSCConf.h"
32 #include "CicoSCSystemConfig.h"
33 #include <Ecore.h>
34 //#include <Ecore_Evas.h>
35
36 const int gEV1000 = 1000; // CPU event
37 const int gEV1001 = 1001; // MEMORY event
38
39 const string gstrSRCCPU_LOW  = "SRCCPU_LOW";
40 const string gstrSRCCPU_HIGH = "SRCCPU_HIGH";
41 const string gstrSRCMEM_LOW  = "SRCMEM_LOW";
42 const string gstrSRCMEM_HIGH = "SRCMEM_HIGH";
43
44 static const string gstrStateMachineFileName = "CicoSCSysResourceSM.json";
45
46 bool g_RC_LOG = false;
47 int  g_samplingWaitTimer = 200;
48
49 Ecore_Timer* g_SCResourceWatch = 0;
50 static Eina_Bool ico_SCResourceWatch(void *data)
51 {
52     if (g_RC_LOG) ICO_TRA("start data(%x)", data);
53     if ((NULL == data) || (0 == data)) {
54         if (g_RC_LOG) ICO_TRA("end");
55         return ECORE_CALLBACK_RENEW;
56     }
57     CicoSCSysResourceController* oCSCSRC = (CicoSCSysResourceController*)data;
58     oCSCSRC->watch();
59 //    double tVal = (double)g_samplingWaitTimer / 100;
60 //    ecore_timer_add(g_samplingWaitTimer, ico_SCResourceWatch, data);
61     if (g_RC_LOG) ICO_TRA("end");
62     return ECORE_CALLBACK_RENEW;
63 }
64
65
66 /**
67  * @brief constructor
68  */
69 CicoSCSysResourceController::CicoSCSysResourceController()
70 {
71     ICO_TRA("start");
72     m_cgrpCPU = 0;
73     m_cgrpMEM = 0;
74     m_cpu = -1;
75     m_mem = -1;
76     m_rConf = CicoSCSystemConfig::getInstance()->getResourceConf();
77     if (0 != m_rConf) {
78         g_RC_LOG = m_rConf->m_bLog;
79         if (-1 != m_rConf->m_sampling) {
80             g_samplingWaitTimer = m_rConf->m_sampling;
81         }
82     }
83     if (false == m_rConf->m_bDoIt) {
84         ICO_TRA("end");
85         return ;
86     }
87     // cpu,cpuacct cgroup init
88     init_cgroup();  // cgroup 
89     m_monitor = new CicoSCSysResourceMonitor();
90     CicoSCSystemConfig* CSCSC = CicoSCSystemConfig::getInstance();
91     string filePath(CSCSC->getDefaultConf()->confdir);
92     filePath += string("/");
93     filePath += gstrStateMachineFileName;
94
95     CicoStateMachineCreator csmc;
96     m_stt = csmc.createFile(filePath);
97     if ((CicoStateMachine*)0 == m_stt) {
98         ICO_ERR("state machine create error(%s)", filePath.c_str());
99         return;
100     }
101
102     m_SRCCPU_LOW  = new CicoSRCCPU_LOW(this);
103     m_SRCCPU_HIGH = new CicoSRCCPU_HIGH(this);
104     m_SRCMEM_LOW  = new CicoSRCMEM_LOW(this);
105     m_SRCMEM_HIGH = new CicoSRCMEM_HIGH(this);
106
107     CicoState* s = (CicoState*)m_stt->getState(gstrSRCCPU_LOW);
108     if ((CicoState*)0 != s) {
109         s->addEntryAction(m_SRCCPU_LOW);
110         s->addDoAction(m_SRCCPU_LOW);
111     }
112     s = (CicoState*)m_stt->getState(gstrSRCCPU_HIGH);
113     if ((CicoState*)0 != s) {
114         s->addEntryAction(m_SRCCPU_HIGH);
115         s->addDoAction(m_SRCCPU_HIGH);
116     }
117     s = (CicoState*)m_stt->getState(gstrSRCMEM_LOW);
118     if ((CicoState*)0 != s) {
119         s->addEntryAction(m_SRCMEM_LOW);
120         s->addDoAction(m_SRCMEM_LOW);
121     }
122     s = (CicoState*)m_stt->getState(gstrSRCMEM_HIGH);
123     if ((CicoState*)0 != s) {
124         s->addEntryAction(m_SRCMEM_HIGH);
125         s->addDoAction(m_SRCMEM_HIGH);
126     }
127     m_stt->start();
128     double tVal = (double)g_samplingWaitTimer / 100;
129 #if 1
130     ICO_TRA("ECORE_TIMER(%f)", tVal);
131     g_SCResourceWatch = ecore_timer_add(tVal, ico_SCResourceWatch, this);
132 #else
133     ICO_TRA("ECORE_TIMER(%f)", tVal);
134     g_SCResourceWatch = ecore_timer_add(tVal, ico_SCResourceWatch, 0);
135 #endif
136     ICO_TRA("end");
137 }
138
139 /**
140  * @brief destructor
141  */
142 CicoSCSysResourceController::~CicoSCSysResourceController()
143 {
144     ICO_TRA("start");
145     if (0 != g_SCResourceWatch) {
146         ecore_timer_del(g_SCResourceWatch);
147     }
148
149     if ((CicoStateMachine*)0 != m_stt) {
150         m_stt->stop();
151         delete m_stt;
152         m_stt = (CicoStateMachine*)0;
153         ICO_TRA("delete CicoStateMachine");
154     }
155
156     if ((CicoSRCCPU_LOW*)0 != m_SRCCPU_LOW) {
157         delete m_SRCCPU_LOW;
158         m_SRCCPU_LOW = (CicoSRCCPU_LOW*)0;
159         ICO_TRA("delete CicoSRCCPU_LOW");
160     }
161
162     if ((CicoSRCCPU_HIGH*)0 != m_SRCCPU_HIGH) {
163         delete m_SRCCPU_HIGH;
164         m_SRCCPU_HIGH = (CicoSRCCPU_HIGH*)0;
165         ICO_TRA("delete CicoSRCCPU_HIGH");
166     }
167
168     if ((CicoSRCMEM_LOW*)0 != m_SRCMEM_LOW) {
169         delete m_SRCMEM_LOW;
170         m_SRCMEM_LOW = (CicoSRCMEM_LOW*)0;
171         ICO_TRA("delete CicoSRCMEM_LOW");
172     }
173
174     if ((CicoSRCMEM_HIGH*)0 != m_SRCMEM_HIGH) {
175         delete m_SRCMEM_HIGH;
176         m_SRCMEM_HIGH = (CicoSRCMEM_HIGH*)0;
177         ICO_TRA("delete CicoSRCMEM_HIGH");
178     }
179
180     if ((CicoSCSysResourceMonitor*)0 != m_monitor) {
181         delete m_monitor;
182         m_monitor = (CicoSCSysResourceMonitor*)0;
183         ICO_TRA("delete CicoSCSysResourceMonitor");
184     }
185     ICO_TRA("end");
186 }
187
188 /**
189  * @brief watch
190  * @return true:change level false:no change
191  */
192 bool CicoSCSysResourceController::watch()
193 {
194     if (g_RC_LOG) ICO_TRA("start");
195     if ((CicoSCSysResourceMonitor*)0 == m_monitor) {
196         if (g_RC_LOG) ICO_TRA("end false");
197         return false;
198     }
199     bool r = false;
200     m_monitor->monitoring();
201     int cpu = m_monitor->getCPUuser(); // application cpu
202     if (-1 != cpu) {
203         cpu /= 100;
204         CicoEvent ev(gEV1000, cpu);
205         bool b = m_stt->eventEntry(ev);
206         if (g_RC_LOG) ICO_TRA("cpu %c, %d->%d", b? 't': 'f', m_cpu, cpu);
207         m_cpu = cpu;
208         r = true;
209     }
210     int mem = m_monitor->getUsageFreeMem(); // free memory
211     if (-1 != mem) {
212         mem = (10000 - mem)/100;  // free->used memory calc
213         CicoEvent ev(gEV1001, mem);
214         m_stt->eventEntry(ev);
215         m_mem = mem;
216         r = true;
217     }
218     if (g_RC_LOG) ICO_TRA("end %s", r? "true": "false");
219     return r;
220 }
221
222 /**
223  * @brief CPU share control request
224  * @param pulus true:level up / false level down
225  */
226 void CicoSCSysResourceController::resourceControlCPUShares(bool bHight)
227 {
228     ICO_TRA("start %s", bHight? "true": "false");
229     if ((NULL == m_rConf) || (false == m_rConf->m_bDoIt)) {
230         ICO_TRA("end");
231         return;
232     }
233     if (true == m_rConf->m_cpuCtrl.empty()) {
234         ICO_TRA("end");
235         return;
236     }
237     int newCgrpCPU = -1;
238     int sz = m_rConf->m_cpuCtrl.size();
239     for (int i = 0; i < sz; i++) {
240         if (true == m_RCCpuShares[i].empty()) { // write target none
241             continue; // next target
242         }
243         int sharesVal = -1; // initialize cpu.shares value
244         if (true == bHight) {
245             if (m_cgrpCPU < (int)m_rConf->m_cpuCtrl[i]->m_hight.size()) {
246                 sharesVal = m_rConf->m_cpuCtrl[i]->m_hight[m_cgrpCPU];
247                 newCgrpCPU = m_cgrpCPU + 1;
248                 ICO_DBG("m_hight[%d]=%d", m_cgrpCPU, sharesVal);
249             }
250         }
251         else {
252             if (0 != m_cgrpCPU) {
253                 int tmp = m_cgrpCPU - 1;
254                 if (tmp < (int)m_rConf->m_cpuCtrl[i]->m_low.size()) {
255                     sharesVal = m_rConf->m_cpuCtrl[i]->m_low[tmp];
256                     newCgrpCPU = tmp;
257                     ICO_DBG("m_low[%d]=%d", tmp, sharesVal);
258                 }
259             }
260         }
261         if (0 <= sharesVal) {
262             replaceCgroupFile(m_RCCpuShares[i], sharesVal);
263         }
264 //        else if (-9 == sharesVal) {
265 //        }
266     }
267     if (-1 != newCgrpCPU) { // control level value check
268         ICO_DBG("control level %d -> %d", m_cgrpCPU, newCgrpCPU);
269         m_cgrpCPU = newCgrpCPU; // set next control level
270     }
271     ICO_TRA("end");
272 }
273
274 bool CicoSCSysResourceController::replaceCgroupFile(const std::string& tgt,
275                                                     int val)
276 {
277     char sv[64];
278     sprintf(sv, "%d", val);
279     return replaceCgroupFile(tgt, sv);
280 }
281
282 bool CicoSCSysResourceController::replaceCgroupFile(const std::string& tgt,
283                                                     const char* val)
284 {
285     ICO_TRA("start");
286     if (true == tgt.empty()) {
287         ICO_TRA("end");
288         return false;
289     }
290     FILE *fp = fopen(tgt.c_str(), "wt");
291     if (0 == fp) {
292         ICO_TRA("end open error %s", tgt.c_str());
293         return false;
294     }
295     fprintf(fp, val);
296     fclose(fp);
297     ICO_TRA("end Cmd(echo %s > %s", val, tgt.c_str());
298     return true;
299 }
300
301 /**
302  * @brief memory limit control request
303  * @param pulus true:level up / false level down
304  */
305 void CicoSCSysResourceController::resourceControlMemLimit(bool bHight)
306 {
307     ICO_TRA("start");
308     if ((NULL == m_rConf) || (false == m_rConf->m_bDoIt)) {
309         ICO_TRA("end");
310         return;
311     }
312     // TODO mk_k coming soon
313     if (true == bHight) {
314         // coming soon
315         ICO_TRA("hight (true)");
316     }
317     else {
318         // coming soon
319         ICO_TRA("low (false)");
320     }
321 //    m_cgrpMEM++;
322     ICO_TRA("end");
323 }
324
325
326
327 /**
328  * @brief
329  *
330  */
331 bool CicoSCSysResourceController::entryCgroupCPU(int pid, int grpNo)
332 {
333     ICO_TRA("start pid(%d), cgrpNo(%d)", pid, grpNo);
334     if ((0 > grpNo) || ((int)m_RCCpuTasks.size() <= grpNo)) {
335         ICO_TRA("end %d", m_RCCpuTasks.size());
336         return false;
337     }
338 #if 1
339     struct stat statbuf;
340     char procdir[128];
341     sprintf(procdir, "/proc/%d/task", pid);
342     if (0 != stat(procdir, &statbuf)) {
343         ICO_TRA("end %s ng dir", procdir);
344         return false;
345     }
346     DIR *dp;
347     dp = opendir(procdir);
348     if(dp == NULL) {
349         ICO_TRA("end opendir error");
350         return false;
351     }
352     struct dirent *ent;
353     while((ent = readdir(dp)) != NULL){
354         if (0 != isdigit(ent->d_name[0])) {
355             ICO_DBG("echo %s > %s", ent->d_name, m_RCCpuTasks[grpNo].c_str());
356             replaceCgroupFile(m_RCCpuTasks[grpNo], ent->d_name);
357         }
358     }
359     closedir(dp);
360     ICO_TRA("end");
361     return true;
362 #else
363     return replaceCgroupFile(m_RCCpuTasks[grpNo], pid);
364 #endif
365 }
366
367 /**
368  * @brief initialize cgroup
369  */
370 void CicoSCSysResourceController::init_cgroup()
371 {
372     ICO_TRA("start");
373     init_cgroup_cpu();
374     // memory cgroup directory get
375     init_cgroup_memory();
376     ICO_TRA("end");
377 }
378
379 /**
380  * @brief initialize cgroup cpu
381  */
382 void CicoSCSysResourceController::init_cgroup_cpu()
383 {
384     ICO_TRA("start");
385     if ((NULL == m_rConf) || (false == m_rConf->m_bDoIt)) {
386         ICO_TRA("end");
387         return;
388     }
389     string ss("/");
390     string sTasks("tasks");
391     string sShares("cpu.shares");
392     string t1(m_rConf->m_cpuCGRPPath);
393     if ('/' != t1[t1.size()-1]) {
394         t1 += ss;
395     }
396     vector<string> d;
397     d.push_back(m_rConf->m_cpuCGRPPath);
398     int sz = m_rConf->m_cpuCtrl.size();
399     for (int i = 0; i < sz; i++) {
400         CicoSCCpuResourceGrp* obj = m_rConf->m_cpuCtrl[i];
401         string t2;
402         if (0 != obj) {
403             t2 = t1;
404             t2 += obj->m_grpNm;
405         }
406         else {
407             t2.clear();
408         }
409         d.push_back(t2);
410         string t3(t2);
411         string t4(t2);
412         if (false == t2.empty()) {
413             if ('/' != t2[t2.size()-1]) {
414                 t3 += ss;
415                 t4 += ss;
416             }
417             t3 += sTasks;
418             t4 += sShares;
419         }
420         m_RCCpuTasks.push_back(t3);
421         m_RCCpuShares.push_back(t4);
422     }
423     make_directorys(d);
424     ICO_TRA("end");
425     return;
426 }
427
428 /**
429  * @brief initialize cgroup memory
430  */
431 void CicoSCSysResourceController::init_cgroup_memory()
432 {
433     ICO_TRA("start");
434     if ((NULL == m_rConf) || (false == m_rConf->m_bDoIt)) {
435         ICO_TRA("end error config class");
436         return;
437     }
438     // Coming Soon
439     ICO_TRA("end");
440     return;
441 }
442
443 /**
444  * @brief make directory
445  * @param d create directory target
446  */
447 void CicoSCSysResourceController::make_directorys(std::vector<std::string> dir)
448 {
449     ICO_TRA("start");
450     int sz = dir.size();
451     for (int i = 0; i < sz; i++) {
452         if (true == dir[i].empty()) {
453             continue;
454         }
455         const char* dpath = dir[i].c_str();
456         struct stat stat_buf;
457         if (0 != stat(dpath, &stat_buf)) {
458             // drwxr-xr-x
459             int r = mkdir(dpath, S_IRUSR| S_IWUSR| S_IXUSR| S_IRGRP|
460                           S_IXGRP| S_IROTH| S_IXOTH);
461             ICO_DBG("%s create status(%d)", dpath, r);
462         }
463     }
464     ICO_TRA("end");
465 }
466
467 /**
468  * @brief Class ico System Resource Controller CPU LOW level
469  *        constructor
470  */
471 CicoSRCCPU_LOW::CicoSRCCPU_LOW(CicoSCSysResourceController* obj):
472     m_cntlr(obj)
473 {
474     ICO_TRA("constructor");
475     m_val = -1;      // cpu or memory usage value
476     m_baseVal = -1;  // cpu or memory base usage value
477     m_cnt = 0;
478     m_rConf = CicoSCSystemConfig::getInstance()->getResourceConf();
479 }
480
481 /**
482  * @brief Class ico System Resource Controller CPU LOW level
483  *        destructor
484  */
485 CicoSRCCPU_LOW::~CicoSRCCPU_LOW()
486 {
487     ICO_TRA("destructor");
488     m_cntlr = NULL;
489 }
490
491 /**
492  * @brief resource control entry state
493  * @param ev event data
494  * @param stt state object
495  */
496 void CicoSRCCPU_LOW::onEntry(const CicoEvent& ev, const CicoState* stt, int)
497 {
498     int v1 = ev.getEV();
499     int v2 = ev.getGCVi();
500     if (g_RC_LOG) ICO_TRA("start %s,%d,%d CicoSRCCPU_LOW::", stt->getName().c_str(), v1, v2);
501     m_baseVal = v2;
502     m_val = m_baseVal;
503     m_cnt = m_rConf->m_retryCnt;
504     if (g_RC_LOG) ICO_TRA("end cnt(%d) CicoSRCCPU_LOW::", m_cnt);
505 }
506
507 /**
508  * @brief cpu usage low resource control
509  * @param ev event data
510  * @param stt state object
511  */
512 void CicoSRCCPU_LOW::onDo(const CicoEvent& ev, const CicoState* stt, int)
513 {
514     int valN = ev.getGCVi();
515     if (g_RC_LOG) ICO_TRA("start o(%d), n(%d)CicoSRCCPU_LOW::", m_val, valN);
516 #if 0
517     if (valN > m_val) {
518         // When the value is greater than the previous
519         if (g_RC_LOG) ICO_TRA("end n(%d)->o(%d) CicoSRCCPU_LOW::", m_val, valN);
520         return;
521     }
522     // When the value is less than the previous
523     int t = ((double)valN / (double)m_baseVal)*100;
524     if (50 <= t) {
525         m_cntlr->resourceControlCPUShares(false);
526         if (g_RC_LOG) ICO_DBG("CHG %d->%d CicoSRCCPU_LOW::",m_baseVal, valN);
527         m_baseVal = valN;
528     }
529 #else
530     if (valN < m_rConf->m_lowLimitVal) {
531         m_cnt--;
532         if (0 >= m_cnt) {
533             m_cntlr->resourceControlCPUShares(false);
534             if (g_RC_LOG) ICO_DBG("CHG %d->%d CicoSRCCPU_LOW::",m_baseVal, valN);
535             m_cnt = m_rConf->m_retryCnt;
536             m_baseVal = valN;
537         }
538     }
539     else {
540         if (g_RC_LOG) ICO_DBG("cnt rst V(%d) CicoSRCCPU_LOW::", valN);
541         m_cnt = m_rConf->m_retryCnt;
542     }
543 #endif
544     m_val = valN;
545     if (g_RC_LOG) ICO_TRA("end CicoSRCCPU_LOW::");
546 }
547
548
549 /**
550  * @brief resource control exit state
551  * @param ev event data
552  * @param stt state object
553  */
554 void CicoSRCCPU_LOW::onExit(const CicoEvent&, const CicoState*, int)
555 {
556     if (g_RC_LOG) ICO_TRA("start CicoSRCCPU_LOW::");
557     m_baseVal = -1;
558     m_val = -1;
559     if (g_RC_LOG) ICO_TRA("end CicoSRCCPU_LOW::");
560 }
561
562 /**
563  * @brief Class ico System Resource Controller CPU HIGH level
564  *        constructor
565  */
566 CicoSRCCPU_HIGH::CicoSRCCPU_HIGH(CicoSCSysResourceController* obj):
567         CicoSRCCPU_LOW(obj)
568 {
569     ICO_TRA("constructor");
570 }
571
572 /**
573  * @brief Class ico System Resource Controller CPU HIGH level
574  *        destructor
575  */
576 CicoSRCCPU_HIGH::~CicoSRCCPU_HIGH()
577 {
578     ICO_TRA("destructor");
579 }
580
581 /**
582  * @brief cpu usage high resource control
583  * @param ev event data
584  * @param stt state object
585  */
586 void CicoSRCCPU_HIGH::onDo(const CicoEvent& ev, const CicoState* stt, int)
587 {
588     int valN = ev.getGCVi();
589     if (g_RC_LOG) ICO_TRA("start o(%d), n(%d) CicoSRCCPU_HIGH::", m_val, valN);
590 #if 0
591     if (valN <= m_val) {
592         // When the value is less than the previous
593         if (g_RC_LOG) ICO_TRA("n(%d)<=o(%d) CicoSRCCPU_HIGH::", valN, m_val);
594         return;
595     }
596     // When the value is greater than the previous
597     int t = ((double)(100-valN) / (double)(100-m_baseVal))*100;
598     if (50 <= t) {
599         m_cntlr->resourceControlCPUShares(true);
600         if (g_RC_LOG) ICO_DBG("%d->%d CicoSRCCPU_HIGH::", m_baseVal, valN);
601         m_baseVal = valN;
602     }
603 #else
604     if (valN > m_rConf->m_highLimitVal) {
605         m_cnt--;
606         if (g_RC_LOG) ICO_DBG("cnt(%d) CicoSRCCPU_HIGH::", m_cnt);
607         if (0 >= m_cnt) {
608             m_cntlr->resourceControlCPUShares(true);
609             if (g_RC_LOG) ICO_DBG("CicoSRCCPU_HIGH:: %d->%d",m_baseVal, valN);
610             m_cnt = m_rConf->m_retryCnt;
611             m_baseVal = valN;
612         }
613     }
614     else {
615         if (g_RC_LOG) ICO_DBG("CicoSRCCPU_HIGH:: (%d)", valN);
616         m_cnt = m_rConf->m_retryCnt;
617     }
618 #endif
619     m_val = valN;
620     if (g_RC_LOG) ICO_TRA("end CicoSRCCPU_HIGH::");
621 }
622
623 /**
624  * @brief Class ico System Resource Controller MEMory LOW level
625  *        constructor
626  */
627 CicoSRCMEM_LOW::CicoSRCMEM_LOW(CicoSCSysResourceController* obj):
628         CicoSRCCPU_LOW(obj)
629 {
630     ICO_TRA("constructor CicoSRCMEM_LOW::");
631 }
632
633 /**
634  * @brief Class ico System Resource Controller MEMory LOW level
635  *        constructor
636  */
637 CicoSRCMEM_LOW::~CicoSRCMEM_LOW()
638 {
639     ICO_TRA("destructor CicoSRCMEM_LOW::");
640 }
641
642 /**
643  * @brief memory usage low resource control
644  * @param ev event data
645  * @param stt state object
646  */
647 void CicoSRCMEM_LOW::onDo(const CicoEvent& ev, const CicoState* stt, int)
648 {
649     int valN = ev.getGCVi();
650     if (g_RC_LOG) ICO_TRA("start o(%d), n(%d)", m_val, valN);
651     if (valN >= m_val) {
652         // When the value is greater than the previous
653         if (g_RC_LOG) ICO_TRA("n(%d)>=o(%d)", valN, m_val);
654         return;
655     }
656     // When the value is less than the previous
657     int t = ((double)valN / (double)m_baseVal)*100;
658     if (50 <= t) {
659         m_cntlr->resourceControlMemLimit(false);
660         if (g_RC_LOG) ICO_TRA("BASE CHG %d->%d",m_baseVal, valN);
661         m_baseVal = valN;
662     }
663     m_val = valN;
664     if (g_RC_LOG) ICO_TRA("end");
665
666 }
667
668 /**
669  * @brief Class ico System Resource Controller MEMory HIGH level
670  *        constructor
671  */
672 CicoSRCMEM_HIGH::CicoSRCMEM_HIGH(CicoSCSysResourceController* obj):
673     CicoSRCCPU_LOW(obj)
674 {
675     ICO_TRA("constructor");
676 }
677
678 /**
679  * @brief Class ico System Resource Controller MEMory HIGH level
680  *        destructor
681  */
682 CicoSRCMEM_HIGH::~CicoSRCMEM_HIGH()
683 {
684     ICO_TRA("destructor");
685 }
686
687 /**
688  * @brief memory usage high resource control
689  * @param ev event data
690  * @param stt state object
691  */
692 void CicoSRCMEM_HIGH::onDo(const CicoEvent& ev, const CicoState* stt, int)
693 {
694     int valN = ev.getGCVi();
695     if (g_RC_LOG) ICO_TRA("start o(%d), n(%d)", m_val, valN);
696     if (valN <= m_val) {
697         // When the value is less than the previous
698         ICO_TRA("end");
699         return;
700     }
701     // When the value is greater than the previous
702     int t = ((double)(100-valN) / (double)(100-m_baseVal))*100;
703     if (50 <= t) {
704         m_cntlr->resourceControlMemLimit(true);
705         if (g_RC_LOG) ICO_TRA("BASE CHG %d -> %d", m_baseVal, valN);
706         m_baseVal = valN;
707     }
708     m_val = valN;
709     if (g_RC_LOG) ICO_TRA("end");
710 }