diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2019-06-27 12:05:12 -0400 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2019-06-27 12:05:12 -0400 |
| commit | 6cd3995754adcdcb1873c3fbfc0ec98ba95b68b5 (patch) | |
| tree | 386bc97a4f257fee93e467605e8d89f4a349a6ef /std | |
| parent | 516b5e649fa5f6c4043275b3dbe8e38273d79344 (diff) | |
| parent | 0041e00a7821f68c34f392b858ad1595c910dabc (diff) | |
| download | zig-6cd3995754adcdcb1873c3fbfc0ec98ba95b68b5.tar.gz zig-6cd3995754adcdcb1873c3fbfc0ec98ba95b68b5.zip | |
Merge branch 'daurnimator-logging-allocator'
Diffstat (limited to 'std')
| -rw-r--r-- | std/heap.zig | 2 | ||||
| -rw-r--r-- | std/heap/logging_allocator.zig | 53 |
2 files changed, 55 insertions, 0 deletions
diff --git a/std/heap.zig b/std/heap.zig index c72c6456cd..d14f34dd6e 100644 --- a/std/heap.zig +++ b/std/heap.zig @@ -8,6 +8,8 @@ const builtin = @import("builtin"); const c = std.c; const maxInt = std.math.maxInt; +pub const LoggingAllocator = @import("heap/logging_allocator.zig").LoggingAllocator; + const Allocator = mem.Allocator; pub const c_allocator = &c_allocator_state; diff --git a/std/heap/logging_allocator.zig b/std/heap/logging_allocator.zig new file mode 100644 index 0000000000..c1f09a1aad --- /dev/null +++ b/std/heap/logging_allocator.zig @@ -0,0 +1,53 @@ +const std = @import("../std.zig"); +const Allocator = std.mem.Allocator; + +const AnyErrorOutStream = std.io.OutStream(anyerror); + +/// This allocator is used in front of another allocator and logs to the provided stream +/// on every call to the allocator. Stream errors are ignored. +/// If https://github.com/ziglang/zig/issues/2586 is implemented, this API can be improved. +pub const LoggingAllocator = struct { + allocator: Allocator, + parent_allocator: *Allocator, + out_stream: *AnyErrorOutStream, + + const Self = @This(); + + pub fn init(parent_allocator: *Allocator, out_stream: *AnyErrorOutStream) Self { + return Self{ + .allocator = Allocator{ + .reallocFn = realloc, + .shrinkFn = shrink, + }, + .parent_allocator = parent_allocator, + .out_stream = out_stream, + }; + } + + fn realloc(allocator: *Allocator, old_mem: []u8, old_align: u29, new_size: usize, new_align: u29) ![]u8 { + const self = @fieldParentPtr(Self, "allocator", allocator); + if (old_mem.len == 0) { + self.out_stream.print("allocation of {} ", new_size) catch {}; + } else { + self.out_stream.print("resize from {} to {} ", old_mem.len, new_size) catch {}; + } + const result = self.parent_allocator.reallocFn(self.parent_allocator, old_mem, old_align, new_size, new_align); + if (result) |buff| { + self.out_stream.print("success!\n") catch {}; + } else |err| { + self.out_stream.print("failure!\n") catch {}; + } + return result; + } + + fn shrink(allocator: *Allocator, old_mem: []u8, old_align: u29, new_size: usize, new_align: u29) []u8 { + const self = @fieldParentPtr(Self, "allocator", allocator); + const result = self.parent_allocator.shrinkFn(self.parent_allocator, old_mem, old_align, new_size, new_align); + if (new_size == 0) { + self.out_stream.print("free of {} bytes success!\n", old_mem.len) catch {}; + } else { + self.out_stream.print("shrink from {} bytes to {} bytes success!\n", old_mem.len, new_size) catch {}; + } + return result; + } +}; |
