mirror of
https://github.com/rdmsr/zag.git
synced 2026-10-27 13:58:20 +00:00
rtl: add racy_read
This commit is contained in:
@@ -30,3 +30,8 @@ pub fn read_struct(
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Racily read a pointer on purpose.
|
||||
pub fn racy_read(comptime T: type, ptr: *T) T {
|
||||
return @atomicLoad(T, ptr, .unordered);
|
||||
}
|
||||
|
||||
+4
-4
@@ -24,8 +24,8 @@ pub fn SeqLockType(comptime T: type) type {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Relaxed load memcpy is needed here since data races are UB.
|
||||
rtl.barrier.atomic_load_memcpy(&ret, &self.raw, .monotonic);
|
||||
// Unordered load memcpy is needed here since data races are UB.
|
||||
rtl.barrier.atomic_load_memcpy(&ret, &self.raw, .unordered);
|
||||
|
||||
// Ensure the sequence read happens *after* the data is fully
|
||||
// loaded.
|
||||
@@ -49,8 +49,8 @@ pub fn SeqLockType(comptime T: type) type {
|
||||
// is incremented.
|
||||
rtl.barrier.fence(.release);
|
||||
|
||||
// Relaxed store memcpy is needed here since data races are UB.
|
||||
rtl.barrier.atomic_store_memcpy(&self.raw, &data, .monotonic);
|
||||
// Unordered store memcpy is needed here since data races are UB.
|
||||
rtl.barrier.atomic_store_memcpy(&self.raw, &data, .unordered);
|
||||
|
||||
self.sequence.store(seq + 2, .release);
|
||||
}
|
||||
|
||||
+2
-3
@@ -144,13 +144,12 @@ const Pool = struct {
|
||||
|
||||
/// Return whether or not a new worker thread should be added to this pool.
|
||||
fn should_grow(self: *Pool) bool {
|
||||
// NOTE: lockless racy check whether or not the queue is empty
|
||||
// Lockless racy check whether or not the queue is empty
|
||||
// and its active count.
|
||||
// This is fine as this is best effort anyway and is a heuristic.
|
||||
const is_empty = @atomicLoad(
|
||||
const is_empty = rtl.mem.racy_read(
|
||||
*rtl.List.Entry,
|
||||
&self.queue.items.head.next,
|
||||
.monotonic,
|
||||
) == &self.queue.items.head;
|
||||
|
||||
const active = self.queue.active.load(.monotonic);
|
||||
|
||||
@@ -293,11 +293,7 @@ pub fn RingBufferType(data_size_bits: usize, avg_msg_bits: usize) type {
|
||||
// Loading the ID here is purposely racey because
|
||||
// we check if the descriptor is valid anyway.
|
||||
const id: Id = @truncate(
|
||||
@atomicLoad(
|
||||
usize,
|
||||
@as(*usize, @ptrCast(&blk.id)),
|
||||
.monotonic,
|
||||
),
|
||||
rtl.mem.racy_read(usize, @ptrCast(&blk.id)),
|
||||
);
|
||||
const res = self.read_desc(id);
|
||||
desc = res.desc;
|
||||
|
||||
@@ -175,10 +175,9 @@ pub const Mutex = struct {
|
||||
|
||||
var gas: usize = 0;
|
||||
|
||||
while (@atomicLoad(
|
||||
while (rtl.mem.racy_read(
|
||||
?*ke.Thread,
|
||||
cpu_curtd,
|
||||
.unordered,
|
||||
) == owner and gas < optimistic_spins) : (gas += 1) {
|
||||
if (m.state.load(.monotonic) == State.uncontended) {
|
||||
// Got released, retry acquiring it.
|
||||
|
||||
@@ -1779,11 +1779,7 @@ pub fn idle(_: ?*anyopaque) noreturn {
|
||||
|
||||
while (true) {
|
||||
// Racy but only a hint anyway
|
||||
const next = @atomicLoad(
|
||||
?*ke.Thread,
|
||||
&cpu.next_thread,
|
||||
.monotonic,
|
||||
);
|
||||
const next = rtl.mem.racy_read(?*ke.Thread, &cpu.next_thread);
|
||||
|
||||
if (cpu.load.load(.monotonic) != 0 or next != null) {
|
||||
std.atomic.spinLoopHint();
|
||||
|
||||
+2
-2
@@ -736,7 +736,7 @@ pub const Zone = struct {
|
||||
// Local depot is empty, rebalance with the zone depot.
|
||||
// Purposefully race against cpu_depot_size because locking is
|
||||
// tricky here, we may get a stale value but it is harmless.
|
||||
const n = @atomicLoad(usize, &self.cpu_depot_size, .monotonic);
|
||||
const n = rtl.mem.racy_read(usize, &self.cpu_depot_size);
|
||||
|
||||
self.alloc_depot_rebalance(n, cpu);
|
||||
|
||||
@@ -924,7 +924,7 @@ pub const Zone = struct {
|
||||
|
||||
// Local depot is empty, rebalance with the zone depot.
|
||||
// Race explained in alloc.
|
||||
const n = @atomicLoad(usize, &self.cpu_depot_size, .monotonic);
|
||||
const n = rtl.mem.racy_read(usize, &self.cpu_depot_size);
|
||||
|
||||
self.free_depot_rebalance(n, cpu);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user