| author | |
| committer | |
| log | 658de75500871f28015aa2ff14872eed0410dddf |
| tree | 417adcfd2d59ca065d45b12be27d261dee252596 |
| parent | 5b90fa05a4e5b155f25319713acfc67ad9516c69 |
This wraps any allocator and makes it thread-safe by using a mutex.2 files changed, 46 insertions(+), 0 deletions(-)
lib/std/heap.zig+1| ... | @@ -19,6 +19,7 @@ pub const GeneralPurposeAllocator = @import("heap/general_purpose_allocator.zig" | ... | @@ -19,6 +19,7 @@ pub const GeneralPurposeAllocator = @import("heap/general_purpose_allocator.zig" |
| 19 | pub const WasmAllocator = @import("heap/WasmAllocator.zig"); | 19 | pub const WasmAllocator = @import("heap/WasmAllocator.zig"); |
| 20 | pub const WasmPageAllocator = @import("heap/WasmPageAllocator.zig"); | 20 | pub const WasmPageAllocator = @import("heap/WasmPageAllocator.zig"); |
| 21 | pub const PageAllocator = @import("heap/PageAllocator.zig"); | 21 | pub const PageAllocator = @import("heap/PageAllocator.zig"); |
| 22 | pub const ThreadSafeAllocator = @import("heap/ThreadSafeAllocator.zig"); | ||
| 22 | 23 | ||
| 23 | const memory_pool = @import("heap/memory_pool.zig"); | 24 | const memory_pool = @import("heap/memory_pool.zig"); |
| 24 | pub const MemoryPool = memory_pool.MemoryPool; | 25 | pub const MemoryPool = memory_pool.MemoryPool; |
lib/std/heap/ThreadSafeAllocator.zig created+45| ... | @@ -0,0 +1,45 @@ | ||
| 1 | //! Wraps a non-thread-safe allocator and makes it thread-safe. | ||
| 2 | |||
| 3 | child_allocator: Allocator, | ||
| 4 | mutex: std.Thread.Mutex = .{}, | ||
| 5 | |||
| 6 | pub fn allocator(self: *ThreadSafeAllocator) Allocator { | ||
| 7 | return .{ | ||
| 8 | .ptr = self, | ||
| 9 | .vtable = &.{ | ||
| 10 | .alloc = alloc, | ||
| 11 | .resize = resize, | ||
| 12 | .free = free, | ||
| 13 | }, | ||
| 14 | }; | ||
| 15 | } | ||
| 16 | |||
| 17 | fn alloc(ctx: *anyopaque, n: usize, log2_ptr_align: u8, ra: usize) ?[*]u8 { | ||
| 18 | const self = @ptrCast(*ThreadSafeAllocator, @alignCast(@alignOf(ThreadSafeAllocator), ctx)); | ||
| 19 | self.mutex.lock(); | ||
| 20 | defer self.mutex.unlock(); | ||
| 21 | |||
| 22 | return self.child_allocator.rawAlloc(n, log2_ptr_align, ra); | ||
| 23 | } | ||
| 24 | |||
| 25 | fn resize(ctx: *anyopaque, buf: []u8, log2_buf_align: u8, new_len: usize, ret_addr: usize) bool { | ||
| 26 | const self = @ptrCast(*ThreadSafeAllocator, @alignCast(@alignOf(ThreadSafeAllocator), ctx)); | ||
| 27 | |||
| 28 | self.mutex.lock(); | ||
| 29 | defer self.mutex.unlock(); | ||
| 30 | |||
| 31 | return self.child_allocator.rawResize(buf, log2_buf_align, new_len, ret_addr); | ||
| 32 | } | ||
| 33 | |||
| 34 | fn free(ctx: *anyopaque, buf: []u8, log2_buf_align: u8, ret_addr: usize) void { | ||
| 35 | const self = @ptrCast(*ThreadSafeAllocator, @alignCast(@alignOf(ThreadSafeAllocator), ctx)); | ||
| 36 | |||
| 37 | self.mutex.lock(); | ||
| 38 | defer self.mutex.unlock(); | ||
| 39 | |||
| 40 | return self.child_allocator.rawFree(buf, log2_buf_align, ret_addr); | ||
| 41 | } | ||
| 42 | |||
| 43 | const std = @import("../std.zig"); | ||
| 44 | const ThreadSafeAllocator = @This(); | ||
| 45 | const Allocator = std.mem.Allocator; | ||