2 * Copyright (c) 2013, TOYOTA MOTOR CORPORATION.
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
16 #include <sys/types.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"
34 //#include <Ecore_Evas.h>
36 const int gEV1000 = 1000; // CPU event
37 const int gEV1001 = 1001; // MEMORY event
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";
44 static const string gstrStateMachineFileName = "CicoSCSysResourceSM.json";
46 bool g_RC_LOG = false;
47 int g_samplingWaitTimer = 200;
49 Ecore_Timer* g_SCResourceWatch = 0;
50 static Eina_Bool ico_SCResourceWatch(void *data)
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;
57 CicoSCSysResourceController* oCSCSRC = (CicoSCSysResourceController*)data;
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;
69 CicoSCSysResourceController::CicoSCSysResourceController()
76 m_rConf = CicoSCSystemConfig::getInstance()->getResourceConf();
78 g_RC_LOG = m_rConf->m_bLog;
79 if (-1 != m_rConf->m_sampling) {
80 g_samplingWaitTimer = m_rConf->m_sampling;
83 // cpu,cpuacct cgroup init
84 init_cgroup(); // cgroup
85 m_monitor = new CicoSCSysResourceMonitor();
86 CicoSCSystemConfig* CSCSC = CicoSCSystemConfig::getInstance();
87 string filePath(CSCSC->getDefaultConf()->confdir);
88 filePath += string("/");
89 filePath += gstrStateMachineFileName;
91 CicoStateMachineCreator csmc;
92 m_stt = csmc.createFile(filePath);
93 if ((CicoStateMachine*)0 == m_stt) {
94 ICO_ERR("state machine create error(%s)", filePath.c_str());
98 m_SRCCPU_LOW = new CicoSRCCPU_LOW(this);
99 m_SRCCPU_HIGH = new CicoSRCCPU_HIGH(this);
100 m_SRCMEM_LOW = new CicoSRCMEM_LOW(this);
101 m_SRCMEM_HIGH = new CicoSRCMEM_HIGH(this);
103 CicoState* s = (CicoState*)m_stt->getState(gstrSRCCPU_LOW);
104 if ((CicoState*)0 != s) {
105 s->addEntryAction(m_SRCCPU_LOW);
106 s->addDoAction(m_SRCCPU_LOW);
108 s = (CicoState*)m_stt->getState(gstrSRCCPU_HIGH);
109 if ((CicoState*)0 != s) {
110 s->addEntryAction(m_SRCCPU_HIGH);
111 s->addDoAction(m_SRCCPU_HIGH);
113 s = (CicoState*)m_stt->getState(gstrSRCMEM_LOW);
114 if ((CicoState*)0 != s) {
115 s->addEntryAction(m_SRCMEM_LOW);
116 s->addDoAction(m_SRCMEM_LOW);
118 s = (CicoState*)m_stt->getState(gstrSRCMEM_HIGH);
119 if ((CicoState*)0 != s) {
120 s->addEntryAction(m_SRCMEM_HIGH);
121 s->addDoAction(m_SRCMEM_HIGH);
124 double tVal = (double)g_samplingWaitTimer / 100;
126 ICO_TRA("ECORE_TIMER(%f)", tVal);
127 g_SCResourceWatch = ecore_timer_add(tVal, ico_SCResourceWatch, this);
129 ICO_TRA("ECORE_TIMER(%f)", tVal);
130 g_SCResourceWatch = ecore_timer_add(tVal, ico_SCResourceWatch, 0);
138 CicoSCSysResourceController::~CicoSCSysResourceController()
141 if (0 != g_SCResourceWatch) {
142 ecore_timer_del(g_SCResourceWatch);
145 if ((CicoStateMachine*)0 != m_stt) {
148 m_stt = (CicoStateMachine*)0;
149 ICO_TRA("delete CicoStateMachine");
152 if ((CicoSRCCPU_LOW*)0 != m_SRCCPU_LOW) {
154 m_SRCCPU_LOW = (CicoSRCCPU_LOW*)0;
155 ICO_TRA("delete CicoSRCCPU_LOW");
158 if ((CicoSRCCPU_HIGH*)0 != m_SRCCPU_HIGH) {
159 delete m_SRCCPU_HIGH;
160 m_SRCCPU_HIGH = (CicoSRCCPU_HIGH*)0;
161 ICO_TRA("delete CicoSRCCPU_HIGH");
164 if ((CicoSRCMEM_LOW*)0 != m_SRCMEM_LOW) {
166 m_SRCMEM_LOW = (CicoSRCMEM_LOW*)0;
167 ICO_TRA("delete CicoSRCMEM_LOW");
170 if ((CicoSRCMEM_HIGH*)0 != m_SRCMEM_HIGH) {
171 delete m_SRCMEM_HIGH;
172 m_SRCMEM_HIGH = (CicoSRCMEM_HIGH*)0;
173 ICO_TRA("delete CicoSRCMEM_HIGH");
176 if ((CicoSCSysResourceMonitor*)0 != m_monitor) {
178 m_monitor = (CicoSCSysResourceMonitor*)0;
179 ICO_TRA("delete CicoSCSysResourceMonitor");
186 * @return true:change level false:no change
188 bool CicoSCSysResourceController::watch()
190 if (g_RC_LOG) ICO_TRA("start");
191 if ((CicoSCSysResourceMonitor*)0 == m_monitor) {
192 if (g_RC_LOG) ICO_TRA("end false");
196 m_monitor->monitoring();
197 int cpu = m_monitor->getCPUuser(); // application cpu
200 if (g_RC_LOG) ICO_TRA("cpu %d -> %d", m_cpu, cpu);
201 CicoEvent ev(gEV1000, cpu);
202 m_stt->eventEntry(ev);
206 int mem = m_monitor->getUsageFreeMem(); // free memory
208 mem = (10000 - mem)/100; // free->used memory calc
209 CicoEvent ev(gEV1001, mem);
210 m_stt->eventEntry(ev);
214 if (g_RC_LOG) ICO_TRA("end %s", r? "true": "false");
219 * @brief CPU share control request
220 * @param pulus true:level up / false level down
222 void CicoSCSysResourceController::resourceControlCPUShares(bool bHight)
225 bHight? "true": "false");
226 if ((NULL == m_rConf) || (false == m_rConf->m_bDoIt)) {
230 if (true == m_rConf->m_cpuCtrl.empty()) {
235 int sz = m_rConf->m_cpuCtrl.size();
236 for (int i = 0; i < sz; i++) {
237 if (true == m_RCCpuShares[i].empty()) { // write target none
238 continue; // next target
240 int sharesVal = -1; // initialize cpu.shares value
241 if (true == bHight) {
242 if (m_cgrpCPU < (int)m_rConf->m_cpuCtrl[i]->m_hight.size()) {
243 sharesVal = m_rConf->m_cpuCtrl[i]->m_hight[m_cgrpCPU];
244 newCgrpCPU = m_cgrpCPU + 1;
245 ICO_DBG("m_hight[%d]=%d", m_cgrpCPU, sharesVal);
249 if (0 != m_cgrpCPU) {
250 int tmp = m_cgrpCPU - 1;
251 if (tmp < (int)m_rConf->m_cpuCtrl[i]->m_low.size()) {
252 sharesVal = m_rConf->m_cpuCtrl[i]->m_low[tmp];
254 ICO_DBG("m_low[%d]=%d", tmp, sharesVal);
258 if (0 <= sharesVal) {
259 replaceCgroupFile(m_RCCpuShares[i], sharesVal);
261 // else if (-9 == sharesVal) {
264 if (-1 != newCgrpCPU) { // control level value check
265 ICO_DBG("control level %d -> %d", m_cgrpCPU, newCgrpCPU);
266 m_cgrpCPU = newCgrpCPU; // set next control level
271 bool CicoSCSysResourceController::replaceCgroupFile(const std::string& tgt,
275 sprintf(sv, "%d", val);
276 return replaceCgroupFile(tgt, sv);
279 bool CicoSCSysResourceController::replaceCgroupFile(const std::string& tgt,
283 if (true == tgt.empty()) {
287 FILE *fp = fopen(tgt.c_str(), "wt");
289 ICO_TRA("end open error %s", tgt.c_str());
294 ICO_TRA("end Cmd(echo %s > %s", val, tgt.c_str());
299 * @brief memory limit control request
300 * @param pulus true:level up / false level down
302 void CicoSCSysResourceController::resourceControlMemLimit(bool bHight)
305 if ((NULL == m_rConf) || (false == m_rConf->m_bDoIt)) {
309 // TODO mk_k coming soon
310 if (true == bHight) {
312 ICO_TRA("hight (true)");
316 ICO_TRA("low (false)");
328 bool CicoSCSysResourceController::entryCgroupCPU(int pid, int grpNo)
330 ICO_TRA("start pid(%d), cgrpNo(%d)", pid, grpNo);
331 if ((0 > grpNo) || ((int)m_RCCpuTasks.size() <= grpNo)) {
332 ICO_TRA("end %d", m_RCCpuTasks.size());
338 sprintf(procdir, "/proc/%d/task", pid);
339 if (0 != stat(procdir, &statbuf)) {
340 ICO_TRA("end %s ng dir", procdir);
344 dp = opendir(procdir);
346 ICO_TRA("end opendir error");
350 while((ent = readdir(dp)) != NULL){
351 if (0 != isdigit(ent->d_name[0])) {
352 ICO_DBG("echo %s > %s", ent->d_name, m_RCCpuTasks[grpNo].c_str());
353 replaceCgroupFile(m_RCCpuTasks[grpNo], ent->d_name);
360 return replaceCgroupFile(m_RCCpuTasks[grpNo], pid);
365 * @breif initialize cgroup
367 void CicoSCSysResourceController::init_cgroup()
371 // memory cgroup directory get
372 init_cgroup_memory();
377 * @breif initialize cgroup cpu
379 void CicoSCSysResourceController::init_cgroup_cpu()
382 if (NULL == m_rConf) {
387 string sTasks("tasks");
388 string sShares("cpu.shares");
389 string t1(m_rConf->m_cpuCGRPPath);
390 if ('/' != t1[t1.size()-1]) {
394 d.push_back(m_rConf->m_cpuCGRPPath);
395 int sz = m_rConf->m_cpuCtrl.size();
396 for (int i = 0; i < sz; i++) {
397 CicoSCCpuResourceGrp* obj = m_rConf->m_cpuCtrl[i];
409 if (false == t2.empty()) {
410 if ('/' != t2[t2.size()-1]) {
417 m_RCCpuTasks.push_back(t3);
418 m_RCCpuShares.push_back(t4);
426 * @breif initialize cgroup memory
428 void CicoSCSysResourceController::init_cgroup_memory()
431 if (NULL == m_rConf) {
432 ICO_TRA("end error config class");
441 * @breif make directory
442 * @param d create directory target
444 void CicoSCSysResourceController::make_directorys(std::vector<std::string> dir)
448 for (int i = 0; i < sz; i++) {
449 if (true == dir[i].empty()) {
452 const char* dpath = dir[i].c_str();
453 struct stat stat_buf;
454 if (0 != stat(dpath, &stat_buf)) {
456 int r = mkdir(dpath, S_IRUSR| S_IWUSR| S_IXUSR| S_IRGRP|
457 S_IXGRP| S_IROTH| S_IXOTH);
458 ICO_DBG("%s create status(%d)", dpath, r);
465 * @brief Class ico System Resource Controller CPU LOW level
468 CicoSRCCPU_LOW::CicoSRCCPU_LOW(CicoSCSysResourceController* obj):
471 ICO_TRA("constructor");
472 m_val = -1; // cpu or memory usage value
473 m_baseVal = -1; // cpu or memory base usage value
477 * @brief Class ico System Resource Controller CPU LOW level
480 CicoSRCCPU_LOW::~CicoSRCCPU_LOW()
482 ICO_TRA("destructor");
487 * @brief resource control entry state
488 * @param ev event data
489 * @param stt state object
491 void CicoSRCCPU_LOW::onEnttry(const CicoEvent& ev, const CicoState* stt, int)
493 ICO_TRA("start %s,%d,%d", stt->getName().c_str(),
494 ev.getEV(),ev.getGCVi());
495 m_baseVal = ev.getGCVi();
500 * @brief cpu usage low resource control
501 * @param ev event data
502 * @param stt state object
504 void CicoSRCCPU_LOW::onDo(const CicoEvent& ev, const CicoState* stt, int)
506 int valN = ev.getGCVi();
507 ICO_TRA("start o(%d), n(%d)", m_val, valN);
509 // When the value is greater than the previous
510 ICO_TRA("end n(%d) >= o(%d)", m_val, valN);
513 // When the value is less than the previous
514 int t = ((double)valN / (double)m_baseVal)*100;
516 m_cntlr->resourceControlCPUShares(false);
517 ICO_DBG("BASE CHG %d->%d",m_baseVal, valN);
526 * @brief resource control exit state
527 * @param ev event data
528 * @param stt state object
530 void CicoSRCCPU_LOW::onExit(const CicoEvent&, const CicoState*, int)
539 * @brief Class ico System Resource Controller CPU HIGH level
542 CicoSRCCPU_HIGH::CicoSRCCPU_HIGH(CicoSCSysResourceController* obj):
545 ICO_TRA("constructor");
549 * @brief Class ico System Resource Controller CPU HIGH level
552 CicoSRCCPU_HIGH::~CicoSRCCPU_HIGH()
554 ICO_TRA("destructor");
558 * @brief cpu usage high resource control
559 * @param ev event data
560 * @param stt state object
562 void CicoSRCCPU_HIGH::onDo(const CicoEvent& ev, const CicoState* stt, int)
564 int valN = ev.getGCVi();
565 ICO_TRA("start o(%d), n(%d)", m_val, valN);
567 // When the value is less than the previous
568 ICO_TRA("end n(%d)<=o(%d)", valN, m_val);
571 // When the value is greater than the previous
572 int t = ((double)(100-valN) / (double)(100-m_baseVal))*100;
574 m_cntlr->resourceControlCPUShares(true);
575 ICO_DBG("BASE CHG %d -> %d", m_baseVal, valN);
583 * @brief Class ico System Resource Controller MEMory LOW level
586 CicoSRCMEM_LOW::CicoSRCMEM_LOW(CicoSCSysResourceController* obj):
589 ICO_TRA("constructor");
593 * @brief Class ico System Resource Controller MEMory LOW level
596 CicoSRCMEM_LOW::~CicoSRCMEM_LOW()
598 ICO_TRA("destructor");
602 * @brief memory usage low resource control
603 * @param ev event data
604 * @param stt state object
606 void CicoSRCMEM_LOW::onDo(const CicoEvent& ev, const CicoState* stt, int)
608 int valN = ev.getGCVi();
609 ICO_TRA("start o(%d), n(%d)", m_val, valN);
611 // When the value is greater than the previous
612 ICO_TRA("n(%d)>=o(%d)", valN, m_val);
615 // When the value is less than the previous
616 int t = ((double)valN / (double)m_baseVal)*100;
618 m_cntlr->resourceControlMemLimit(false);
619 ICO_TRA("BASE CHG %d->%d",m_baseVal, valN);
628 * @brief Class ico System Resource Controller MEMory HIGH level
631 CicoSRCMEM_HIGH::CicoSRCMEM_HIGH(CicoSCSysResourceController* obj):
634 ICO_TRA("constructor");
638 * @brief Class ico System Resource Controller MEMory HIGH level
641 CicoSRCMEM_HIGH::~CicoSRCMEM_HIGH()
643 ICO_TRA("destructor");
647 * @brief memory usage high resource control
648 * @param ev event data
649 * @param stt state object
651 void CicoSRCMEM_HIGH::onDo(const CicoEvent& ev, const CicoState* stt, int)
653 int valN = ev.getGCVi();
654 ICO_TRA("start o(%d), n(%d)", m_val, valN);
656 // When the value is less than the previous
660 // When the value is greater than the previous
661 int t = ((double)(100-valN) / (double)(100-m_baseVal))*100;
663 m_cntlr->resourceControlMemLimit(true);
664 ICO_TRA("BASE CHG %d -> %d", m_baseVal, valN);