/* sp_tester.c Build with: gcc -o sp_tester sp_tester.c -lrt -W -Wall -O2 How to use: echo 1 > /proc/sys/vm/overcommit_memory swapoff -a swapon -a ./sp_tester then repeat with changed conditions eg echo 0 > /proc/sys/vm/swap_prefetch Each Test takes 10 minutes */ #include #include #include #include #include #include #include void fatal(const char *format, ...) { va_list ap; if (format) { va_start(ap, format); vfprintf(stderr, format, ap); va_end(ap); } fprintf(stderr, "Fatal error - exiting\n"); exit(1); } unsigned long ramsize, swapsize; size_t get_ram(void) { FILE *meminfo; char aux[256]; if(!(meminfo = fopen("/proc/meminfo", "r"))) fatal("fopen\n"); while( !feof(meminfo) && !fscanf(meminfo, "MemTotal: %lu kB", &ramsize) ) fgets(aux,sizeof(aux),meminfo); while( !feof(meminfo) && !fscanf(meminfo, "SwapTotal: %lu kB", &swapsize) ) fgets(aux,sizeof(aux),meminfo); if (fclose(meminfo) == -1) fatal("fclose"); ramsize *= 1000; swapsize *= 1000; printf("Ram %lu Swap %lu\n", ramsize, swapsize); return ramsize + (swapsize / 2); } unsigned long get_usecs(struct timespec *myts) { if (clock_gettime(CLOCK_REALTIME, myts)) fatal("clock_gettime"); return (myts->tv_sec * 1000000 + myts->tv_nsec / 1000 ); } int main(void) { unsigned long current_time, time_diff; struct timespec myts; char *buf1, *buf2, *buf3, *buf4; size_t size = get_ram(); int sleep_seconds = 600; if (size > ramsize / 2 * 3) size = ramsize / 2 * 3; printf("Total ram to be malloced: %u bytes\n", size); size /= 2; printf("Starting first malloc of %u bytes\n", size); buf1 = malloc(size); buf4 = malloc(1); if (buf1 == (char *)-1) fatal("Failed to malloc 1st buffer\n"); memset(buf1, 0, size); time_diff = current_time = get_usecs(&myts); for (buf3 = buf1; buf3 < buf1 + size; buf3++) *buf4 = *buf3; printf("Starting 1st read of first malloc\n"); current_time = get_usecs(&myts); time_diff = current_time - time_diff; printf("Touching this much ram takes %lu milliseconds\n",time_diff / 1000); printf("Starting second malloc of %u bytes\n", size); buf2 = malloc(size); if (buf2 == (char *)-1) fatal("Failed to malloc 2nd buffer\n"); memset(buf2, 0, size); for (buf3 = buf2 + size; buf3 > buf2; buf3--) *buf4 = *buf3; free(buf2); printf("Completed second malloc and free\n"); printf("Sleeping for %u seconds\n", sleep_seconds); sleep(sleep_seconds); printf("Important part - starting reread of first malloc\n"); time_diff = current_time = get_usecs(&myts); for (buf3 = buf1; buf3 < buf1 + size; buf3++) *buf4 = *buf3; current_time = get_usecs(&myts); time_diff = current_time - time_diff; printf("Completed read of first malloc\n"); printf("Timed portion %lu milliseconds\n",time_diff / 1000); free(buf1); free(buf4); return 0; }