Zig 0.17.0-dev (Split by item)

This is an example of documentation generated by ZigDoc, an alternative to Zig's built-in Auto Doc feature. See also examples in other modes/formats. The project being documented here (as the example) is the Zig library itself.

wideUpdate

atomics.wideUpdate
fn wideUpdate(comptime T: type, ptr: *T, val: T, update: anytype) T

File

lib/compiler_rt/atomics.zig:228

Code

fn wideUpdate(comptime T: type, ptr: *T, val: T, update: anytype) T {
    const WideAtomic = @Int(.unsigned, smallest_atomic_fetch_exch_size * 8);

    const addr = @intFromPtr(ptr);
    const wide_addr = addr & ~(@as(T, smallest_atomic_fetch_exch_size) - 1);
    const wide_ptr: *align(smallest_atomic_fetch_exch_size) WideAtomic = @alignCast(@as(*WideAtomic, @ptrFromInt(wide_addr)));

    const inner_offset = addr & (@as(T, smallest_atomic_fetch_exch_size) - 1);
    const inner_shift = @as(std.math.Log2Int(T), @intCast(inner_offset * 8));

    const mask = @as(WideAtomic, std.math.maxInt(T)) << inner_shift;

    var wide_old = @atomicLoad(WideAtomic, wide_ptr, .seq_cst);
    while (true) {
        const old = @as(T, @truncate((wide_old & mask) >> inner_shift));
        const new = update(val, old);
        const wide_new = wide_old & ~mask | (@as(WideAtomic, new) << inner_shift);
        if (@cmpxchgWeak(WideAtomic, wide_ptr, wide_old, wide_new, .seq_cst, .seq_cst)) |new_wide_old| {
            wide_old = new_wide_old;
        } else {
            return old;
        }
    }
}