diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2024-11-28 14:56:08 -0500 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2024-12-03 14:42:05 -0500 |
commit | b4ce4d681ed0a3660be08d3d1ce881783fb018ab (patch) | |
tree | 99feec7f8cb11e472b63726a46e0c218319d1483 /src | |
parent | ac393d60a3d390ffc3b5f79e9099ecb805e80ba9 (diff) | |
download | bfs-b4ce4d681ed0a3660be08d3d1ce881783fb018ab.tar.xz |
ioq: Try spinning before blocking in ioq_slot_wait()
Diffstat (limited to 'src')
-rw-r--r-- | src/ioq.c | 18 |
1 files changed, 17 insertions, 1 deletions
@@ -277,10 +277,26 @@ static struct ioq_monitor *ioq_slot_monitor(struct ioqq *ioqq, ioq_slot *slot) { /** Atomically wait for a slot to change. */ _noinline static uintptr_t ioq_slot_wait(struct ioqq *ioqq, ioq_slot *slot, uintptr_t value) { + // Try spinning a few times before blocking + uintptr_t ret; + for (int i = 0; i < 10; ++i) { + // Exponential backoff + for (int j = 0; j < (1 << i); ++j) { + spin_loop(); + } + + // Check if the slot changed + ret = load(slot, relaxed); + if (ret != value) { + return ret; + } + } + + // Nothing changed, start blocking struct ioq_monitor *monitor = ioq_slot_monitor(ioqq, slot); mutex_lock(&monitor->mutex); - uintptr_t ret = load(slot, relaxed); + ret = load(slot, relaxed); if (ret != value) { goto done; } |