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 {
|
pub fn pushAll(self: *Self, items: []const Item) bool {
|
||||||
const new_len = self.items.len + items.len;
|
const new_len = self.items.len + items.len;
|
||||||
|
|
||||||
if (new_len < self.cap) {
|
if (new_len > self.items.cap) {
|
||||||
const index = self.items.len;
|
return false;
|
||||||
|
|
||||||
self.items.len = new_len;
|
|
||||||
|
|
||||||
std.debug.assert(self.items.sliced(index, self.items.len).copy(items));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
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;
|
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_align = @alignOf(Item);
|
||||||
const item_size = @sizeOf(usize);
|
const item_size = @sizeOf(Item);
|
||||||
const byte_size = @sizeOf(u8);
|
|
||||||
|
|
||||||
return Generic(Item, struct {
|
return Generic(Item, struct {
|
||||||
ptr: [*]align(item_align) u8 = undefined,
|
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 {
|
pub fn get(self: Self, index: usize) ?Item {
|
||||||
if (index >= self.cap) {
|
if (index >= self.len) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,29 +148,52 @@ pub fn Parallel(comptime Item: type) type {
|
|||||||
|
|
||||||
inline for (item_fields) |item_field| {
|
inline for (item_fields) |item_field| {
|
||||||
@field(item, item_field.name) = @as([*]item_field.type, @ptrCast(@alignCast(ptr)))[index];
|
@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;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn grow(self: *Self, allocator: std.mem.Allocator, amount: usize) std.mem.Allocator.Error!void {
|
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;
|
return error.OutOfMemory;
|
||||||
};
|
};
|
||||||
|
|
||||||
const reallocation = try allocator.alignedAlloc(u8, item_align, byte_size * new_cap);
|
if (new_cap != 0) {
|
||||||
const len_in_bytes = byte_size * self.len;
|
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]);
|
errdefer {
|
||||||
allocator.free(self.ptr[0 .. byte_size * self.cap]);
|
allocator.free(new_allocation);
|
||||||
|
}
|
||||||
|
|
||||||
self.ptr = reallocation.ptr;
|
if (old_cap != 0) {
|
||||||
self.cap = @intCast(new_cap);
|
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 {
|
pub fn set(self: Self, index: usize, item: Item) bool {
|
||||||
if (index >= self.cap) {
|
if (index >= self.len) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,7 +201,7 @@ pub fn Parallel(comptime Item: type) type {
|
|||||||
|
|
||||||
inline for (item_fields) |item_field| {
|
inline for (item_fields) |item_field| {
|
||||||
@as([*]item_field.type, @ptrCast(@alignCast(ptr)))[index] = @field(item, item_field.name);
|
@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;
|
return true;
|
||||||
@ -180,7 +212,7 @@ pub fn Parallel(comptime Item: type) type {
|
|||||||
var ptr: [*]u8 = self.ptr;
|
var ptr: [*]u8 = self.ptr;
|
||||||
|
|
||||||
inline for (item_fields[0..field_index]) |item_field| {
|
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];
|
return @as([*]item_fields[field_index].type, @ptrCast(@alignCast(ptr)))[0..self.len];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user