#include "perf_index.h" #include "fail.h" #include #include #include #include static char *memblock; static size_t memsize; size_t hw_memsize(void) { int mib[2]; size_t len; size_t my_memsize; int retval; mib[0] = CTL_HW; mib[1] = HW_MEMSIZE; len = sizeof(my_memsize); retval = sysctl(mib, 2, &my_memsize, &len, NULL, 0); if (retval != 0) { return 0; } return my_memsize; } DECL_SETUP { char *memblockfiller; long long i; int pgsz = getpagesize(); /* Heuristic: use half the physical memory, hopefully this should work on all * devices. We use the amount of physical memory, rather than some softer * metric, like amount of free memory, so that the memory allocated is always * consistent for a given device. */ memsize = hw_memsize(); VERIFY(memsize > 0, "hw_memsize failed"); memsize = memsize / 2; memblock = (char*)malloc(memsize); VERIFY(memblock != NULL, "malloc failed"); memblockfiller = memblock; /* Do this manually, to make sure everything is paged in */ for (i = 0; i < memsize; i += pgsz) { memblockfiller[i] = 1; } return PERFINDEX_SUCCESS; } /* figures out what region of memory to copy, so it does interfere with other * threads, */ DECL_TEST { long long left = length; long long region_len = memsize / num_threads / 2; long long region_start = memsize / num_threads * thread_id / 2; long long copy_len; if (thread_id < memsize / 2 % num_threads) { region_start += thread_id; region_len++; } else { region_start += memsize / 2 % num_threads; } while (left > 0) { copy_len = region_len < left ? region_len : left; memcpy(memblock + region_start + memsize / 2, memblock + region_start, copy_len); left -= copy_len; } return PERFINDEX_SUCCESS; } DECL_CLEANUP { free(memblock); return PERFINDEX_SUCCESS; }