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.
This commit is contained in:
parent
5f11830754
commit
de8a68e853
@ -189,6 +189,7 @@ TESTS_UNIT := \
|
|||||||
$(srcroot)test/unit/size_classes.c \
|
$(srcroot)test/unit/size_classes.c \
|
||||||
$(srcroot)test/unit/slab.c \
|
$(srcroot)test/unit/slab.c \
|
||||||
$(srcroot)test/unit/smoothstep.c \
|
$(srcroot)test/unit/smoothstep.c \
|
||||||
|
$(srcroot)test/unit/spin.c \
|
||||||
$(srcroot)test/unit/stats.c \
|
$(srcroot)test/unit/stats.c \
|
||||||
$(srcroot)test/unit/stats_print.c \
|
$(srcroot)test/unit/stats_print.c \
|
||||||
$(srcroot)test/unit/ticker.c \
|
$(srcroot)test/unit/ticker.c \
|
||||||
|
@ -8,14 +8,19 @@ void spin_adaptive(spin_t *spin);
|
|||||||
#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_SPIN_C_))
|
#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_SPIN_C_))
|
||||||
JEMALLOC_INLINE void
|
JEMALLOC_INLINE void
|
||||||
spin_adaptive(spin_t *spin) {
|
spin_adaptive(spin_t *spin) {
|
||||||
volatile uint64_t i;
|
volatile uint32_t i;
|
||||||
|
|
||||||
for (i = 0; i < (KQU(1) << spin->iteration); i++) {
|
if (spin->iteration < 5) {
|
||||||
CPU_SPINWAIT;
|
for (i = 0; i < (1U << spin->iteration); i++) {
|
||||||
}
|
CPU_SPINWAIT;
|
||||||
|
}
|
||||||
if (spin->iteration < 63) {
|
|
||||||
spin->iteration++;
|
spin->iteration++;
|
||||||
|
} else {
|
||||||
|
#ifdef _WIN32
|
||||||
|
SwitchToThread();
|
||||||
|
#else
|
||||||
|
sched_yield();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
16
test/unit/spin.c
Normal file
16
test/unit/spin.c
Normal file
@ -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);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user