Perform an atomic fence which uses the atomic value as a hint for the modification order. Use this when you want to imply a fence on an atomic variable without necessarily performing a memory access.
Example:
const RefCount = struct {
count: Atomic(usize),
dropFn: *const fn(*RefCount) void,
fn ref(self: *RefCount) void {
_ = self.count.fetchAdd(1, .Monotonic); // no ordering necessary, just updating a counter
}
fn unref(self: *RefCount) void {
// Release ensures code before unref() happens-before the count is decremented as dropFn could be called by then.
if (self.count.fetchSub(1, .Release)) {
// Acquire ensures count decrement and code before previous unrefs()s happens-before we call dropFn below.
// NOTE: another alternative is to use .AcqRel on the fetchSub count decrement but it's extra barrier in possibly hot path.
self.count.fence(.Acquire);
(self.dropFn)(self);
}
}
};