When using the RCU_MEMBARRIER flavour of userspace-RCU, kernel support for
sys-membarrier is detected dynamically and stored in the rcu_has_sys_membarrier
global variable. Checking the value of this variable adds a small but
measurable overhead to smp_mb_slave. I only use userspace-rcu on systems which
support sys-membarrier, and I'd like a way of avoiding that overhead.
The attached patch makes the following changes: if RCU_FORCE_SYS_MEMBARRIER is
defined then rcu_has_sys_membarrier is replaced with the constant 1, eliminating
the overhead in smp_mb_slave. As a sanity check, support for sys-membarrier is
still detected at startup and if it isn't supported then the program aborts.
I didn't try to integrate this feature into the build system (eg by adding a
configure option for it) since I'm using my own build system.
Best wishes, Duncan.
Index: userspace-rcu-0.9.2/urcu/map/urcu.h
===================================================================
--- userspace-rcu-0.9.2/urcu/map/urcu.h (revision 32603)
+++ userspace-rcu-0.9.2/urcu/map/urcu.h (working copy)
@@ -80,9 +80,6 @@
#define rcu_flavor rcu_flavor_memb
-/* Specific to MEMBARRIER flavor */
-#define rcu_has_sys_membarrier rcu_has_sys_membarrier_memb
-
#elif defined(RCU_SIGNAL)
#define rcu_read_lock rcu_read_lock_sig
Index: userspace-rcu-0.9.2/urcu/static/urcu.h
===================================================================
--- userspace-rcu-0.9.2/urcu/static/urcu.h (revision 32603)
+++ userspace-rcu-0.9.2/urcu/static/urcu.h (working copy)
@@ -90,7 +90,11 @@
*/
#ifdef RCU_MEMBARRIER
+#ifdef RCU_FORCE_SYS_MEMBARRIER
+#define rcu_has_sys_membarrier 1
+#else
extern int rcu_has_sys_membarrier;
+#endif
static inline void smp_mb_slave(void)
{
Index: userspace-rcu-0.9.2/urcu.c
===================================================================
--- userspace-rcu-0.9.2/urcu.c (revision 32603)
+++ userspace-rcu-0.9.2/urcu.c (working copy)
@@ -78,7 +78,9 @@
#ifdef RCU_MEMBARRIER
static int init_done;
+#ifndef RCU_FORCE_SYS_MEMBARRIER
int rcu_has_sys_membarrier;
+#endif
void __attribute__((constructor)) rcu_init(void);
#endif
@@ -542,7 +544,12 @@
init_done = 1;
ret = membarrier(MEMBARRIER_CMD_QUERY, 0);
if (ret >= 0 && (ret & MEMBARRIER_CMD_SHARED)) {
+#ifndef RCU_FORCE_SYS_MEMBARRIER
rcu_has_sys_membarrier = 1;
+#else
+ } else {
+ abort();
+#endif
}
}
#endif
_______________________________________________
lttng-dev mailing list
[email protected]
https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev