X-Git-Url: http://git.liburcu.org/?p=urcu.git;a=blobdiff_plain;f=tests%2Fregression%2Frcutorture.h;h=db3dfad00785a5aede0aa486d2805b5ed67a8814;hp=3444f5bdbab5e815234cc6976e4fd91f7e3f66c6;hb=4b2d70a71f5d7ac75c9eb2589c3df26a2ed0684a;hpb=ad46005890368f9c306f0c510b3d4b08c47b66f8 diff --git a/tests/regression/rcutorture.h b/tests/regression/rcutorture.h index 3444f5b..db3dfad 100644 --- a/tests/regression/rcutorture.h +++ b/tests/regression/rcutorture.h @@ -73,6 +73,14 @@ DEFINE_PER_THREAD(long long, n_reads_pt); DEFINE_PER_THREAD(long long, n_updates_pt); +enum callrcu_type { + CALLRCU_GLOBAL, + CALLRCU_PERCPU, + CALLRCU_PERTHREAD, +}; + +static enum callrcu_type callrcu_type = CALLRCU_GLOBAL; + long long n_reads = 0LL; long n_updates = 0L; int nthreadsrunning; @@ -122,7 +130,6 @@ volatile int goflag __attribute__((__aligned__(CAA_CACHE_LINE_SIZE))) void *rcu_read_perf_test(void *arg) { - struct call_rcu_data *crdp; int i; int me = (long)arg; long long n_reads_local = 0; @@ -146,9 +153,6 @@ void *rcu_read_perf_test(void *arg) } __get_thread_var(n_reads_pt) += n_reads_local; put_thread_offline(); - crdp = get_thread_call_rcu_data(); - set_thread_call_rcu_data(NULL); - call_rcu_data_free(crdp); rcu_unregister_thread(); return (NULL); @@ -158,12 +162,12 @@ void *rcu_update_perf_test(void *arg) { long long n_updates_local = 0; - if ((random() & 0xf00) == 0) { + if (callrcu_type == CALLRCU_PERTHREAD) { struct call_rcu_data *crdp; crdp = create_call_rcu_data(0, -1); if (crdp != NULL) { - diag("Using per-thread call_rcu() worker."); + diag("Successfully using per-thread call_rcu() worker."); set_thread_call_rcu_data(crdp); } } @@ -175,6 +179,13 @@ void *rcu_update_perf_test(void *arg) n_updates_local++; } __get_thread_var(n_updates_pt) += n_updates_local; + if (callrcu_type == CALLRCU_PERTHREAD) { + struct call_rcu_data *crdp; + + crdp = get_thread_call_rcu_data(); + set_thread_call_rcu_data(NULL); + call_rcu_data_free(crdp); + } return NULL; } @@ -385,7 +396,23 @@ void *rcu_update_stress_test(void *arg) strerror(errno)); abort(); } + rcu_register_thread(); call_rcu(&rh, rcu_update_stress_test_rcu); + rcu_unregister_thread(); + /* + * Our MacOS X test machine with the following + * config: + * 15.6.0 Darwin Kernel Version 15.6.0 + * root:xnu-3248.60.10~1/RELEASE_X86_64 + * appears to have issues with liburcu-signal + * signal being delivered on top of + * pthread_cond_wait. It seems to make the + * thread continue, and therefore corrupt the + * rcu_head. Work around this issue by + * unregistering the RCU read-side thread + * immediately after call_rcu (call_rcu needs + * us to be registered RCU readers). + */ ret = pthread_cond_wait(&call_rcu_test_cond, &call_rcu_test_mutex); if (ret) { @@ -404,17 +431,18 @@ void *rcu_update_stress_test(void *arg) } n_updates++; } + return NULL; } void *rcu_fake_update_stress_test(void *arg) { - if ((random() & 0xf00) == 0) { + if (callrcu_type == CALLRCU_PERTHREAD) { struct call_rcu_data *crdp; crdp = create_call_rcu_data(0, -1); if (crdp != NULL) { - diag("Using per-thread call_rcu() worker."); + diag("Successfully using per-thread call_rcu() worker."); set_thread_call_rcu_data(crdp); } } @@ -424,6 +452,13 @@ void *rcu_fake_update_stress_test(void *arg) synchronize_rcu(); (void) poll(NULL, 0, 1); } + if (callrcu_type == CALLRCU_PERTHREAD) { + struct call_rcu_data *crdp; + + crdp = get_thread_call_rcu_data(); + set_thread_call_rcu_data(NULL); + call_rcu_data_free(crdp); + } return NULL; } @@ -486,7 +521,7 @@ int stresstest(int nreaders) void usage(int argc, char *argv[]) { - diag("Usage: %s [nreaders [ perf | rperf | uperf | stress ] ]\n", argv[0]); + diag("Usage: %s nreaders [ perf | rperf | uperf | stress ] [ stride ] [ callrcu_global | callrcu_percpu | callrcu_perthread ]\n", argv[0]); exit(-1); } @@ -499,12 +534,36 @@ int main(int argc, char *argv[]) smp_init(); //rcu_init(); - srandom(time(NULL)); - if (random() & 0x100) { - diag("Allocating per-CPU call_rcu threads."); + if (argc > 4) { + const char *callrcu_str = argv[4];; + + if (strcmp(callrcu_str, "callrcu_global") == 0) { + callrcu_type = CALLRCU_GLOBAL; + } else if (strcmp(callrcu_str, "callrcu_percpu") == 0) { + callrcu_type = CALLRCU_PERCPU; + } else if (strcmp(callrcu_str, "callrcu_perthread") == 0) { + callrcu_type = CALLRCU_PERTHREAD; + } else { + usage(argc, argv); + goto end; + } + } + + switch (callrcu_type) { + case CALLRCU_GLOBAL: + diag("Using global per-process call_rcu thread."); + break; + case CALLRCU_PERCPU: + diag("Using per-CPU call_rcu threads."); if (create_all_cpu_call_rcu_data(0)) diag("create_all_cpu_call_rcu_data: %s", strerror(errno)); + break; + case CALLRCU_PERTHREAD: + diag("Using per-thread call_rcu() worker."); + break; + default: + abort(); } #ifdef DEBUG_YIELD @@ -513,6 +572,11 @@ int main(int argc, char *argv[]) #endif if (argc > 1) { + if (strcmp(argv[1], "-h") == 0 + || strcmp(argv[1], "--help") == 0) { + usage(argc, argv); + goto end; + } nreaders = strtoul(argv[1], NULL, 0); if (argc == 2) { ok(!perftest(nreaders, cpustride), @@ -541,9 +605,7 @@ int main(int argc, char *argv[]) else usage(argc, argv); } else { - ok(!perftest(nreaders, cpustride), - "perftest readers: %d, stride: %d", - nreaders, cpustride); + usage(argc, argv); } end: return exit_status();