/* Neutrino-HD License: GPL (C) 2013 martii This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __USE_FILE_OFFSET64 #define __USE_FILE_OFFSET64 1 #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include static cSysLoad *instance = NULL; cSysLoad *cSysLoad::getInstance(void) { if (!instance) instance = new cSysLoad; return instance; } void *cSysLoad::Run(void *arg) { set_threadname("sysload"); class cSysLoad *caller = (class cSysLoad *)arg; unsigned long stat_idle = 0, stat_total = 0; while (caller->running) { std::ifstream in("/proc/stat"); if (in.is_open()) { std::string line; while (getline(in, line)) { unsigned long _stat_user, _stat_nice, _stat_system, _stat_idle; if (4 == sscanf(line.c_str(), "cpu %lu %lu %lu %lu", &_stat_user, &_stat_nice, &_stat_system, &_stat_idle)) { unsigned long _stat_total = _stat_user + _stat_nice + _stat_system + _stat_idle; if (stat_total) { unsigned long div = _stat_total - stat_total; if (!div) // prevent division by zero if previous stat_total is equal to new. break; caller->data_last = (int)(1000 - 1000 * (_stat_idle - stat_idle) / div); if (caller->data_avail < caller->data_size) { caller->data[caller->data_avail++] = caller->data_last; } else { memmove(caller->data, caller->data + 1, (caller->data_size - 1) * sizeof(int)); caller->data[caller->data_size - 1] = caller->data_last; } } stat_idle = _stat_idle; stat_total = _stat_total; break; } } in.close(); } timespec ts; clock_gettime(CLOCK_REALTIME, &ts); ts.tv_sec += caller->period; sem_timedwait(&caller->sem, &ts); } pthread_exit(NULL); } cSysLoad::cSysLoad(void) { data_last = -1; data_avail = 0; period = 5; data_size = 1800/period; data = new int[data_size]; for (unsigned int i = 0; i < data_size; i++) data[i] = -1; running = true; sem_init(&sem, 0, 0); if (pthread_create(&thr, NULL, Run, this)) running = false; } cSysLoad::~cSysLoad(void) { if (running) { running = false; sem_post(&sem); pthread_join(thr, NULL); } sem_destroy(&sem); delete[] data; }