Make the DynamicPackedIntArray data (unordered) atomic

This commit is contained in:
IntegratedQuantum 2025-07-28 16:26:59 +02:00
parent fe9b456cd8
commit 2e583c5072

View File

@ -989,7 +989,7 @@ pub fn deinitDynamicIntArrayStorage() void {
pub fn DynamicPackedIntArray(size: comptime_int) type { // MARK: DynamicPackedIntArray
std.debug.assert(std.math.isPowerOfTwo(size));
return struct {
data: []align(64) u32 = &.{},
data: []align(64) Atomic(u32) = &.{},
bitSize: u5 = 0,
const Self = @This();
@ -997,13 +997,13 @@ pub fn DynamicPackedIntArray(size: comptime_int) type { // MARK: DynamicPackedIn
pub fn initCapacity(bitSize: u5) Self {
std.debug.assert(bitSize == 0 or bitSize & bitSize - 1 == 0); // Must be a power of 2
return .{
.data = dynamicIntArrayAllocator.allocator().alignedAlloc(u32, .@"64", @as(usize, @divExact(size, @bitSizeOf(u32)))*bitSize),
.data = dynamicIntArrayAllocator.allocator().alignedAlloc(Atomic(u32), .@"64", @as(usize, @divExact(size, @bitSizeOf(u32)))*bitSize),
.bitSize = bitSize,
};
}
pub fn deinit(self: *Self) void {
dynamicIntArrayAllocator.allocator().free(self.data);
main.heap.GarbageCollection.deferredFreeSlice(dynamicIntArrayAllocator.allocator(), Atomic(u32), self.data);
self.* = .{};
}
@ -1021,12 +1021,12 @@ pub fn DynamicPackedIntArray(size: comptime_int) type { // MARK: DynamicPackedIn
var newSelf = Self.initCapacity(newBitSize);
switch(self.bitSize) {
0 => @memset(newSelf.data, 0),
0 => @memset(newSelf.data, .init(0)),
inline 1, 2, 4, 8 => |bits| {
for(0..self.data.len) |i| {
const oldVal = self.data[i];
newSelf.data[2*i] = bitInterleave(bits, oldVal & 0xffff);
newSelf.data[2*i + 1] = bitInterleave(bits, oldVal >> 16);
const oldVal = self.data[i].load(.unordered);
newSelf.data[2*i] = .init(bitInterleave(bits, oldVal & 0xffff));
newSelf.data[2*i + 1] = .init(bitInterleave(bits, oldVal >> 16));
}
},
else => unreachable,
@ -1042,7 +1042,7 @@ pub fn DynamicPackedIntArray(size: comptime_int) type { // MARK: DynamicPackedIn
const intIndex = bitIndex >> 5;
const bitOffset: u5 = @intCast(bitIndex & 31);
const bitMask = (@as(u32, 1) << self.bitSize) - 1;
return self.data[intIndex] >> bitOffset & bitMask;
return self.data[intIndex].load(.unordered) >> bitOffset & bitMask;
}
pub fn setValue(self: *Self, i: usize, value: u32) void {
@ -1053,9 +1053,9 @@ pub fn DynamicPackedIntArray(size: comptime_int) type { // MARK: DynamicPackedIn
const bitOffset: u5 = @intCast(bitIndex & 31);
const bitMask = (@as(u32, 1) << self.bitSize) - 1;
std.debug.assert(value <= bitMask);
const ptr: *u32 = &self.data[intIndex];
ptr.* &= ~(bitMask << bitOffset);
ptr.* |= value << bitOffset;
const ptr: *Atomic(u32) = &self.data[intIndex];
const old = ptr.load(.unordered);
ptr.store((old & ~(bitMask << bitOffset)) | value << bitOffset, .unordered);
}
pub fn setAndGetValue(self: *Self, i: usize, value: u32) u32 {
@ -1066,11 +1066,10 @@ pub fn DynamicPackedIntArray(size: comptime_int) type { // MARK: DynamicPackedIn
const bitOffset: u5 = @intCast(bitIndex & 31);
const bitMask = (@as(u32, 1) << self.bitSize) - 1;
std.debug.assert(value <= bitMask);
const ptr: *u32 = &self.data[intIndex];
const result = ptr.* >> bitOffset & bitMask;
ptr.* &= ~(bitMask << bitOffset);
ptr.* |= value << bitOffset;
return result;
const ptr: *Atomic(u32) = &self.data[intIndex];
const old = ptr.load(.unordered);
ptr.store((old & ~(bitMask << bitOffset)) | value << bitOffset, .unordered);
return old >> bitOffset & bitMask;
}
};
}