Skip to content

Commit b529310

Browse files
committed
event: ensure acquire release semantics for muxnote disposal
While it is sufficient to use the relaxed ordering for the acquire semantics in the `_dispatch_muxnote_retain`, we need to use the acquire release semantics on the release in `_dispatch_muxnote_release` to ensure that any pending retains are not interrupted. This should hopefully alleviate the occasional crashes that have been observed with the muxnote reference counting. Fixes: #887, #844
1 parent d58b86d commit b529310

File tree

1 file changed

+9
-1
lines changed

1 file changed

+9
-1
lines changed

src/event/event_windows.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,8 +260,16 @@ _dispatch_muxnote_retain(dispatch_muxnote_t dmn)
260260
static void
261261
_dispatch_muxnote_release(dispatch_muxnote_t dmn)
262262
{
263-
uintptr_t refcount = os_atomic_dec(&dmn->dmn_refcount, relaxed);
263+
// We perform a minor optimization here - perform the decrement with
264+
// release semantics. In the case that we are going to dispose of the
265+
// value, we perform the acquire fence. This reduces the cost on the
266+
// normal path by avoiding the acquire fence. This should be more
267+
// beneficial on ARM64, as X64 being TSO'ed doesn't gain much. However,
268+
// `mfence` being isolated should hopefully be a bit more efficient than
269+
// the repeated `lock` if there is contention.
270+
uintptr_t refcount = os_atomic_dec(&dmn->dmn_refcount, release);
264271
if (refcount == 0) {
272+
os_atomic_thread_fence(acquire);
265273
_dispatch_muxnote_dispose(dmn);
266274
} else if (refcount == UINTPTR_MAX) {
267275
DISPATCH_INTERNAL_CRASH(0, "muxnote refcount underflow");

0 commit comments

Comments
 (0)