std: introduce atomic.Mutex and use it in heap.SmpAllocator

This allocator implementation uses only lock-free operations.
This commit is contained in:
Andrew Kelley
2026-02-01 14:57:27 -08:00
parent e9eadee006
commit 255aeb57b2
2 changed files with 22 additions and 5 deletions
+21 -4
View File
@@ -1,3 +1,10 @@
const builtin = @import("builtin");
const std = @import("std.zig");
const AtomicOrder = std.builtin.AtomicOrder;
const testing = std.testing;
const assert = std.debug.assert;
/// This is a thin wrapper around a primitive value to prevent accidental data races.
pub fn Value(comptime T: type) type {
return extern struct {
@@ -496,7 +503,17 @@ test "current CPU has a cache line size" {
_ = cache_line;
}
const std = @import("std.zig");
const builtin = @import("builtin");
const AtomicOrder = std.builtin.AtomicOrder;
const testing = std.testing;
/// A lock-free single-owner resource.
pub const Mutex = enum(u8) {
unlocked,
locked,
pub fn tryLock(m: *Mutex) bool {
return @cmpxchgWeak(Mutex, m, .unlocked, .locked, .acquire, .monotonic) == null;
}
pub fn unlock(m: *Mutex) void {
assert(m.* == .locked);
@atomicStore(Mutex, m, .unlocked, .release);
}
};
+1 -1
View File
@@ -62,7 +62,7 @@ const Thread = struct {
///
/// Threads lock this before accessing their own state in order
/// to support freelist reclamation.
mutex: std.Thread.Mutex = .{},
mutex: std.atomic.Mutex = .unlocked,
/// For each size class, tracks the next address to be returned from
/// `alloc` when the freelist is empty.