From 5b46e39d0e4d2592853c7bfc11add02b1101c04b Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Fri, 22 Nov 2019 11:02:36 -0500 Subject: [PATCH] urcu-bp: perform thread registration on urcu_bp_register_thread Some real-time use-cases (e.g. Xenomai) require to perform urcu-bp thread registration early in the thread life-time before it starts performing real-time tasks. Currently, this can be achieved by issuing a urcu_bp_read_lock() and urcu_bp_read_unlock() pair, or by using urcu_bp_read_ongoing(), while in the initialization phrase. However, it seems natural to expect that calling urcu_bp_register_thread() would have the side effect to perform the lazy thread registration immediately rather than being a no-op. Signed-off-by: Mathieu Desnoyers --- README.md | 9 +++++---- include/urcu/urcu-bp.h | 10 ++++++---- src/urcu-bp.c | 6 ++++++ 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 601703b..2d6dcaa 100644 --- a/README.md +++ b/README.md @@ -224,10 +224,11 @@ be overridden with `-DSIGRCU` by modifying `Makefile.build.inc`. The BP library flavor stands for "bulletproof". It is specifically designed to help tracing library to hook on applications without -requiring to modify these applications. `urcu_bp_init()`, -`urcu_bp_register_thread()` and `urcu_bp_unregister_thread()` all become -nops. The state is dealt with by the library internally at the expense -of read-side and write-side performance. +requiring to modify these applications. `urcu_bp_init()`, and +`urcu_bp_unregister_thread()` all become nops, whereas calling +`urcu_bp_register_thread()` becomes optional. The state is dealt with by +the library internally at the expense of read-side and write-side +performance. ### Initialization diff --git a/include/urcu/urcu-bp.h b/include/urcu/urcu-bp.h index d3d122d..2ea17e6 100644 --- a/include/urcu/urcu-bp.h +++ b/include/urcu/urcu-bp.h @@ -151,12 +151,14 @@ extern void urcu_bp_after_fork_parent(void); extern void urcu_bp_after_fork_child(void); /* - * In the bulletproof version, the following functions are no-ops. + * In the bulletproof version, thread registration is performed lazily, + * but it can be forced by issuing an explicit urcu_bp_register_thread(). */ -static inline void urcu_bp_register_thread(void) -{ -} +extern void urcu_bp_register_thread(void); +/* + * In the bulletproof version, the following functions are no-ops. + */ static inline void urcu_bp_unregister_thread(void) { } diff --git a/src/urcu-bp.c b/src/urcu-bp.c index 33f2807..05efd97 100644 --- a/src/urcu-bp.c +++ b/src/urcu-bp.c @@ -566,6 +566,12 @@ end: } URCU_ATTR_ALIAS("urcu_bp_register") void rcu_bp_register(); +void urcu_bp_register_thread(void) +{ + if (caa_unlikely(!URCU_TLS(urcu_bp_reader))) + urcu_bp_register(); /* If not yet registered. */ +} + /* Disable signals, take mutex, remove from registry */ static void urcu_bp_unregister(struct rcu_reader *rcu_reader_reg) -- 2.34.1