| ... | @@ -248,8 +248,8 @@ const Node = struct { | ... | @@ -248,8 +248,8 @@ const Node = struct { |
| 248 | }; | 248 | }; |
| 249 | | 249 | |
| 250 | fn loadBuf(node: *Node) []u8 { | 250 | fn loadBuf(node: *Node) []u8 { |
| 251 | // monotonic is fine since `size` can only ever grow, so the buffer returned | 251 | // `size` can only ever grow, so the buffer returned by this function is |
| 252 | // by this function is always valid memory. | 252 | // always valid memory. |
| 253 | const size = @atomicLoad(Size, &node.size, .monotonic); | 253 | const size = @atomicLoad(Size, &node.size, .monotonic); |
| 254 | return @as([*]u8, @ptrCast(node))[0..size.toInt()][@sizeOf(Node)..]; | 254 | return @as([*]u8, @ptrCast(node))[0..size.toInt()][@sizeOf(Node)..]; |
| 255 | } | 255 | } |
| ... | @@ -298,8 +298,9 @@ fn tryPushNode(arena: *ArenaAllocator, node: *Node) PushResult { | ... | @@ -298,8 +298,9 @@ fn tryPushNode(arena: *ArenaAllocator, node: *Node) PushResult { |
| 298 | } | 298 | } |
| 299 | | 299 | |
| 300 | fn stealFreeList(arena: *ArenaAllocator) ?*Node { | 300 | fn stealFreeList(arena: *ArenaAllocator) ?*Node { |
| 301 | // syncs with acq_rel in other `stealFreeList` calls or release in `pushFreeList` | 301 | // We don't need acq_rel here because we're always swapping in `null`, so |
| 302 | return @atomicRmw(?*Node, &arena.state.free_list, .Xchg, null, .acq_rel); | 302 | // there's no node we'd need to release. |
| | 303 | return @atomicRmw(?*Node, &arena.state.free_list, .Xchg, null, .acquire); // syncs with release in `pushFreeList` |
| 303 | } | 304 | } |
| 304 | | 305 | |
| 305 | fn pushFreeList(arena: *ArenaAllocator, first: *Node, last: *Node) void { | 306 | fn pushFreeList(arena: *ArenaAllocator, first: *Node, last: *Node) void { |
| ... | @@ -311,7 +312,7 @@ fn pushFreeList(arena: *ArenaAllocator, first: *Node, last: *Node) void { | ... | @@ -311,7 +312,7 @@ fn pushFreeList(arena: *ArenaAllocator, first: *Node, last: *Node) void { |
| 311 | &arena.state.free_list, | 312 | &arena.state.free_list, |
| 312 | last.next, | 313 | last.next, |
| 313 | first, | 314 | first, |
| 314 | .release, // syncs with acquire part of acq_rel in `stealFreeList` | 315 | .release, // syncs with acquire in `stealFreeList` |
| 315 | .monotonic, // we never access any fields of `old_free_list`, we only care about the pointer | 316 | .monotonic, // we never access any fields of `old_free_list`, we only care about the pointer |
| 316 | )) |old_free_list| { | 317 | )) |old_free_list| { |
| 317 | last.next = old_free_list; | 318 | last.next = old_free_list; |