==> src/proc_usage.c <==1/* native.rs's usage on Linux: fields after the parenthesised command: utime 14, stime 15, rss 24. */
2#include "mesh/proc_usage.h"
3
4#include <stdio.h>
5#include <stdlib.h>
6#include <string.h>
7#include <unistd.h>
8
9bool mesh_proc_usage(pid_t pid, uint64_t *cpu_ns, uint64_t *rss) {
10 char path[64], buf[4096];
11 snprintf(path, sizeof path, "/proc/%d/stat", (int)pid);
12 FILE *f = fopen(path, "r");
13 if (!f) return false;
14 size_t n = fread(buf, 1, sizeof buf - 1, f);
15 fclose(f);
16 buf[n] = 0;
17 char *close_paren = strrchr(buf, ')');
18 if (!close_paren || close_paren[1] == 0) return false;
19 /* rest starts at the state field (field 3). */
20 char *rest = close_paren + 2, *save = NULL;
21 char *tok = strtok_r(rest, " ", &save);
22 unsigned long long ut = 0, stt = 0, pages = 0;
23 for (int i = 0; tok && i <= 21; i++, tok = strtok_r(NULL, " ", &save)) {
24 if (i == 11) ut = strtoull(tok, NULL, 10);
25 if (i == 12) stt = strtoull(tok, NULL, 10);
26 if (i == 21) {
27 pages = strtoull(tok, NULL, 10);
28 long tick = sysconf(_SC_CLK_TCK), page = sysconf(_SC_PAGESIZE);
29 if (tick < 1) tick = 1;
30 if (page < 1) page = 1;
31 *cpu_ns = (ut + stt) * 1000000000ull / (unsigned long long)tick;
32 *rss = pages * (unsigned long long)page;
33 return true;
34 }
35 }
36 return false;
37}