Fix parallel stack bugs
This commit is contained in:
parent
9b0368a568
commit
3ddf351a08
@ -61,17 +61,17 @@ fn Generic(comptime Item: type, comptime Storage: type) type {
|
||||
pub fn pushAll(self: *Self, items: []const Item) bool {
|
||||
const new_len = self.items.len + items.len;
|
||||
|
||||
if (new_len < self.cap) {
|
||||
const index = self.items.len;
|
||||
|
||||
self.items.len = new_len;
|
||||
|
||||
std.debug.assert(self.items.sliced(index, self.items.len).copy(items));
|
||||
|
||||
return true;
|
||||
if (new_len > self.items.cap) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
const index = self.items.len;
|
||||
|
||||
self.items.len = new_len;
|
||||
|
||||
std.debug.assert(self.items.sliced(index, self.items.len).copy(items));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
pub fn pushGrow(self: *Self, allocator: std.mem.Allocator, item: Item) std.mem.Allocator.Error!void {
|
||||
@ -99,6 +99,16 @@ fn Generic(comptime Item: type, comptime Storage: type) type {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
pub fn set(self: *Self, item: Item) bool {
|
||||
if (self.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std.debug.assert(self.items.set(self.items.len - 1, item));
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -109,8 +119,7 @@ pub fn Parallel(comptime Item: type) type {
|
||||
};
|
||||
|
||||
const item_align = @alignOf(Item);
|
||||
const item_size = @sizeOf(usize);
|
||||
const byte_size = @sizeOf(u8);
|
||||
const item_size = @sizeOf(Item);
|
||||
|
||||
return Generic(Item, struct {
|
||||
ptr: [*]align(item_align) u8 = undefined,
|
||||
@ -130,7 +139,7 @@ pub fn Parallel(comptime Item: type) type {
|
||||
}
|
||||
|
||||
pub fn get(self: Self, index: usize) ?Item {
|
||||
if (index >= self.cap) {
|
||||
if (index >= self.len) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -139,29 +148,52 @@ pub fn Parallel(comptime Item: type) type {
|
||||
|
||||
inline for (item_fields) |item_field| {
|
||||
@field(item, item_field.name) = @as([*]item_field.type, @ptrCast(@alignCast(ptr)))[index];
|
||||
ptr += @sizeOf(item_field.type) * self.len;
|
||||
ptr += @sizeOf(item_field.type) * self.cap;
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
pub fn grow(self: *Self, allocator: std.mem.Allocator, amount: usize) std.mem.Allocator.Error!void {
|
||||
const new_cap = std.math.cast(u32, @as(usize, self.cap + amount)) orelse {
|
||||
const old_cap = self.cap;
|
||||
|
||||
const new_cap = std.math.cast(u32, @as(usize, old_cap) + amount) orelse {
|
||||
return error.OutOfMemory;
|
||||
};
|
||||
|
||||
const reallocation = try allocator.alignedAlloc(u8, item_align, byte_size * new_cap);
|
||||
const len_in_bytes = byte_size * self.len;
|
||||
if (new_cap != 0) {
|
||||
const new_allocation = try allocator.alignedAlloc(u8, item_align, item_size * new_cap);
|
||||
|
||||
@memcpy(reallocation[0..len_in_bytes], self.ptr[0..len_in_bytes]);
|
||||
allocator.free(self.ptr[0 .. byte_size * self.cap]);
|
||||
errdefer {
|
||||
allocator.free(new_allocation);
|
||||
}
|
||||
|
||||
self.ptr = reallocation.ptr;
|
||||
self.cap = @intCast(new_cap);
|
||||
if (old_cap != 0) {
|
||||
var old_ptr_offset: usize = 0;
|
||||
var new_ptr_offset: usize = 0;
|
||||
|
||||
inline for (item_fields) |field| {
|
||||
const FieldType = field.type;
|
||||
const old_field_ptr: [*]const FieldType = @ptrCast(@alignCast(self.ptr + old_ptr_offset));
|
||||
const new_field_ptr: [*]FieldType = @ptrCast(@alignCast(new_allocation.ptr + new_ptr_offset));
|
||||
|
||||
@memcpy(new_field_ptr[0..self.len], old_field_ptr[0..self.len]);
|
||||
|
||||
old_ptr_offset += @sizeOf(FieldType) * old_cap;
|
||||
new_ptr_offset += @sizeOf(FieldType) * new_cap;
|
||||
}
|
||||
|
||||
// Free the old allocation
|
||||
allocator.free(self.ptr[0 .. item_size * old_cap]);
|
||||
}
|
||||
|
||||
self.ptr = new_allocation.ptr;
|
||||
self.cap = new_cap;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set(self: Self, index: usize, item: Item) bool {
|
||||
if (index >= self.cap) {
|
||||
if (index >= self.len) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -169,7 +201,7 @@ pub fn Parallel(comptime Item: type) type {
|
||||
|
||||
inline for (item_fields) |item_field| {
|
||||
@as([*]item_field.type, @ptrCast(@alignCast(ptr)))[index] = @field(item, item_field.name);
|
||||
ptr += @sizeOf(item_field.type) * self.len;
|
||||
ptr += @sizeOf(item_field.type) * self.cap;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -180,7 +212,7 @@ pub fn Parallel(comptime Item: type) type {
|
||||
var ptr: [*]u8 = self.ptr;
|
||||
|
||||
inline for (item_fields[0..field_index]) |item_field| {
|
||||
ptr += @sizeOf(item_field.type) * self.len;
|
||||
ptr += @sizeOf(item_field.type) * self.cap;
|
||||
}
|
||||
|
||||
return @as([*]item_fields[field_index].type, @ptrCast(@alignCast(ptr)))[0..self.len];
|
||||
|
Loading…
x
Reference in New Issue
Block a user