authorgravatar for john.schmidt.h@gmail.comJohn Schmidt <john.schmidt.h@gmail.com> 2019-02-07 21:28:37+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-02-07 23:21:37-05:00
logbe6d022257d8d7e99bd080823d4d8f0175f320c5
treee4bafc487c702e65bf18fb95ab2df21509a68e8a
parentf330eebe4bc6a036846cf05706f72855627c705a

Make ThreadSafeFixedBufferAllocator alias FixedBufferAllocator when --single-threaded

Fixes #1910

1 files changed, 46 insertions(+), 40 deletions(-)

std/heap.zig+46-40
...@@ -321,51 +321,57 @@ pub const FixedBufferAllocator = struct {...@@ -321,51 +321,57 @@ pub const FixedBufferAllocator = struct {
321 fn free(allocator: *Allocator, bytes: []u8) void {}321 fn free(allocator: *Allocator, bytes: []u8) void {}
322};322};
323323
324/// lock free324pub const ThreadSafeFixedBufferAllocator = blk: {
325pub const ThreadSafeFixedBufferAllocator = struct {325 if (builtin.single_threaded) {
326 allocator: Allocator,326 break :blk FixedBufferAllocator;
327 end_index: usize,327 } else {
328 buffer: []u8,328 /// lock free
329 break :blk struct {
330 allocator: Allocator,
331 end_index: usize,
332 buffer: []u8,
333
334 pub fn init(buffer: []u8) ThreadSafeFixedBufferAllocator {
335 return ThreadSafeFixedBufferAllocator{
336 .allocator = Allocator{
337 .allocFn = alloc,
338 .reallocFn = realloc,
339 .freeFn = free,
340 },
341 .buffer = buffer,
342 .end_index = 0,
343 };
344 }
329345
330 pub fn init(buffer: []u8) ThreadSafeFixedBufferAllocator {346 fn alloc(allocator: *Allocator, n: usize, alignment: u29) ![]u8 {
331 return ThreadSafeFixedBufferAllocator{347 const self = @fieldParentPtr(ThreadSafeFixedBufferAllocator, "allocator", allocator);
332 .allocator = Allocator{348 var end_index = @atomicLoad(usize, &self.end_index, builtin.AtomicOrder.SeqCst);
333 .allocFn = alloc,349 while (true) {
334 .reallocFn = realloc,350 const addr = @ptrToInt(self.buffer.ptr) + end_index;
335 .freeFn = free,351 const rem = @rem(addr, alignment);
336 },352 const march_forward_bytes = if (rem == 0) 0 else (alignment - rem);
337 .buffer = buffer,353 const adjusted_index = end_index + march_forward_bytes;
338 .end_index = 0,354 const new_end_index = adjusted_index + n;
339 };355 if (new_end_index > self.buffer.len) {
340 }356 return error.OutOfMemory;
357 }
358 end_index = @cmpxchgWeak(usize, &self.end_index, end_index, new_end_index, builtin.AtomicOrder.SeqCst, builtin.AtomicOrder.SeqCst) orelse return self.buffer[adjusted_index..new_end_index];
359 }
360 }
341361
342 fn alloc(allocator: *Allocator, n: usize, alignment: u29) ![]u8 {362 fn realloc(allocator: *Allocator, old_mem: []u8, new_size: usize, alignment: u29) ![]u8 {
343 const self = @fieldParentPtr(ThreadSafeFixedBufferAllocator, "allocator", allocator);363 if (new_size <= old_mem.len) {
344 var end_index = @atomicLoad(usize, &self.end_index, builtin.AtomicOrder.SeqCst);364 return old_mem[0..new_size];
345 while (true) {365 } else {
346 const addr = @ptrToInt(self.buffer.ptr) + end_index;366 const result = try alloc(allocator, new_size, alignment);
347 const rem = @rem(addr, alignment);367 mem.copy(u8, result, old_mem);
348 const march_forward_bytes = if (rem == 0) 0 else (alignment - rem);368 return result;
349 const adjusted_index = end_index + march_forward_bytes;369 }
350 const new_end_index = adjusted_index + n;
351 if (new_end_index > self.buffer.len) {
352 return error.OutOfMemory;
353 }370 }
354 end_index = @cmpxchgWeak(usize, &self.end_index, end_index, new_end_index, builtin.AtomicOrder.SeqCst, builtin.AtomicOrder.SeqCst) orelse return self.buffer[adjusted_index..new_end_index];
355 }
356 }
357371
358 fn realloc(allocator: *Allocator, old_mem: []u8, new_size: usize, alignment: u29) ![]u8 {372 fn free(allocator: *Allocator, bytes: []u8) void {}
359 if (new_size <= old_mem.len) {373 };
360 return old_mem[0..new_size];
361 } else {
362 const result = try alloc(allocator, new_size, alignment);
363 mem.copy(u8, result, old_mem);
364 return result;
365 }
366 }374 }
367
368 fn free(allocator: *Allocator, bytes: []u8) void {}
369};375};
370376
371pub fn stackFallback(comptime size: usize, fallback_allocator: *Allocator) StackFallbackAllocator(size) {377pub fn stackFallback(comptime size: usize, fallback_allocator: *Allocator) StackFallbackAllocator(size) {