Add a simple postponing test verifying RCU callbacks have executed and RCU exits in order. Add as part of library unit-tests.
Signed-off-by: Gaetan Rivet <gr...@u256.net> --- tests/library.at | 8 ++++++- tests/test-rcu.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/tests/library.at b/tests/library.at index e572c22e3..6e8a154e5 100644 --- a/tests/library.at +++ b/tests/library.at @@ -251,10 +251,16 @@ AT_KEYWORDS([barrier]) AT_CHECK([ovstest test-barrier], [0], []) AT_CLEANUP -AT_SETUP([rcu]) +AT_SETUP([rcu quiescing]) +AT_KEYWORDS([rcu]) AT_CHECK([ovstest test-rcu-quiesce], [0], []) AT_CLEANUP +AT_SETUP([rcu postponing]) +AT_KEYWORDS([rcu]) +AT_CHECK([ovstest test-rcu], [0], []) +AT_CLEANUP + AT_SETUP([stopwatch module]) AT_CHECK([ovstest test-stopwatch], [0], [...... ], [ignore]) diff --git a/tests/test-rcu.c b/tests/test-rcu.c index 965f3c49f..38e1cbb6f 100644 --- a/tests/test-rcu.c +++ b/tests/test-rcu.c @@ -49,3 +49,64 @@ test_rcu_quiesce(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) } OVSTEST_REGISTER("test-rcu-quiesce", test_rcu_quiesce); + +struct rcu_user_aux { + bool done; +}; + +static void +rcu_user_deferred(struct rcu_user_aux *aux) +{ + aux->done = true; +} + +static void * +rcu_user_main(void *aux_) +{ + struct rcu_user_aux *aux = aux_; + + ovsrcu_quiesce(); + + aux->done = false; + ovsrcu_postpone(rcu_user_deferred, aux); + + ovsrcu_quiesce(); + + return NULL; +} + +#define N_THREAD 4 + +static void +test_rcu(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) +{ + struct rcu_user_aux main_aux = {0}; + struct rcu_user_aux aux[N_THREAD]; + pthread_t users[N_THREAD]; + size_t i; + + memset(aux, 0, sizeof aux); + + for (i = 0; i < ARRAY_SIZE(users); i++) { + users[i] = ovs_thread_create("user", rcu_user_main, &aux[i]); + } + + for (i = 0; i < ARRAY_SIZE(users); i++) { + xpthread_join(users[i], NULL); + } + + /* Register a last callback and verify that it will be properly executed + * even if the RCU lib is exited without this thread quiescing. + */ + ovsrcu_postpone(rcu_user_deferred, &main_aux); + + ovsrcu_exit(); + + ovs_assert(main_aux.done); + + for (i = 0; i < ARRAY_SIZE(users); i++) { + ovs_assert(aux[i].done); + } +} + +OVSTEST_REGISTER("test-rcu", test_rcu); -- 2.31.1 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev