MINOR: plock: support disabling exponential back-off
The new macro PLOCK_DISABLE_EBO may be defined to disable exponential
backoff. This can be useful to more easily spot functions that cause
contention. In this case the CPU will be spent inside the functions
themselves instead of the pl_wait_unlock_{long,int}() functions, making
them easier to spot using "perf top" even if that causes a significant
degradation of the thread scalability.
diff --git a/include/import/plock.h b/include/import/plock.h
index 0f16eb2..ac10950 100644
--- a/include/import/plock.h
+++ b/include/import/plock.h
@@ -58,8 +58,23 @@
* enforces an exponential backoff using CPU pauses to limit the pollution to
* the other threads' caches. The progression follows (1.5^N)-1, limited to
* 16384 iterations, which is way sufficient even for very large numbers of
- * threads.
+ * threads. It's possible to disable exponential backoff (EBO) for debugging
+ * purposes by setting PLOCK_DISABLE_EBO, in which case the function will be
+ * replaced with a simpler macro. This may for example be useful to more
+ * easily track callers' CPU usage. The macro was not designed to be used
+ * outside of the functions defined here.
*/
+#if defined(PLOCK_DISABLE_EBO)
+#define pl_wait_unlock_long(lock, mask) \
+ ({ \
+ unsigned long _r; \
+ do { \
+ pl_cpu_relax(); \
+ _r = pl_deref_long(lock); \
+ } while (_r & mask); \
+ _r; /* return value */ \
+ })
+#else
__attribute__((unused,noinline,no_instrument_function))
static unsigned long pl_wait_unlock_long(const unsigned long *lock, const unsigned long mask)
{
@@ -94,6 +109,7 @@
return ret;
}
+#endif /* PLOCK_DISABLE_EBO */
/* This function waits for <lock> to release all bits covered by <mask>, and
* enforces an exponential backoff using CPU pauses to limit the pollution to
@@ -101,7 +117,23 @@
* iterations, which is way sufficient even for very large numbers of threads.
* The function slightly benefits from size optimization under gcc, but Clang
* cannot do it, so it's not done here, as it doesn't make a big difference.
+ * It is possible to disable exponential backoff (EBO) for debugging purposes
+ * by setting PLOCK_DISABLE_EBO, in which case the function will be replaced
+ * with a simpler macro. This may for example be useful to more easily track
+ * callers' CPU usage. The macro was not designed to be used outside of the
+ * functions defined here.
*/
+#if defined(PLOCK_DISABLE_EBO)
+#define pl_wait_unlock_int(lock, mask) \
+ ({ \
+ unsigned int _r; \
+ do { \
+ pl_cpu_relax(); \
+ _r = pl_deref_int(lock); \
+ } while (_r & mask); \
+ _r; /* return value */ \
+ })
+#else
__attribute__((unused,noinline,no_instrument_function))
static unsigned int pl_wait_unlock_int(const unsigned int *lock, const unsigned int mask)
{
@@ -136,6 +168,7 @@
return ret;
}
+#endif /* PLOCK_DISABLE_EBO */
/* This function waits for <lock> to change from value <prev> and returns the
* new value. It enforces an exponential backoff using CPU pauses to limit the