summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Evans <jasone@canonware.com>2017-02-08 18:30:44 (GMT)
committerJason Evans <jasone@canonware.com>2017-02-09 02:50:03 (GMT)
commitde8a68e85304848189643fb48100c18aa9d60e32 (patch)
tree501e17ec14e3f73068711b8e19c470cc56c50b80
parent5f118307543b128e1ad6298ec2ab1acd71140095 (diff)
downloadjemalloc-de8a68e85304848189643fb48100c18aa9d60e32.zip
jemalloc-de8a68e85304848189643fb48100c18aa9d60e32.tar.gz
jemalloc-de8a68e85304848189643fb48100c18aa9d60e32.tar.bz2
Enhance spin_adaptive() to yield after several iterations.
This avoids worst case behavior if e.g. another thread is preempted while owning the resource the spinning thread is waiting for.
-rw-r--r--Makefile.in1
-rw-r--r--include/jemalloc/internal/spin_inlines.h17
-rw-r--r--test/unit/spin.c16
3 files changed, 28 insertions, 6 deletions
diff --git a/Makefile.in b/Makefile.in
index acd31f7..23056f7 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -189,6 +189,7 @@ TESTS_UNIT := \
$(srcroot)test/unit/size_classes.c \
$(srcroot)test/unit/slab.c \
$(srcroot)test/unit/smoothstep.c \
+ $(srcroot)test/unit/spin.c \
$(srcroot)test/unit/stats.c \
$(srcroot)test/unit/stats_print.c \
$(srcroot)test/unit/ticker.c \
diff --git a/include/jemalloc/internal/spin_inlines.h b/include/jemalloc/internal/spin_inlines.h
index 03beead..1657326 100644
--- a/include/jemalloc/internal/spin_inlines.h
+++ b/include/jemalloc/internal/spin_inlines.h
@@ -8,14 +8,19 @@ void spin_adaptive(spin_t *spin);
#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_SPIN_C_))
JEMALLOC_INLINE void
spin_adaptive(spin_t *spin) {
- volatile uint64_t i;
+ volatile uint32_t i;
- for (i = 0; i < (KQU(1) << spin->iteration); i++) {
- CPU_SPINWAIT;
- }
-
- if (spin->iteration < 63) {
+ if (spin->iteration < 5) {
+ for (i = 0; i < (1U << spin->iteration); i++) {
+ CPU_SPINWAIT;
+ }
spin->iteration++;
+ } else {
+#ifdef _WIN32
+ SwitchToThread();
+#else
+ sched_yield();
+#endif
}
}
diff --git a/test/unit/spin.c b/test/unit/spin.c
new file mode 100644
index 0000000..bd368b3
--- /dev/null
+++ b/test/unit/spin.c
@@ -0,0 +1,16 @@
+#include "test/jemalloc_test.h"
+
+TEST_BEGIN(test_spin) {
+ spin_t spinner = SPIN_INITIALIZER;
+
+ for (unsigned i = 0; i < 100; i++) {
+ spin_adaptive(&spinner);
+ }
+}
+TEST_END
+
+int
+main(void) {
+ return test(
+ test_spin);
+}