/* * contswap benchmark */ #include #include #include #include #include #include #include #define MEMORY (1650 << 20) #define RECLAIMERS 128 #define PAGE_SIZE 4096 #define PART (MEMORY / RECLAIMERS) static void *anonmap(unsigned long size) { void *map = mmap(NULL, size, PROT_READ, MAP_PRIVATE | MAP_ANON, -1, 0); assert(map != MAP_FAILED); return map; } static void touch_linear(char *map, unsigned long size) { unsigned long off; for (off = 0; off < size; off += PAGE_SIZE) if (map[off]) puts("huh?"); } static void __claim(unsigned long size) { char *map = anonmap(size); touch_linear(map, size); sleep(5); munmap(map, size); } static pid_t claim(unsigned long size) { pid_t pid; switch (pid = fork()) { case -1: puts("fork failed"); exit(1); case 0: kill(getpid(), SIGSTOP); __claim(size); exit(0); default: return pid; } } int main(void) { struct timeval start, stop, diff; pid_t pids[RECLAIMERS]; int nr, crap; char *one; one = anonmap(MEMORY); touch_linear(one, MEMORY); for (nr = 0; nr < RECLAIMERS; nr++) pids[nr] = claim(PART); for (nr = 0; nr < RECLAIMERS; nr++) kill(pids[nr], SIGCONT); for (nr = 0; nr < RECLAIMERS; nr++) waitpid(pids[nr], &crap, 0); gettimeofday(&start, NULL); touch_linear(one, MEMORY); gettimeofday(&stop, NULL); munmap(one, MEMORY); timersub(&stop, &start, &diff); printf("%lu.%lu\n", diff.tv_sec, diff.tv_usec); return 0; }