ke: change mutex spinning policy

This commit is contained in:
Loïc Grégoire
2026-06-27 10:06:17 -04:00
parent 55b89c1880
commit f94098d0a5
+19 -4
View File
@@ -3,7 +3,7 @@ const ke = @import("root").ke;
const ki = ke.private; const ki = ke.private;
/// Number of spins before blocking. /// Number of spins before blocking.
const optimistic_spins = 10000; const optimistic_spins = 100;
pub const Mutex = struct { pub const Mutex = struct {
/// The thread currently holding the mutex, null if unlocked. /// The thread currently holding the mutex, null if unlocked.
@@ -17,14 +17,29 @@ pub const Mutex = struct {
const ipl = ke.ipl.raise(.Dispatch); const ipl = ke.ipl.raise(.Dispatch);
const curtd = ki.sched.percpu.local().current_thread.?; const curtd = ki.sched.percpu.local().current_thread.?;
// Fast path: try to acquire without a turnstile by spinning a bit. // Very fast path: the lock is uncontended and we can acquire it immediately.
for (0..optimistic_spins) |_| { const cur_owner = m.owner.cmpxchgStrong(null, curtd, .acquire, .monotonic);
if (m.owner.cmpxchgStrong(null, curtd, .acquire, .monotonic) == null) {
if (cur_owner == null) {
ke.ipl.lower(ipl); ke.ipl.lower(ipl);
return; return;
} }
// Fast path: if the owner is running, try to acquire without a turnstile by spinning a bit.
if (cur_owner.?.?.state.load(.monotonic) == .Running) {
for (0..optimistic_spins) |_| {
if (m.owner.cmpxchgStrong(null, curtd, .acquire, .monotonic)) |maybe_owner| {
const owner = maybe_owner.?;
if (owner.state.load(.monotonic) != .Running) break;
std.atomic.spinLoopHint(); std.atomic.spinLoopHint();
continue;
}
ke.ipl.lower(ipl);
return;
}
} }
// Slow path: contended, block on a turnstile. // Slow path: contended, block on a turnstile.