Files
hakmem/archive/tools/investigate_smaps_detailed.c
Moe Charm (CI) 52386401b3 Debug Counters Implementation - Clean History
Major Features:
- Debug counter infrastructure for Refill Stage tracking
- Free Pipeline counters (ss_local, ss_remote, tls_sll)
- Diagnostic counters for early return analysis
- Unified larson.sh benchmark runner with profiles
- Phase 6-3 regression analysis documentation

Bug Fixes:
- Fix SuperSlab disabled by default (HAKMEM_TINY_USE_SUPERSLAB)
- Fix profile variable naming consistency
- Add .gitignore patterns for large files

Performance:
- Phase 6-3: 4.79 M ops/s (has OOM risk)
- With SuperSlab: 3.13 M ops/s (+19% improvement)

This is a clean repository without large log files.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-05 12:31:14 +09:00

149 lines
5.4 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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;
}