int do_test_getters(const char *test_parm) { (void)test_parm; //SYSCALL(getpagesize); //SYSCALL(personality); TEST_GET(gettid); TEST_GET(getpid); TEST_GET(getuid); TEST_GET(getuid32); TEST_GET(getpgrp); TEST_GET(getppid); TEST_GET(getegid); TEST_GET(getegid32); TEST_GET(geteuid); TEST_GET(geteuid32); TEST_GET(getgid); TEST_GET(getgid32); test_get( "getpgid", getpgid(getpid()) ); return 0; }
int main(void) { plan_tests(1); if (getenv("SHF_PERFORMANCE_TEST_ENABLE") && atoi(getenv("SHF_PERFORMANCE_TEST_ENABLE"))) { } else { fprintf(stderr, "NOTE: prefix make with SHF_PERFORMANCE_TEST_ENABLE=1 ?\n"); goto EARLY_EXIT; } uint32_t cpu_count_desired = getenv("SHF_PERFORMANCE_TEST_CPUS") ? atoi(getenv("SHF_PERFORMANCE_TEST_CPUS")) : 0; uint32_t test_keys_desired = getenv("SHF_PERFORMANCE_TEST_KEYS") ? atoi(getenv("SHF_PERFORMANCE_TEST_KEYS")) : 0; TEST_INIT(); #define TEST_MAX_PROCESSES (16) #ifdef TEST_LMDB uint32_t test_keys_default = 100 * 1000000; /* assume enough RAM is available for LMDB */ #else uint64_t vfs_available_md = shf_get_vfs_available(shf) / 1024 / 1024; uint32_t test_keys_10m = vfs_available_md / 436 * 10; /* 10M keys is about 436MB */ uint32_t test_keys_default = test_keys_10m > 100 ? 100 * 1000000 : test_keys_10m * 1000000; SHF_ASSERT(test_keys_default > 0, "ERROR: only %luMB available on /dev/shm but 10M keys takes at least 436MB for SharedHashFile", vfs_available_md); #endif uint32_t test_keys = test_keys_desired ? test_keys_desired : test_keys_default; uint32_t cpu_count = cpu_count_desired ? cpu_count_desired : test_get_cpu_count(); uint32_t process; uint32_t processes = cpu_count > TEST_MAX_PROCESSES ? TEST_MAX_PROCESSES : cpu_count; uint32_t counts_old[TEST_MAX_PROCESSES] = { 0 }; volatile uint32_t * put_counts = mmap(NULL, SHF_MOD_PAGE(TEST_MAX_PROCESSES*sizeof(uint32_t)), PROT_READ|PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED | MAP_NORESERVE, -1, 0); SHF_ASSERT(MAP_FAILED != put_counts, "mmap(): %u: ", errno); volatile uint32_t * get_counts = mmap(NULL, SHF_MOD_PAGE(TEST_MAX_PROCESSES*sizeof(uint32_t)), PROT_READ|PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED | MAP_NORESERVE, -1, 0); SHF_ASSERT(MAP_FAILED != get_counts, "mmap(): %u: ", errno); volatile uint32_t * mix_counts = mmap(NULL, SHF_MOD_PAGE(TEST_MAX_PROCESSES*sizeof(uint32_t)), PROT_READ|PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED | MAP_NORESERVE, -1, 0); SHF_ASSERT(MAP_FAILED != mix_counts, "mmap(): %u: ", errno); volatile uint64_t * start_line = mmap(NULL, SHF_MOD_PAGE( 3*sizeof(uint64_t)), PROT_READ|PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED | MAP_NORESERVE, -1, 0); SHF_ASSERT(MAP_FAILED != mix_counts, "mmap(): %u: ", errno); SHF_ASSERT(sizeof(uint64_t) == sizeof(long), "INTERNAL: expected sizeof(uint64_t) == sizeof(long), but got %lu == %lu", sizeof(uint64_t), sizeof(long)); start_line[0] = 0; start_line[1] = 0; start_line[2] = 0; for (process = 0; process < processes; process++) { pid_t fork_pid = fork(); if (fork_pid == 0) { /*child*/ SHF_DEBUG("test process #%u with pid %5u\n", process, getpid()); { long previous_long_value; SHF_UNUSE(previous_long_value); previous_long_value = InterlockedExchangeAdd((long volatile *) &start_line[0], 1); while (processes != start_line[0]) { SHF_YIELD(); } TEST_INIT_CHILD(); for (uint32_t i = 0; i < (1 + (test_keys / processes)); i++) { uint32_t key = test_keys / processes * process + i; put_counts[process] ++; TEST_PUT(); } TEST_PUT_POST(); TEST_MIX_PRE(); usleep(2000000); /* 2 seconds */ previous_long_value = InterlockedExchangeAdd((long volatile *) &start_line[1], 1); while (processes != start_line[1]) { SHF_YIELD(); } for (uint32_t i = 0; i < (1 + (test_keys / processes)); i++) { uint32_t key = test_keys / processes * process + i; TEST_MIX(); } TEST_MIX_POST(); TEST_GET_PRE(); usleep(2000000); /* 2 seconds */ previous_long_value = InterlockedExchangeAdd((long volatile *) &start_line[2], 1); while (processes != start_line[2]) { SHF_YIELD(); } for (uint32_t i = 0; i < (1 + (test_keys / processes)); i++) { uint32_t key = test_keys / processes * process + i; TEST_GET(); } TEST_GET_POST(); TEST_FINI(); exit(0); } break; } else if (fork_pid > 0) { /*parent*/ /* loop again */ } } /* parent monitors & reports on forked children */ uint32_t seconds = 0; uint32_t key_total; uint32_t key_total_old = 0; uint64_t tabs_mmaps_old = 0; uint64_t tabs_mremaps_old = 0; uint64_t tabs_shrunk_old = 0; uint64_t tabs_parted_old = 0; uint32_t message = 0; const char * message_text = "PUT"; #ifdef SHF_DEBUG_VERSION uint64_t lock_conflicts_old = 0; #endif char graph_100[] = "----------------------------------------------------------------------------------------------------"; fprintf(stderr, "perf testing: " TEST_WHAT "\n"); fprintf(stderr, "running tests on: via command: '%s'\n", "cat /proc/cpuinfo | egrep 'model name' | head -n 1" ); fprintf(stderr, "running tests on: `%s`\n" , shf_backticks("cat /proc/cpuinfo | egrep 'model name' | head -n 1")); do { if (0 == seconds % 50) { #ifdef SHF_DEBUG_VERSION fprintf(stderr, "-LOCKC "); #endif fprintf(stderr, "-OP MMAP REMAP SHRK PART TOTAL ------PERCENT OPERATIONS PER PROCESS PER SECOND -OPS\n"); #ifdef SHF_DEBUG_VERSION fprintf(stderr, "------ "); #endif fprintf(stderr, "--- -k/s --k/s --/s --/s M-OPS 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 -M/s\n"); } seconds ++; // todo: add % system CPU time to per second summary line; why does put require so much system? #ifdef SHF_DEBUG_VERSION { uint64_t lock_conflicts = 0; for (uint32_t win = 0; win < SHF_WINS_PER_SHF; win++) { lock_conflicts += shf->shf_mmap->wins[win].lock.conflicts; } fprintf(stderr, "%6lu ", lock_conflicts - lock_conflicts_old); lock_conflicts_old = lock_conflicts; } #endif fprintf(stderr, "%s", message_text); { uint64_t tabs_mmaps = 0; uint64_t tabs_mremaps = 0; uint64_t tabs_shrunk = 0; uint64_t tabs_parted = 0; #ifdef TEST_SHF for (uint32_t win = 0; win < SHF_WINS_PER_SHF; win++) { tabs_mmaps += shf->shf_mmap->wins[win].tabs_mmaps ; tabs_mremaps += shf->shf_mmap->wins[win].tabs_mremaps; tabs_shrunk += shf->shf_mmap->wins[win].tabs_shrunk ; tabs_parted += shf->shf_mmap->wins[win].tabs_parted ; } #endif fprintf(stderr, "%5.1f %5.1f %4llu %4llu", (tabs_mmaps - tabs_mmaps_old ) / 1000.0, (tabs_mremaps - tabs_mremaps_old) / 1000.0, (tabs_shrunk - tabs_shrunk_old ) , (tabs_parted - tabs_parted_old ) ); tabs_mmaps_old = tabs_mmaps ; tabs_mremaps_old = tabs_mremaps; tabs_shrunk_old = tabs_shrunk ; tabs_parted_old = tabs_parted ; } { key_total = 0; uint32_t key_total_this_second = 0; for (process = 0; process < TEST_MAX_PROCESSES; process++) { key_total += put_counts[process] + get_counts[process] + mix_counts[process]; key_total_this_second += put_counts[process] + get_counts[process] + mix_counts[process] - counts_old[process]; } fprintf(stderr, " %5.1f", key_total / 1000.0 / 1000.0); for (process = 0; process < TEST_MAX_PROCESSES; process++) { fprintf(stderr, "%3.0f", (put_counts[process] + get_counts[process] + mix_counts[process] - counts_old[process]) * 100.0 / (0 == key_total_this_second ? 1 : key_total_this_second)); counts_old[process] = put_counts[process] + get_counts[process] + mix_counts[process]; } uint32_t key_total_per_second = key_total - key_total_old; fprintf(stderr, "%5.1f %s\n", key_total_per_second / 1000.0 / 1000.0, &graph_100[100 - (key_total_per_second / 750000)]); if (0 == message && key_total >= (1 * test_keys)) { message ++; message_text = "MIX"; } else if (1 == message && key_total >= (2 * test_keys)) { message ++; message_text = "GET"; } key_total_old = key_total; } usleep(1000000); /* one second */ } while (key_total < (3 * test_keys)); fprintf(stderr, "* MIX is 2%% (%u) del/put, 98%% (%u) get\n", test_keys * 2 / 100, test_keys * 98 / 100); TEST_FINI_MASTER(); EARLY_EXIT:; ok(1, "test still alive"); return exit_status(); } /* main() */