Skip to content

Commit aac3050

Browse files
committed
Fetch per-numa (effectively per-kind) memory usage from the OS.
A simplified version, without assigning kinds, etc.
1 parent 17a6cfa commit aac3050

File tree

2 files changed

+82
-0
lines changed

2 files changed

+82
-0
lines changed

Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ libmemkind_la_SOURCES = src/hbwmalloc.c \
4040
src/ranking_queue.c \
4141
src/slab_allocator.c \
4242
src/ranking_controller.c \
43+
src/numus.c \
4344
# end
4445

4546

src/numus.c

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
#include <stdio.h>
2+
#include <stdbool.h>
3+
#include <string.h>
4+
#include <stdint.h>
5+
#include <stdlib.h>
6+
7+
#define MAX_NODES 1024 /* kernel max */
8+
static struct {
9+
size_t used;
10+
} numamem[MAX_NODES];
11+
12+
static bool gather_numamem()
13+
{
14+
FILE *f = fopen("/proc/self/numa_maps", "r");
15+
if (!f)
16+
return false;
17+
18+
char line[1024];
19+
while (fgets(line, sizeof(line), f)) {
20+
char *saveptr = 0;
21+
char *err;
22+
// We get page size of a mapping only at the end, thus we need to
23+
// temporarily keep the counts.
24+
int maxnode = 0;
25+
short num[MAX_NODES];
26+
size_t count[MAX_NODES];
27+
uint64_t pagesize = 0;
28+
29+
char *tok = strtok_r(line, " ", &saveptr);
30+
if (!tok) {
31+
fprintf(stderr, "Empty line in proc/numa_maps\n");
32+
fclose(f);
33+
return false;
34+
}
35+
strtoul(tok, &err, 16);
36+
if (*err) {
37+
fprintf(stderr, "Invalid addr: %s\n", tok);
38+
fclose(f);
39+
return false;
40+
}
41+
//printf("Addr: %lx\n", val);
42+
43+
while ((tok = strtok_r(0, " ", &saveptr))) {
44+
char *valp = strchr(tok, '=');
45+
if (!valp) {
46+
/* flags */
47+
if (!strcmp(tok, "stack"))
48+
goto skip_mapping;
49+
continue;
50+
}
51+
*valp++ = 0;
52+
53+
if (!strcmp(tok, "kernelpagesize_kB"))
54+
pagesize = atoi(valp) * 1024ULL;
55+
else if (tok[0] == 'N' && tok[1] >= '0' && tok[1] <= '9') {
56+
// per-node counts are given as N3=15 which means 15 pages
57+
// on node 3.
58+
int node = atoi(tok + 1);
59+
if (node >= MAX_NODES)
60+
continue;
61+
if (maxnode + 1 >= MAX_NODES) // overflow (can't happen)
62+
continue;
63+
num[maxnode] = node;
64+
count[maxnode] = atol(valp);
65+
maxnode++;
66+
}
67+
}
68+
69+
if (maxnode && !pagesize) {
70+
fprintf(stderr, "Pages used but no page size\n");
71+
fclose(f);
72+
return false;
73+
}
74+
for (int i = 0; i < maxnode; i++)
75+
numamem[num[i]].used += count[i] * pagesize;
76+
77+
skip_mapping:
78+
}
79+
fclose(f);
80+
return true;
81+
}

0 commit comments

Comments
 (0)