25 #include <IceUtil/Handle.h>
27 #include <SimoxUtility/algorithm/string/string_tools.h>
30 #include <ext/alloc_traits.h>
35 #include <unordered_set>
41 #include "ArmarXCore/interface/core/ThreadingIceBase.h"
43 #include "../exceptions/local/ExpressionException.h"
47 #include <sys/utsname.h>
57 Hertz = sysconf(_SC_CLK_TCK);
59 ss <<
"/proc/" << pid <<
"/stat";
60 processCpuDataFilename = ss.str();
62 cpuUsageFromProcFile();
78 watcherTask =
nullptr;
84 std::unique_lock lock(threadWatchListMutex);
91 threadWatchList.insert(usage);
99 void ProcessWatcher::watch()
102 runThreadWatchList();
103 cpuUsageFromProcFile();
109 void ProcessWatcher::runThreadWatchList()
112 std::unique_lock lock(threadWatchListMutex);
113 std::unordered_set<ThreadUsage> newset;
114 std::unordered_set<ThreadUsage>::iterator it = threadWatchList.begin();
116 for (; it != threadWatchList.end(); it++)
119 ThreadUsage usage = *it;
125 usage.load = (curJiffies - usage.lastJiffies) / ((queryTime - usage.lastUpdate).toSecondsDouble() *
GetHertz());
132 usage.lastJiffies = curJiffies;
133 usage.lastUpdate = queryTime;
134 newset.insert(usage);
137 threadWatchList.swap(newset);
141 #if !defined(_WIN32) && !defined(__APPLE__)
145 static std::mutex mutex;
146 std::unique_lock lock(mutex);
147 static int value = -2;
152 static std::string _release;
154 if (_release.empty())
156 struct utsname utsinfo;
158 _release = utsinfo.release;
161 std::string fileName =
"/boot/config-" + _release;
162 std::ifstream configFile(fileName.c_str());
166 if (!configFile.is_open())
168 ARMARX_WARNING_S <<
"Cannot open " << fileName <<
" for reading the cpu hertz value";
175 const std::string searchString =
"CONFIG_HZ=";
177 while (getline(configFile, line))
180 std::size_t pos = line.find(searchString);
182 if (pos != std::string::npos)
184 std::string hzString = line.substr(pos + searchString.length());
185 value = std::stoi(hzString);
197 void ProcessWatcher::cpuUsageFromProcFile()
202 std::ifstream file(processCpuDataFilename);
210 std::getline(file, line);
215 int currentUtime = std::stoi(pidElements.at(eUTime));
216 int currentStime = std::stoi(pidElements.at(eSTime));
218 int currentCUtime = std::stoi(pidElements.at(eCUTIME));
219 int currentCStime = std::stoi(pidElements.at(eCSTIME));
222 std::unique_lock guard{processCpuUsageMutex};
229 processCpuUsage.
lastUtime = currentUtime;
230 processCpuUsage.
lastStime = currentStime;
237 void ProcessWatcher::getMemoryUsage()
240 struct mallinfo _mallinfo;
242 _mallinfo = mallinfo();
245 std::unique_lock guard{processMemoryUsageMutex};
258 std::map<int, int> resultMap;
259 for (
int threadId : threadIds)
262 resultMap[threadId] = 0;
263 std::stringstream fileName;
264 fileName <<
"/proc/" << threadId <<
"/task/" << threadId <<
"/stat";
265 std::ifstream statFile(fileName.str().c_str());
267 if (!statFile.is_open())
269 ARMARX_WARNING_S <<
"Cannot open " << fileName.str() <<
" for reading the hertz value";
270 resultMap[threadId] = 0;
276 while (getline(statFile, line))
279 simox::alg::trim(line);
284 int userTimeJiffies = atoi(stringVec.at(13).c_str());
285 int kernelTimeJiffies = atoi(stringVec.at(14).c_str());
287 resultMap[threadId] = userTimeJiffies + kernelTimeJiffies;
302 return std::map<int, int>();
305 void ProcessWatcher::cpuUsageFromProcFile()
309 void ProcessWatcher::getMemoryUsage()
344 std::map<int, int>::iterator it = result.find(threadId);
346 if (it == result.end())
357 std::unique_lock guard{processCpuUsageMutex};
363 std::unique_lock guard{processMemoryUsageMutex};
379 std::unique_lock lock(threadWatchListMutex);
380 auto it = threadWatchList.find(query);
383 if (it != threadWatchList.end())
385 return it->load * 100;
395 std::unique_lock guard{processCpuUsageMutex};
396 return processCpuUsage;
406 std::unique_lock lock(threadWatchListMutex);
407 threadWatchList.erase(query);