Skip to content

Commit 469d1b9

Browse files
committed
Add memory size retrieving (Linux)
1 parent ef27686 commit 469d1b9

1 file changed

Lines changed: 161 additions & 1 deletion

File tree

src/process.cpp

Lines changed: 161 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@
55

66
#include <chrono>
77
#include <cstring>
8+
#include <fstream>
89
#include <iostream>
10+
#include <string>
911
#include <type_traits>
12+
#include <atomic>
1013

1114
namespace ttldtor::process {
1215

@@ -41,7 +44,7 @@ constexpr To bit_cast(const From &from)
4144

4245
} // namespace ttldtor::process
4346

44-
#if WIN32
47+
#ifdef WIN32
4548

4649
# include <Windows.h>
4750
# include <processthreadsapi.h>
@@ -117,5 +120,162 @@ std::uint64_t Process::getPrivateMemorySize() noexcept {
117120
return static_cast<std::uint64_t>(processMemoryCountersEx.PrivateUsage);
118121
}
119122
} // namespace ttldtor::process
123+
#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+
}
134+
135+
struct Parser {
136+
enum ParseResultType { KEY_NOT_FOUND, VALUE_NOT_FOUND, OK };
137+
138+
struct ParseResult {
139+
ParseResultType resultType;
140+
std::uint64_t value;
141+
};
142+
143+
static ParseResult parse(const std::string &s, const std::string &key) noexcept {
144+
if (auto foundKeyPos = s.find(key); foundKeyPos != std::string::npos) {
145+
if (auto foundValuePos = s.find_first_of("0123456789", foundKeyPos + 6);
146+
foundValuePos != std::string::npos) {
147+
try {
148+
return {OK, static_cast<std::uint64_t>(std::stoll(s.substr(foundValuePos)))};
149+
} catch (...) {
150+
return {OK, 0};
151+
}
152+
} else {
153+
return {VALUE_NOT_FOUND, 0};
154+
}
155+
} else {
156+
return {KEY_NOT_FOUND, 0};
157+
}
158+
}
159+
};
160+
161+
162+
163+
static unsigned long long lastTotalUser, lastTotalUserLow, lastTotalSys, lastTotalIdle;
164+
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);
169+
}
170+
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+
177+
std::chrono::milliseconds Process::getKernelProcessorTime() noexcept {
178+
return std::chrono::milliseconds(0);
179+
}
180+
181+
std::chrono::milliseconds Process::getUserProcessorTime() noexcept {
182+
return std::chrono::milliseconds(0);
183+
}
184+
185+
std::chrono::milliseconds Process::getTotalProcessorTime() noexcept {
186+
init();
187+
188+
// std::cout << (lastTotalUser + lastTotalSys) << std::endl;
189+
190+
return std::chrono::milliseconds((lastTotalUser + lastTotalSys) * 10);
191+
}
192+
193+
std::uint64_t Process::getWorkingSetSize() noexcept {
194+
std::ifstream is("/proc/self/status");
195+
196+
if (is.fail()) {
197+
return 0ULL;
198+
}
199+
200+
std::string s{};
201+
202+
while (!std::getline(is, s).fail()) {
203+
auto result = Parser::parse(s, "VmRSS:");
204+
205+
if (result.resultType == Parser::KEY_NOT_FOUND) {
206+
continue;
207+
} else {
208+
return result.value * 1024;
209+
}
210+
}
211+
212+
return 0LL;
213+
}
214+
215+
std::uint64_t Process::getPrivateMemorySize() noexcept {
216+
std::ifstream is("/proc/self/status");
217+
218+
if (is.fail()) {
219+
return 0ULL;
220+
}
221+
222+
std::string s{};
223+
224+
while (!std::getline(is, s).fail()) {
225+
auto result = Parser::parse(s, "VmSize:");
226+
227+
if (result.resultType == Parser::KEY_NOT_FOUND) {
228+
continue;
229+
} else {
230+
return result.value * 1024;
231+
}
232+
}
120233

234+
return 0LL;
235+
}
236+
} // namespace ttldtor::process
237+
#elif defined(__APPLE__) && defined(__MACH__)
238+
namespace ttldtor::process {
239+
std::chrono::milliseconds Process::getKernelProcessorTime() noexcept {
240+
return std::chrono::milliseconds(0);
241+
}
242+
243+
std::chrono::milliseconds Process::getUserProcessorTime() noexcept {
244+
return std::chrono::milliseconds(0);
245+
}
246+
247+
std::chrono::milliseconds Process::getTotalProcessorTime() noexcept {
248+
return std::chrono::milliseconds(0);
249+
}
250+
251+
std::uint64_t Process::getWorkingSetSize() noexcept {
252+
return 0ULL;
253+
}
254+
255+
std::uint64_t Process::getPrivateMemorySize() noexcept {
256+
return 0ULL;
257+
}
258+
} // namespace ttldtor::process
259+
#else
260+
namespace ttldtor::process {
261+
std::chrono::milliseconds Process::getKernelProcessorTime() noexcept {
262+
return std::chrono::milliseconds(0);
263+
}
264+
265+
std::chrono::milliseconds Process::getUserProcessorTime() noexcept {
266+
return std::chrono::milliseconds(0);
267+
}
268+
269+
std::chrono::milliseconds Process::getTotalProcessorTime() noexcept {
270+
return std::chrono::milliseconds(0);
271+
}
272+
273+
std::uint64_t Process::getWorkingSetSize() noexcept {
274+
return 0ULL;
275+
}
276+
277+
std::uint64_t Process::getPrivateMemorySize() noexcept {
278+
return 0ULL;
279+
}
280+
} // namespace ttldtor::process
121281
#endif

0 commit comments

Comments
 (0)