skip to content
==> 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}