X-Git-Url: https://git.liburcu.org/?a=blobdiff_plain;f=tests%2Fregression%2Frcutorture.h;h=93fdf0cf373c6623dafec968b64257bb96a24bd6;hb=0d48d10d15ca38fea1010456581b4840dbc9f888;hp=ead5b4082ca217e5064dcd350a06799dd4e0ccf6;hpb=ce29b37132cef1c1c758e0862ac701e9bb756d29;p=urcu.git diff --git a/tests/regression/rcutorture.h b/tests/regression/rcutorture.h index ead5b40..93fdf0c 100644 --- a/tests/regression/rcutorture.h +++ b/tests/regression/rcutorture.h @@ -56,6 +56,8 @@ #include #include "tap.h" +#include "urcu-wait.h" + #define NR_TESTS 1 DEFINE_PER_THREAD(long long, n_reads_pt); @@ -334,35 +336,15 @@ void *rcu_read_stress_test(void *arg __attribute__((unused))) return (NULL); } -static pthread_mutex_t call_rcu_test_mutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_cond_t call_rcu_test_cond = PTHREAD_COND_INITIALIZER; +static DEFINE_URCU_WAIT_QUEUE(call_rcu_waiters); static void rcu_update_stress_test_rcu(struct rcu_head *head __attribute__((unused))) { - int ret; + struct urcu_waiters waiters; - ret = pthread_mutex_lock(&call_rcu_test_mutex); - if (ret) { - errno = ret; - diag("pthread_mutex_lock: %s", - strerror(errno)); - abort(); - } - ret = pthread_cond_signal(&call_rcu_test_cond); - if (ret) { - errno = ret; - diag("pthread_cond_signal: %s", - strerror(errno)); - abort(); - } - ret = pthread_mutex_unlock(&call_rcu_test_mutex); - if (ret) { - errno = ret; - diag("pthread_mutex_unlock: %s", - strerror(errno)); - abort(); - } + urcu_move_waiters(&waiters, &call_rcu_waiters); + urcu_wake_all_waiters(&waiters); } static @@ -389,8 +371,14 @@ void *rcu_update_stress_test(void *arg __attribute__((unused))) struct rcu_head rh; enum writer_state writer_state = WRITER_STATE_SYNC_RCU; + rcu_register_thread(); + + /* Offline for poll. */ + put_thread_offline(); while (goflag == GOFLAG_INIT) (void) poll(NULL, 0, 1); + put_thread_online(); + while (goflag == GOFLAG_RUN) { i = rcu_stress_idx + 1; if (i >= RCU_STRESS_PIPE_LEN) @@ -411,58 +399,26 @@ void *rcu_update_stress_test(void *arg __attribute__((unused))) break; case WRITER_STATE_CALL_RCU: { - int ret; - - ret = pthread_mutex_lock(&call_rcu_test_mutex); - if (ret) { - errno = ret; - diag("pthread_mutex_lock: %s", - strerror(errno)); - abort(); - } - rcu_register_thread(); + DEFINE_URCU_WAIT_NODE(wait, URCU_WAIT_WAITING); + + urcu_wait_add(&call_rcu_waiters, &wait); + 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) { - errno = ret; - diag("pthread_cond_signal: %s", - strerror(errno)); - abort(); - } - ret = pthread_mutex_unlock(&call_rcu_test_mutex); - if (ret) { - errno = ret; - diag("pthread_mutex_unlock: %s", - strerror(errno)); - abort(); - } + + urcu_adaptative_busy_wait(&wait); break; } case WRITER_STATE_POLL_RCU: { struct urcu_gp_poll_state poll_state; - rcu_register_thread(); poll_state = start_poll_synchronize_rcu(); - rcu_unregister_thread(); + + /* Offline for poll. */ + put_thread_offline(); while (!poll_state_synchronize_rcu(poll_state)) (void) poll(NULL, 0, 1); /* Wait for 1ms */ + put_thread_online(); break; } } @@ -470,6 +426,8 @@ void *rcu_update_stress_test(void *arg __attribute__((unused))) advance_writer_state(&writer_state); } + rcu_unregister_thread(); + return NULL; }