33
44#include < process/process.hpp>
55
6+ #include < atomic>
67#include < chrono>
78#include < cstring>
89#include < fstream>
910#include < iostream>
1011#include < string>
1112#include < type_traits>
12- #include < atomic>
1313
1414namespace ttldtor ::process {
1515
@@ -121,26 +121,18 @@ std::uint64_t Process::getPrivateMemorySize() noexcept {
121121}
122122} // namespace ttldtor::process
123123#elif defined(__linux__)
124- int parseLine (char *line) {
125- // This assumes that a digit will be found and the line ends in " Kb".
126- int i = strlen (line);
127- const char *p = line;
128- while (*p < ' 0' || *p > ' 9' )
129- p++;
130- line[i - 3 ] = ' \0 ' ;
131- i = atoi (p);
132- return i;
133- }
124+
125+ # include < sys/resource.h>
134126
135127struct Parser {
136128 enum ParseResultType { KEY_NOT_FOUND, VALUE_NOT_FOUND, OK };
137129
138- struct ParseResult {
130+ struct ParseStatusResult {
139131 ParseResultType resultType;
140132 std::uint64_t value;
141133 };
142134
143- static ParseResult parse (const std::string &s, const std::string &key) noexcept {
135+ static ParseStatusResult parseStatus (const std::string &s, const std::string &key) noexcept {
144136 if (auto foundKeyPos = s.find (key); foundKeyPos != std::string::npos) {
145137 if (auto foundValuePos = s.find_first_of (" 0123456789" , foundKeyPos + 6 );
146138 foundValuePos != std::string::npos) {
@@ -158,36 +150,43 @@ struct Parser {
158150 }
159151};
160152
153+ namespace ttldtor ::process {
154+ struct RUsageResult {
155+ std::chrono::milliseconds sysTime{};
156+ std::chrono::milliseconds userTime{};
157+ std::chrono::milliseconds totalTime{};
158+
159+ explicit RUsageResult (const rusage &ru)
160+ : sysTime{static_cast <std::uint64_t >(ru.ru_stime .tv_sec ) * 1000000ULL +
161+ static_cast <std::uint64_t >(ru.ru_stime .tv_usec )},
162+ userTime{static_cast <std::uint64_t >(ru.ru_utime .tv_sec ) * 1000000ULL +
163+ static_cast <std::uint64_t >(ru.ru_utime .tv_usec )},
164+ totalTime{sysTime + userTime} {
165+ }
166+ };
161167
168+ std::chrono::milliseconds Process::getKernelProcessorTime () noexcept {
169+ rusage ru{};
162170
163- static unsigned long long lastTotalUser, lastTotalUserLow, lastTotalSys, lastTotalIdle ;
171+ getrusage (RUSAGE_SELF, &ru) ;
164172
165- void init () {
166- FILE *file = fopen (" /proc/stat" , " r" );
167- fscanf (file, " cpu %llu %llu %llu %llu" , &lastTotalUser, &lastTotalUserLow, &lastTotalSys, &lastTotalIdle);
168- fclose (file);
173+ return RUsageResult{ru}.sysTime ;
169174}
170175
171- namespace ttldtor ::process {
172- /* TODO: implement
173- * https://github.com/dotnet/runtime/blob/de0ab156194eb64deae0e1018db9a58f7b02f4a3/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Unix.cs#L817
174- * https://github.com/dotnet/runtime/blob/de0ab156194eb64deae0e1018db9a58f7b02f4a3/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Linux.cs#L130
175- */
176+ std::chrono::milliseconds Process::getUserProcessorTime () noexcept {
177+ rusage ru{};
176178
177- std::chrono::milliseconds Process::getKernelProcessorTime () noexcept {
178- return std::chrono::milliseconds (0 );
179- }
179+ getrusage (RUSAGE_SELF, &ru);
180180
181- std::chrono::milliseconds Process::getUserProcessorTime () noexcept {
182- return std::chrono::milliseconds (0 );
181+ return RUsageResult{ru}.userTime ;
183182}
184183
185184std::chrono::milliseconds Process::getTotalProcessorTime () noexcept {
186- init () ;
185+ rusage ru{} ;
187186
188- // std::cout << (lastTotalUser + lastTotalSys) << std::endl ;
187+ getrusage (RUSAGE_SELF, &ru) ;
189188
190- return std::chrono::milliseconds ((lastTotalUser + lastTotalSys) * 10 ) ;
189+ return RUsageResult{ru}. totalTime ;
191190}
192191
193192std::uint64_t Process::getWorkingSetSize () noexcept {
@@ -200,7 +199,7 @@ std::uint64_t Process::getWorkingSetSize() noexcept {
200199 std::string s{};
201200
202201 while (!std::getline (is, s).fail ()) {
203- auto result = Parser::parse (s, " VmRSS:" );
202+ auto result = Parser::parseStatus (s, " VmRSS:" );
204203
205204 if (result.resultType == Parser::KEY_NOT_FOUND) {
206205 continue ;
@@ -222,7 +221,7 @@ std::uint64_t Process::getPrivateMemorySize() noexcept {
222221 std::string s{};
223222
224223 while (!std::getline (is, s).fail ()) {
225- auto result = Parser::parse (s, " VmSize:" );
224+ auto result = Parser::parseStatus (s, " VmSize:" );
226225
227226 if (result.resultType == Parser::KEY_NOT_FOUND) {
228227 continue ;
0 commit comments