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