Files
hakmem/archive/tools/investigate_smaps_detailed.c

149 lines
5.4 KiB
C
Raw Normal View History

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Phase 8: Detailed smaps breakdown
// Parse every memory region to find the 5.6 MB overhead
typedef struct {
char name[128];
unsigned long rss;
unsigned long pss;
unsigned long anon;
unsigned long size;
} MemRegion;
void print_smaps_detailed(const char* label) {
printf("\n╔═══════════════════════════════════════════════╗\n");
printf("║ %s\n", label);
printf("╚═══════════════════════════════════════════════╝\n");
FILE* f = fopen("/proc/self/smaps", "r");
if (!f) {
printf("Cannot open /proc/self/smaps\n");
return;
}
char line[512];
MemRegion regions[1000];
int region_count = 0;
MemRegion* current = NULL;
unsigned long total_rss = 0;
unsigned long total_anon = 0;
while (fgets(line, sizeof(line), f)) {
// New region starts with address range
if (strchr(line, '-') && strchr(line, ' ')) {
if (region_count < 1000) {
current = &regions[region_count++];
memset(current, 0, sizeof(MemRegion));
// Extract region name (last part of line)
char* p = strchr(line, '/');
if (p) {
char* end = strchr(p, '\n');
if (end) *end = '\0';
snprintf(current->name, sizeof(current->name), "%s", p);
} else if (strstr(line, "[heap]")) {
snprintf(current->name, sizeof(current->name), "[heap]");
} else if (strstr(line, "[stack]")) {
snprintf(current->name, sizeof(current->name), "[stack]");
} else if (strstr(line, "[vdso]")) {
snprintf(current->name, sizeof(current->name), "[vdso]");
} else if (strstr(line, "[vvar]")) {
snprintf(current->name, sizeof(current->name), "[vvar]");
} else {
snprintf(current->name, sizeof(current->name), "[anon]");
}
}
} else if (current) {
unsigned long val;
if (sscanf(line, "Size: %lu kB", &val) == 1) {
current->size = val;
}
if (sscanf(line, "Rss: %lu kB", &val) == 1) {
current->rss = val;
total_rss += val;
}
if (sscanf(line, "Pss: %lu kB", &val) == 1) {
current->pss = val;
}
if (sscanf(line, "Anonymous: %lu kB", &val) == 1) {
current->anon = val;
total_anon += val;
}
}
}
fclose(f);
// Print regions sorted by RSS (largest first)
printf("\nTop memory regions by RSS:\n");
printf("%-50s %10s %10s %10s\n", "Region", "Size", "RSS", "Anon");
printf("────────────────────────────────────────────────────────────────────────────\n");
// Simple bubble sort by RSS
for (int i = 0; i < region_count - 1; i++) {
for (int j = i + 1; j < region_count; j++) {
if (regions[j].rss > regions[i].rss) {
MemRegion tmp = regions[i];
regions[i] = regions[j];
regions[j] = tmp;
}
}
}
// Print top 30 regions
for (int i = 0; i < region_count && i < 30; i++) {
if (regions[i].rss > 0) {
printf("%-50s %7lu KB %7lu KB %7lu KB\n",
regions[i].name,
regions[i].size,
regions[i].rss,
regions[i].anon);
}
}
printf("────────────────────────────────────────────────────────────────────────────\n");
printf("TOTAL: %7lu KB %7lu KB\n",
total_rss, total_anon);
printf(" %.1f MB %.1f MB\n",
total_rss / 1024.0, total_anon / 1024.0);
}
int main() {
printf("╔═══════════════════════════════════════════════╗\n");
printf("║ Detailed smaps Analysis ║\n");
printf("╚═══════════════════════════════════════════════╝\n");
print_smaps_detailed("Baseline (program start)");
// Allocate 1M × 16B
int n = 1000000;
void** ptrs = malloc(n * sizeof(void*));
for (int i = 0; i < n; i++) {
ptrs[i] = malloc(16);
}
print_smaps_detailed("After 1M × 16B allocation");
// Free all
for (int i = 0; i < n; i++) {
free(ptrs[i]);
}
// Flush Magazine
extern void hak_tiny_magazine_flush_all(void) __attribute__((weak));
if (hak_tiny_magazine_flush_all) {
hak_tiny_magazine_flush_all();
}
print_smaps_detailed("After free + flush");
free(ptrs);
return 0;
}