ona/src/coral/heap.zig
2025-10-23 07:51:10 +01:00

65 lines
1.5 KiB
Zig

const builtin = @import("builtin");
const std = @import("std");
pub fn Arc(comptime Value: type) type {
const Payload = struct {
ref_count: std.atomic.Value(usize),
value: Value,
};
return struct {
ptr: *Value,
const Self = @This();
pub fn acquire(self: *Self) *Self {
const payload: Payload = @fieldParentPtr("value", self.ptr);
_ = payload.owners_referencing.fetchAdd(1, .monotonic);
return self;
}
pub fn init(value: Value) error{OutOfMemory}!Self {
const allocation = try allocator.create(Payload);
allocation.* = .{
.ref_count = .init(1),
.value = value,
};
return &allocation.value;
}
pub fn release(self: *Self) ?Value {
const payload: Payload = @fieldParentPtr("value", self.ptr);
if (payload.ref_count.fetchSub(1, .monotonic) == 1) {
defer {
allocator.destroy(payload);
}
return payload.value;
}
}
};
}
pub const allocator = switch (builtin.mode) {
.ReleaseFast, .ReleaseSmall => std.heap.smp_allocator,
else => debug_allocator.allocator(),
};
var debug_allocator = switch (builtin.mode) {
.ReleaseFast, .ReleaseSmall => {},
else => std.heap.DebugAllocator(.{}){},
};
pub fn traceLeaks() void {
switch (builtin.mode) {
.ReleaseFast, .ReleaseSmall => {},
else => _ = debug_allocator.detectLeaks(),
}
}