| ... | @@ -0,0 +1,53 @@ |
| 1 | const std = @import("../std.zig"); |
| 2 | const Allocator = std.mem.Allocator; |
| 3 | |
| 4 | const AnyErrorOutStream = std.io.OutStream(anyerror); |
| 5 | |
| 6 | /// This allocator is used in front of another allocator and logs to the provided stream |
| 7 | /// on every call to the allocator. Stream errors are ignored. |
| 8 | /// If https://github.com/ziglang/zig/issues/2586 is implemented, this API can be improved. |
| 9 | pub const LoggingAllocator = struct { |
| 10 | allocator: Allocator, |
| 11 | parent_allocator: *Allocator, |
| 12 | out_stream: *AnyErrorOutStream, |
| 13 | |
| 14 | const Self = @This(); |
| 15 | |
| 16 | pub fn init(parent_allocator: *Allocator, out_stream: *AnyErrorOutStream) Self { |
| 17 | return Self{ |
| 18 | .allocator = Allocator{ |
| 19 | .reallocFn = realloc, |
| 20 | .shrinkFn = shrink, |
| 21 | }, |
| 22 | .parent_allocator = parent_allocator, |
| 23 | .out_stream = out_stream, |
| 24 | }; |
| 25 | } |
| 26 | |
| 27 | fn realloc(allocator: *Allocator, old_mem: []u8, old_align: u29, new_size: usize, new_align: u29) ![]u8 { |
| 28 | const self = @fieldParentPtr(Self, "allocator", allocator); |
| 29 | if (old_mem.len == 0) { |
| 30 | self.out_stream.print("allocation of {} ", new_size) catch {}; |
| 31 | } else { |
| 32 | self.out_stream.print("resize from {} to {} ", old_mem.len, new_size) catch {}; |
| 33 | } |
| 34 | const result = self.parent_allocator.reallocFn(self.parent_allocator, old_mem, old_align, new_size, new_align); |
| 35 | if (result) |buff| { |
| 36 | self.out_stream.print("success!\n") catch {}; |
| 37 | } else |err| { |
| 38 | self.out_stream.print("failure!\n") catch {}; |
| 39 | } |
| 40 | return result; |
| 41 | } |
| 42 | |
| 43 | fn shrink(allocator: *Allocator, old_mem: []u8, old_align: u29, new_size: usize, new_align: u29) []u8 { |
| 44 | const self = @fieldParentPtr(Self, "allocator", allocator); |
| 45 | const result = self.parent_allocator.shrinkFn(self.parent_allocator, old_mem, old_align, new_size, new_align); |
| 46 | if (new_size == 0) { |
| 47 | self.out_stream.print("free of {} bytes success!\n", old_mem.len) catch {}; |
| 48 | } else { |
| 49 | self.out_stream.print("shrink from {} bytes to {} bytes success!\n", old_mem.len, new_size) catch {}; |
| 50 | } |
| 51 | return result; |
| 52 | } |
| 53 | }; |