This simplifies management within the threads themselves. Signed-off-by: Paolo Bonzini <pbonz...@redhat.com> --- tests/rcutorture.c | 10 ---------- util/rcu.c | 12 ++++++++++++ 2 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/tests/rcutorture.c b/tests/rcutorture.c index d6b304d..000b216 100644 --- a/tests/rcutorture.c +++ b/tests/rcutorture.c @@ -134,8 +134,6 @@ static void *rcu_read_perf_test(void *arg) qemu_mutex_lock(&counts_mutex); n_reads += n_reads_local; qemu_mutex_unlock(&counts_mutex); - - rcu_unregister_thread(); return NULL; } @@ -157,8 +155,6 @@ static void *rcu_update_perf_test(void *arg) qemu_mutex_lock(&counts_mutex); n_updates += n_updates_local; qemu_mutex_unlock(&counts_mutex); - - rcu_unregister_thread(); return NULL; } @@ -283,8 +279,6 @@ static void *rcu_read_stress_test(void *arg) rcu_stress_count[i] += rcu_stress_local[i]; } qemu_mutex_unlock(&counts_mutex); - - rcu_unregister_thread(); return NULL; } @@ -319,8 +313,6 @@ static void *rcu_update_stress_test(void *arg) synchronize_rcu(); n_updates++; } - - rcu_unregister_thread(); return NULL; } @@ -336,8 +328,6 @@ static void *rcu_fake_update_stress_test(void *arg) synchronize_rcu(); g_usleep(1000); } - - rcu_unregister_thread(); return NULL; } diff --git a/util/rcu.c b/util/rcu.c index 7270151..8830295 100644 --- a/util/rcu.c +++ b/util/rcu.c @@ -268,12 +268,22 @@ void call_rcu1(struct rcu_head *node, void (*func)(struct rcu_head *node)) qemu_event_set(&rcu_call_ready_event); } +static __thread Notifier unregister_thread_notifier; + +static void rcu_unregister_thread_notify(Notifier *n, void *data) +{ + rcu_unregister_thread(); +} + void rcu_register_thread(void) { assert(rcu_reader.ctr == 0); qemu_mutex_lock(&rcu_gp_lock); QLIST_INSERT_HEAD(®istry, &rcu_reader, node); qemu_mutex_unlock(&rcu_gp_lock); + + unregister_thread_notifier.notify = rcu_unregister_thread_notify; + qemu_thread_atexit_add(&unregister_thread_notifier); } void rcu_unregister_thread(void) @@ -281,6 +291,8 @@ void rcu_unregister_thread(void) qemu_mutex_lock(&rcu_gp_lock); QLIST_REMOVE(&rcu_reader, node); qemu_mutex_unlock(&rcu_gp_lock); + + qemu_thread_atexit_remove(&unregister_thread_notifier); } static void rcu_init_complete(void) -- 2.4.3