authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-06-27 12:04:14-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-06-27 12:04:14-04:00
log0041e00a7821f68c34f392b858ad1595c910dabc
tree386bc97a4f257fee93e467605e8d89f4a349a6ef
parentc346b257bba0b4f62c3a27970efa0a53894da6cf
signature Commit is signed but in an unrecognized format.

fixups

* move LoggingAllocator to its own file * style conventions * add documentation * use `anyerror` instead of `error{}` for the stream

3 files changed, 56 insertions(+), 47 deletions(-)

CMakeLists.txt+1
......@@ -524,6 +524,7 @@ set(ZIG_STD_FILES
524524 "hash/siphash.zig"
525525 "hash_map.zig"
526526 "heap.zig"
527 "heap/logging_allocator.zig"
527528 "io.zig"
528529 "io/c_out_stream.zig"
529530 "io/seekable_stream.zig"
std/heap.zig+2-47
......@@ -8,6 +8,8 @@ const builtin = @import("builtin");
88const c = std.c;
99const maxInt = std.math.maxInt;
1010
11pub const LoggingAllocator = @import("heap/logging_allocator.zig").LoggingAllocator;
12
1113const Allocator = mem.Allocator;
1214
1315pub const c_allocator = &c_allocator_state;
......@@ -713,53 +715,6 @@ pub fn StackFallbackAllocator(comptime size: usize) type {
713715 };
714716}
715717
716pub const NoErrorOutStream = std.io.OutStream(error{});
717pub const LoggingAllocator = struct {
718 allocator: Allocator,
719 parentAllocator: *Allocator,
720 outStream: *NoErrorOutStream,
721
722 const Self = @This();
723
724 pub fn init(parentAllocator: *Allocator, outStream: *NoErrorOutStream) Self {
725 return Self{
726 .allocator = Allocator{
727 .reallocFn = realloc,
728 .shrinkFn = shrink,
729 },
730 .parentAllocator = parentAllocator,
731 .outStream = outStream,
732 };
733 }
734
735 fn realloc(allocator: *Allocator, old_mem: []u8, old_align: u29, new_size: usize, new_align: u29) ![]u8 {
736 const self = @fieldParentPtr(Self, "allocator", allocator);
737 if (old_mem.len == 0) {
738 self.outStream.print("allocation of {} ", new_size) catch unreachable;
739 } else {
740 self.outStream.print("resize from {} to {} ", old_mem.len, new_size) catch unreachable;
741 }
742 const result = self.parentAllocator.reallocFn(self.parentAllocator, old_mem, old_align, new_size, new_align);
743 if (result) |buff| {
744 self.outStream.print("success!\n") catch unreachable;
745 } else |err| {
746 self.outStream.print("failure!\n") catch unreachable;
747 }
748 return result;
749 }
750
751 fn shrink(allocator: *Allocator, old_mem: []u8, old_align: u29, new_size: usize, new_align: u29) []u8 {
752 const self = @fieldParentPtr(Self, "allocator", allocator);
753 const result = self.parentAllocator.shrinkFn(self.parentAllocator, old_mem, old_align, new_size, new_align);
754 if (new_size == 0) {
755 self.outStream.print("free of {} bytes success!\n", old_mem.len) catch unreachable;
756 } else {
757 self.outStream.print("shrink from {} bytes to {} bytes success!\n", old_mem.len, new_size) catch unreachable;
758 }
759 return result;
760 }
761};
762
763718test "c_allocator" {
764719 if (builtin.link_libc) {
765720 var slice = try c_allocator.alloc(u8, 50);
std/heap/logging_allocator.zig created+53
......@@ -0,0 +1,53 @@
1const std = @import("../std.zig");
2const Allocator = std.mem.Allocator;
3
4const 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.
9pub 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};