111 lines
3.7 KiB
C
111 lines
3.7 KiB
C
|
|
#include <stdio.h>
|
|||
|
|
#include <stdlib.h>
|
|||
|
|
#include <string.h>
|
|||
|
|
#include <sys/resource.h>
|
|||
|
|
|
|||
|
|
// Phase 8: Investigate 4.23 MB mystery overhead
|
|||
|
|
// Try to measure actual memory usage at different stages
|
|||
|
|
|
|||
|
|
void print_smaps_summary(const char* label) {
|
|||
|
|
printf("\n=== %s ===\n", label);
|
|||
|
|
|
|||
|
|
FILE* f = fopen("/proc/self/smaps", "r");
|
|||
|
|
if (!f) {
|
|||
|
|
printf("Cannot open /proc/self/smaps\n");
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
char line[256];
|
|||
|
|
unsigned long total_rss = 0;
|
|||
|
|
unsigned long total_pss = 0;
|
|||
|
|
unsigned long total_anon = 0;
|
|||
|
|
unsigned long total_heap = 0;
|
|||
|
|
int in_heap = 0;
|
|||
|
|
|
|||
|
|
while (fgets(line, sizeof(line), f)) {
|
|||
|
|
// Check if this is heap region
|
|||
|
|
if (strstr(line, "[heap]")) {
|
|||
|
|
in_heap = 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Parse RSS/PSS/Anonymous lines
|
|||
|
|
unsigned long val;
|
|||
|
|
if (sscanf(line, "Rss: %lu kB", &val) == 1) {
|
|||
|
|
total_rss += val;
|
|||
|
|
if (in_heap) total_heap += val;
|
|||
|
|
}
|
|||
|
|
if (sscanf(line, "Pss: %lu kB", &val) == 1) {
|
|||
|
|
total_pss += val;
|
|||
|
|
}
|
|||
|
|
if (sscanf(line, "Anonymous: %lu kB", &val) == 1) {
|
|||
|
|
total_anon += val;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Reset heap flag on new mapping
|
|||
|
|
if (line[0] != ' ' && line[0] != '\t') {
|
|||
|
|
in_heap = 0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
fclose(f);
|
|||
|
|
|
|||
|
|
printf("Total RSS: %.1f MB\n", total_rss / 1024.0);
|
|||
|
|
printf("Total PSS: %.1f MB\n", total_pss / 1024.0);
|
|||
|
|
printf("Total Anonymous: %.1f MB\n", total_anon / 1024.0);
|
|||
|
|
printf("Heap RSS: %.1f MB\n", total_heap / 1024.0);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void print_rusage(const char* label) {
|
|||
|
|
struct rusage usage;
|
|||
|
|
getrusage(RUSAGE_SELF, &usage);
|
|||
|
|
printf("%s: RSS = %.1f MB\n", label, usage.ru_maxrss / 1024.0);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int main() {
|
|||
|
|
printf("╔═══════════════════════════════════════════════╗\n");
|
|||
|
|
printf("║ Phase 8: Mystery 4.23 MB Investigation ║\n");
|
|||
|
|
printf("╚═══════════════════════════════════════════════╝\n");
|
|||
|
|
|
|||
|
|
print_rusage("Baseline (program start)");
|
|||
|
|
print_smaps_summary("Baseline");
|
|||
|
|
|
|||
|
|
// Allocate pointer array (same as battle test)
|
|||
|
|
int n = 1000000;
|
|||
|
|
void** ptrs = malloc(n * sizeof(void*));
|
|||
|
|
printf("\nPointer array: %d × 8 = %.1f MB\n", n, (n * 8) / 1024.0 / 1024.0);
|
|||
|
|
print_rusage("After pointer array malloc");
|
|||
|
|
|
|||
|
|
// Allocate 1M × 16B (same as battle test)
|
|||
|
|
for (int i = 0; i < n; i++) {
|
|||
|
|
ptrs[i] = malloc(16);
|
|||
|
|
}
|
|||
|
|
printf("\nData allocation: %d × 16 = %.1f MB\n", n, (n * 16) / 1024.0 / 1024.0);
|
|||
|
|
print_rusage("After data allocation");
|
|||
|
|
print_smaps_summary("After allocation");
|
|||
|
|
|
|||
|
|
// Free all
|
|||
|
|
for (int i = 0; i < n; i++) {
|
|||
|
|
free(ptrs[i]);
|
|||
|
|
}
|
|||
|
|
print_rusage("After free (before flush)");
|
|||
|
|
|
|||
|
|
// Flush Magazine (if HAKMEM)
|
|||
|
|
extern void hak_tiny_magazine_flush_all(void) __attribute__((weak));
|
|||
|
|
if (hak_tiny_magazine_flush_all) {
|
|||
|
|
hak_tiny_magazine_flush_all();
|
|||
|
|
print_rusage("After Magazine flush");
|
|||
|
|
print_smaps_summary("After flush");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
free(ptrs);
|
|||
|
|
|
|||
|
|
printf("\n╔═══════════════════════════════════════════════╗\n");
|
|||
|
|
printf("║ Analysis: Check heap RSS vs total data ║\n");
|
|||
|
|
printf("╚═══════════════════════════════════════════════╝\n");
|
|||
|
|
printf("Expected data: 7.6 MB (ptr array) + 15.3 MB (allocs) = 22.9 MB\n");
|
|||
|
|
printf("Actual RSS from smaps above\n");
|
|||
|
|
printf("Overhead = Actual - Expected\n");
|
|||
|
|
|
|||
|
|
return 0;
|
|||
|
|
}
|