summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2024-11-28 14:56:08 -0500
committerTavian Barnes <tavianator@tavianator.com>2024-12-03 13:55:32 -0500
commit95313df74baaadf80fa1cf41d4b044bdeadcbd84 (patch)
treee39a371b62bb2e03a1eadb0258aad575428923dc
parent41f2b1ff4ee0542d860bf253a3843abd8b1a0366 (diff)
downloadbfs-95313df74baaadf80fa1cf41d4b044bdeadcbd84.tar.xz
ioq: Try spinning before blocking in ioq_slot_wait()ioq-nop
-rw-r--r--src/ioq.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/src/ioq.c b/src/ioq.c
index 1280598..b845a2c 100644
--- a/src/ioq.c
+++ b/src/ioq.c
@@ -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;
}