const Thread = struct _: void = {}Avoid false sharing.
mutex: std.atomic.Mutex = .unlockedProtects the state in this struct (per-thread state).
Threads lock this before accessing their own state in order to support freelist reclamation.
next_addrs: [size_class_count]usize = @splat(0)For each size class, tracks the next address to be returned from alloc when the freelist is empty.
frees: [size_class_count]usize = @splat(0)For each size class, points to the freed pointer.
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98const Thread = struct {
/// Avoid false sharing.
_: void align(std.atomic.cache_line) = {},
/// Protects the state in this struct (per-thread state).
///
/// Threads lock this before accessing their own state in order
/// to support freelist reclamation.
mutex: std.atomic.Mutex = .unlocked,
/// For each size class, tracks the next address to be returned from
/// `alloc` when the freelist is empty.
next_addrs: [size_class_count]usize = @splat(0),
/// For each size class, points to the freed pointer.
frees: [size_class_count]usize = @splat(0),
fn lock() *Thread {
var index = thread_index;
{
const t = &global.threads[index];
if (t.mutex.tryLock()) {
@branchHint(.likely);
return t;
}
}
const cpu_count = getCpuCount();
assert(cpu_count != 0);
while (true) {
index = (index + 1) % cpu_count;
const t = &global.threads[index];
if (t.mutex.tryLock()) {
thread_index = index;
return t;
}
}
}
fn unlock(t: *Thread) void {
t.mutex.unlock();
}
}