change refcount type to enum so none can be select

This commit is contained in:
Brendan Hansknecht 2022-04-01 13:48:14 -07:00
parent ef49d5714b
commit 805e4ef5d3

View file

@ -120,15 +120,26 @@ pub const IntWidth = enum(u8) {
I128 = 9, I128 = 9,
}; };
const USE_ATOMICS = false; const Refcount = enum {
none,
normal,
atomic,
};
const RC_TYPE = Refcount.normal;
pub fn increfC(ptr_to_refcount: *isize, amount: isize) callconv(.C) void { pub fn increfC(ptr_to_refcount: *isize, amount: isize) callconv(.C) void {
if (RC_TYPE == Refcount.none) return;
var refcount = ptr_to_refcount.*; var refcount = ptr_to_refcount.*;
var masked_amount = if (refcount < REFCOUNT_MAX_ISIZE) amount else 0; var masked_amount = if (refcount < REFCOUNT_MAX_ISIZE) amount else 0;
if (USE_ATOMICS) { switch(RC_TYPE) {
var last = @atomicRmw(isize, ptr_to_refcount, std.builtin.AtomicRmwOp.Add, masked_amount, std.builtin.AtomicOrder.Monotonic); Refcount.normal => {
} else { ptr_to_refcount.* = refcount + masked_amount;
ptr_to_refcount.* = refcount + masked_amount; },
Refcount.atomic => {
var last = @atomicRmw(isize, ptr_to_refcount, std.builtin.AtomicRmwOp.Add, masked_amount, std.builtin.AtomicOrder.Monotonic);
},
else => unreachable,
} }
} }
@ -175,20 +186,25 @@ inline fn decref_ptr_to_refcount(
refcount_ptr: [*]isize, refcount_ptr: [*]isize,
alignment: u32, alignment: u32,
) void { ) void {
if (RC_TYPE == Refcount.none) return;
const extra_bytes = std.math.max(alignment, @sizeOf(usize)); const extra_bytes = std.math.max(alignment, @sizeOf(usize));
if (USE_ATOMICS) { switch(RC_TYPE) {
var amount: isize = if (refcount_ptr[0] < REFCOUNT_MAX_ISIZE) 1 else 0; Refcount.normal => {
var last = @atomicRmw(isize, &refcount_ptr[0], std.builtin.AtomicRmwOp.Sub, amount, std.builtin.AtomicOrder.Monotonic); const refcount: isize = refcount_ptr[0];
if (last == REFCOUNT_ONE_ISIZE) { if (refcount == REFCOUNT_ONE_ISIZE) {
dealloc(@ptrCast([*]u8, refcount_ptr) - (extra_bytes - @sizeOf(usize)), alignment); dealloc(@ptrCast([*]u8, refcount_ptr) - (extra_bytes - @sizeOf(usize)), alignment);
} } else if (refcount < REFCOUNT_MAX_ISIZE) {
} else { refcount_ptr[0] = refcount - 1;
const refcount: isize = refcount_ptr[0]; }
if (refcount == REFCOUNT_ONE_ISIZE) { },
dealloc(@ptrCast([*]u8, refcount_ptr) - (extra_bytes - @sizeOf(usize)), alignment); Refcount.atomic => {
} else if (refcount < REFCOUNT_MAX_ISIZE) { var amount: isize = if (refcount_ptr[0] < REFCOUNT_MAX_ISIZE) 1 else 0;
refcount_ptr[0] = refcount - 1; var last = @atomicRmw(isize, &refcount_ptr[0], std.builtin.AtomicRmwOp.Sub, amount, std.builtin.AtomicOrder.Monotonic);
} if (last == REFCOUNT_ONE_ISIZE) {
dealloc(@ptrCast([*]u8, refcount_ptr) - (extra_bytes - @sizeOf(usize)), alignment);
}
},
else => unreachable,
} }
} }
@ -207,7 +223,7 @@ pub fn allocateWithRefcount(
var as_usize_array = @ptrCast([*]usize, new_bytes); var as_usize_array = @ptrCast([*]usize, new_bytes);
as_usize_array[0] = 0; as_usize_array[0] = 0;
as_usize_array[1] = REFCOUNT_ONE; as_usize_array[1] = if (RC_TYPE == Refcount.none) REFCOUNT_MAX_ISIZE else REFCOUNT_ONE;
var as_u8_array = @ptrCast([*]u8, new_bytes); var as_u8_array = @ptrCast([*]u8, new_bytes);
const first_slot = as_u8_array + first_slot_offset; const first_slot = as_u8_array + first_slot_offset;
@ -220,7 +236,7 @@ pub fn allocateWithRefcount(
var new_bytes: [*]align(8) u8 = @alignCast(8, raw); var new_bytes: [*]align(8) u8 = @alignCast(8, raw);
var as_isize_array = @ptrCast([*]isize, new_bytes); var as_isize_array = @ptrCast([*]isize, new_bytes);
as_isize_array[0] = REFCOUNT_ONE_ISIZE; as_isize_array[0] = if (RC_TYPE == Refcount.none) REFCOUNT_MAX_ISIZE else REFCOUNT_ONE_ISIZE;
var as_u8_array = @ptrCast([*]u8, new_bytes); var as_u8_array = @ptrCast([*]u8, new_bytes);
const first_slot = as_u8_array + first_slot_offset; const first_slot = as_u8_array + first_slot_offset;
@ -233,7 +249,7 @@ pub fn allocateWithRefcount(
var new_bytes: [*]align(@alignOf(isize)) u8 = @alignCast(@alignOf(isize), raw); var new_bytes: [*]align(@alignOf(isize)) u8 = @alignCast(@alignOf(isize), raw);
var as_isize_array = @ptrCast([*]isize, new_bytes); var as_isize_array = @ptrCast([*]isize, new_bytes);
as_isize_array[0] = REFCOUNT_ONE_ISIZE; as_isize_array[0] = if (RC_TYPE == Refcount.none) REFCOUNT_MAX_ISIZE else REFCOUNT_ONE_ISIZE;
var as_u8_array = @ptrCast([*]u8, new_bytes); var as_u8_array = @ptrCast([*]u8, new_bytes);
const first_slot = as_u8_array + first_slot_offset; const first_slot = as_u8_array + first_slot_offset;