#include #include #include #include #include scan_mem(int *base, int size) { int sum = 0; while (size > 0) { sum += *base++; size -= sizeof (int); } } usage_report(struct rusage *prev_ru, int npages) { struct rusage ru; float fltim; float ofltim; int newline = 0; getrusage(RUSAGE_SELF, &ru); fltim = ru.ru_utime.tv_sec; fltim += ((float)ru.ru_utime.tv_usec)/1.0e06; ofltim = prev_ru->ru_utime.tv_sec; ofltim += ((float)prev_ru->ru_utime.tv_usec)/1.0e06; printf("user %.2f", fltim - ofltim); fltim = ru.ru_stime.tv_sec; fltim += ((float)ru.ru_stime.tv_usec)/1.0e06; ofltim = prev_ru->ru_stime.tv_sec; ofltim += ((float)prev_ru->ru_stime.tv_usec)/1.0e06; printf(" sys %.2f", fltim - ofltim); printf(" reclaims: %d faults %d swaps: %d in/out %d/%d csw %d/%d\n", ru.ru_minflt - prev_ru->ru_minflt, ru.ru_majflt - prev_ru->ru_majflt, ru.ru_nswap - prev_ru->ru_nswap, ru.ru_inblock - prev_ru->ru_inblock, ru.ru_oublock - prev_ru->ru_oublock, ru.ru_nvcsw - prev_ru->ru_nvcsw, ru.ru_nivcsw - prev_ru->ru_nivcsw); if (npages == 0) return; /* should not happen */ if (ru.ru_minflt - prev_ru->ru_minflt > 0) { printf("minor flts/pg: %d ", (ru.ru_minflt - prev_ru->ru_minflt)/npages); newline++; } if (ru.ru_majflt - prev_ru->ru_majflt > 0) { printf("major flts/pg: %d ", (ru.ru_majflt - prev_ru->ru_majflt)/npages); newline++; } if (newline) { printf("\n"); } } #define SZ2PG(x) ((x + PAGE_SIZE - 1)/PAGE_SIZE) main(int argc, char *argv[]) { int size = 512; int tot_size = 0; int loops = 0; int *p; int *base = sbrk(1); int max_size; struct rusage ru; if (argc > 1) { max_size = atoi(argv[1]); printf("Stop growing after crossing %d bytes\n", max_size); } else { max_size = 2000000000; } while ((p = sbrk(size)) != (int *)-1) { printf("Touching %d newly allocated bytes. Size: %d pages/%d " "bytes\n", size, SZ2PG(tot_size), tot_size); memset(p, loops, size); tot_size += size; scan_mem(base, tot_size); size <<= 1; loops++; if (tot_size + size > max_size) break; } printf("Begin doing smaller chunks to finish the job...\n"); while (size > 4096) { size >>= 1; p = sbrk(size); if (p == (int *)-1) continue; printf("Touching %d newly allocated bytes. Size: %d pages/%d " "bytes\n", size, SZ2PG(tot_size), tot_size); tot_size += size; } printf("Finished growing memory. %d pages\n", SZ2PG(tot_size)); memset(&ru, 0, sizeof (ru)); usage_report(&ru, SZ2PG(tot_size)); getrusage(RUSAGE_SELF, &ru); printf("Now scan memory... total size: %d pages/%d. bytes\n", SZ2PG(tot_size), tot_size); for (loops = 5; loops > 0; loops--) { scan_mem(base, tot_size); /*usage_report(&ru, SZ2PG(tot_size));*/ /*getrusage(RUSAGE_SELF, &ru);*/ printf("%d scans remaining...\n", loops); } printf("Overall usage: (%d pages in this run)\n", SZ2PG(tot_size)); memset(&ru, 0, sizeof (ru)); usage_report(&ru, SZ2PG(tot_size)); }