From df5f1407eb831c41a94ea623d01a75bf13ccfa67 Mon Sep 17 00:00:00 2001 From: Taylor R Campbell Date: Fri, 11 Feb 2022 21:03:08 +0000 Subject: [PATCH 12/49] Introduce membar_acquire/release. Deprecate membar_enter/exit. The names membar_enter/exit were unclear, and the documentation of membar_enter has disagreed with the implementations on sparc, powerpc, and even x86(!) for the entire time it has been in NetBSD. The terms `acquire' and `release' are ubiquitous in the literature today, and have been adopted in the C and C++ standards to mean load-before-load/store and load/store-before-store, respectively, which are exactly the orderings required by acquiring and releasing a mutex, as well as other useful applications like decrementing a reference count and then freeing the underlying object if it went to zero. Originally I proposed changing one word in the documentation for membar_enter to make it load-before-load/store instead of store-before-load/store, i.e., to make it an acquire barrier. I proposed this on the grounds that (a) all implementations guarantee load-before-load/store, (b) some implementations fail to guarantee store-before-load/store, and (c) all uses in-tree assume load-before-load/store. I verified parts (a) and (b) (except, for (a), powerpc didn't even guarantee load-before-load/store -- isync isn't necessarily enough; need lwsync in general -- but it _almost_ did, and it certainly didn't guarantee store-before-load/store). Part (c) might not be correct, however: under the mistaken assumption that atomic-r/m/w then membar-w/rw is equivalent to atomic-r/m/w then membar-r/rw, I only audited the cases of membar_enter that _aren't_ immediately after an atomic-r/m/w. All of those cases assume load-before-load/store. But my assumption was wrong -- there are cases of atomic-r/m/w then membar-w/rw that would be broken by changing to atomic-r/m/w then membar-r/rw: https://mail-index.netbsd.org/tech-kern/2022/03/29/msg028044.html Furthermore, the name membar_enter has been adopted in other places like OpenBSD where it actually does follow the documentation and guarantee store-before-load/store, even if that order is not useful. So the name membar_enter currently lives in a bad place where it means either of two things -- r/rw or w/rw. With this change, we deprecate membar_enter/exit, introduce membar_acquire/release as better names for the useful pair (r/rw and rw/w), and make sure the implementation of membar_enter guarantees both what was documented _and_ what was implemented, making it an alias for membar_sync. While here, rework all of the membar_* definitions and aliases. The new logic follows a rule to make it easier to audit: membar_X is defined as an alias for membar_Y iff membar_X is no stronger than membar_Y. The `no stronger than' relation is (the transitive closure of): - membar_consumer (r/r) is no stronger than membar_acquire (r/rw) - membar_producer (w/w) is no stronger than membar_release (rw/w) - membar_acquire (r/rw) is no stronger than membar_sync (rw/rw) - membar_release (rw/w) is no stronger than membar_sync (rw/rw) And, for the deprecated membars: - membar_enter (w/rw) is no stronger than membar_sync (rw/rw) - membar_exit (rw/w) is no stronger than membar_release (rw/w) (membar_exit is identical to membar_release, but the name is deprecated.) Finally, while here, annotate some of the instructions with their semantics. For powerpc, leave an essay with citations on the unfortunate but -- as far as I can tell -- necessary decision to use lwsync, not isync, for membar_acquire and membar_consumer. Also add membar(3) and atomic(3) man page links. --- .../lib/libc/arch/aarch64/atomic/membar_ops.S | 14 +- .../lib/libc/arch/alpha/atomic/membar_ops.S | 25 ++-- common/lib/libc/arch/arm/atomic/membar_ops.S | 8 +- common/lib/libc/arch/hppa/atomic/membar_ops.S | 36 ++--- common/lib/libc/arch/i386/atomic/atomic.S | 22 +-- common/lib/libc/arch/ia64/atomic/atomic.S | 12 ++ common/lib/libc/arch/mips/atomic/membar_ops.S | 28 +++- common/lib/libc/arch/or1k/atomic/membar_ops.S | 17 ++- .../lib/libc/arch/powerpc/atomic/membar_ops.S | 115 +++++++++++++-- .../lib/libc/arch/riscv/atomic/membar_ops.S | 12 ++ .../lib/libc/arch/sparc/atomic/membar_ops.S | 26 ++-- .../lib/libc/arch/sparc64/atomic/membar_ops.S | 24 ++-- common/lib/libc/arch/x86_64/atomic/atomic.S | 22 +-- common/lib/libc/atomic/membar_ops_nop.c | 6 + distrib/sets/lists/comp/mi | 12 ++ lib/libc/atomic/Makefile.inc | 4 + lib/libc/atomic/membar_ops.3 | 135 ++++++++++-------- share/man/man9/atomic_loadstore.9 | 34 ++--- sys/sys/atomic.h | 10 +- tests/lib/libc/membar/t_dekker.c | 4 - tests/lib/libc/membar/t_spinlock.c | 4 - 21 files changed, 387 insertions(+), 183 deletions(-) diff --git a/common/lib/libc/arch/aarch64/atomic/membar_ops.S b/common/lib/libc/arch/aarch64/atomic/membar_ops.S index 8b9009dcc39f..1cac3fa47fd2 100644 --- a/common/lib/libc/arch/aarch64/atomic/membar_ops.S +++ b/common/lib/libc/arch/aarch64/atomic/membar_ops.S @@ -32,19 +32,21 @@ #include "atomic_op_asm.h" ENTRY_NP(_membar_producer) - dmb ishst + dmb ishst /* store-before-store */ ret END(_membar_producer) ATOMIC_OP_ALIAS(membar_producer,_membar_producer) ATOMIC_OP_ALIAS(membar_write,_membar_producer) STRONG_ALIAS(_membar_write,_membar_producer) -ENTRY_NP(_membar_consumer) - dmb ishld +ENTRY_NP(_membar_acquire) + dmb ishld /* load-before-load/store */ ret -END(_membar_consumer) -ATOMIC_OP_ALIAS(membar_consumer,_membar_consumer) +END(_membar_acquire) +ATOMIC_OP_ALIAS(membar_acquire,_membar_acquire) +ATOMIC_OP_ALIAS(membar_consumer,_membar_acquire) ATOMIC_OP_ALIAS(membar_read,_membar_consumer) +STRONG_ALIAS(_membar_consumer,_membar_acquire) STRONG_ALIAS(_membar_read,_membar_consumer) ENTRY_NP(_membar_sync) @@ -52,8 +54,10 @@ ENTRY_NP(_membar_sync) ret END(_membar_sync) ATOMIC_OP_ALIAS(membar_sync,_membar_sync) +ATOMIC_OP_ALIAS(membar_release,_membar_sync) ATOMIC_OP_ALIAS(membar_enter,_membar_sync) ATOMIC_OP_ALIAS(membar_exit,_membar_sync) STRONG_ALIAS(__sync_synchronize,_membar_sync) +STRONG_ALIAS(_membar_release,_membar_sync) STRONG_ALIAS(_membar_enter,_membar_sync) STRONG_ALIAS(_membar_exit,_membar_sync) diff --git a/common/lib/libc/arch/alpha/atomic/membar_ops.S b/common/lib/libc/arch/alpha/atomic/membar_ops.S index 7ec1b011bfb4..5a1b0bb4f343 100644 --- a/common/lib/libc/arch/alpha/atomic/membar_ops.S +++ b/common/lib/libc/arch/alpha/atomic/membar_ops.S @@ -42,45 +42,50 @@ LEAF(_membar_producer, 0) RET nop - END(_membar_producer) +END(_membar_producer) EXPORT(_membar_producer_end) LEAF(_membar_sync, 0) RET nop - END(_membar_sync) +END(_membar_sync) EXPORT(_membar_sync_end) LEAF(_membar_producer_mp, 0) - wmb + wmb /* store-before-store */ RET - END(_membar_producer_mp) +END(_membar_producer_mp) EXPORT(_membar_producer_mp_end) LEAF(_membar_sync_mp, 0) - mb + mb /* load/store-before-load/store */ RET - END(_membar_sync_mp) +END(_membar_sync_mp) EXPORT(_membar_sync_mp_end) #else /* _KERNEL */ LEAF(_membar_producer, 0) - mb + mb /* load/store-before-load/store */ RET - END(_membar_producer) +END(_membar_producer) EXPORT(_membar_producer_end) LEAF(_membar_sync, 0) - mb + mb /* load/store-before-load/store */ RET - END(_membar_sync) +END(_membar_sync) EXPORT(_membar_sync_end) #endif /* _KERNEL */ ATOMIC_OP_ALIAS(membar_producer,_membar_producer) ATOMIC_OP_ALIAS(membar_sync,_membar_sync) + +ATOMIC_OP_ALIAS(membar_acquire,_membar_sync) +STRONG_ALIAS(_membar_acquire,_membar_sync) +ATOMIC_OP_ALIAS(membar_release,_membar_sync) +STRONG_ALIAS(_membar_release,_membar_sync) ATOMIC_OP_ALIAS(membar_enter,_membar_sync) STRONG_ALIAS(_membar_enter,_membar_sync) ATOMIC_OP_ALIAS(membar_exit,_membar_sync) diff --git a/common/lib/libc/arch/arm/atomic/membar_ops.S b/common/lib/libc/arch/arm/atomic/membar_ops.S index 08efd74d38fc..710eee16558e 100644 --- a/common/lib/libc/arch/arm/atomic/membar_ops.S +++ b/common/lib/libc/arch/arm/atomic/membar_ops.S @@ -33,7 +33,7 @@ #if defined(_ARM_ARCH_6) ENTRY_NP(_membar_producer) - DMBST + DMBST /* store-before-store */ RET END(_membar_producer) ATOMIC_OP_ALIAS(membar_producer,_membar_producer) @@ -41,15 +41,19 @@ ATOMIC_OP_ALIAS(membar_write,_membar_producer) STRONG_ALIAS(_membar_write,_membar_producer) ENTRY_NP(_membar_sync) - DMB + DMB /* load/store-before-load/store */ RET END(_membar_sync) ATOMIC_OP_ALIAS(membar_sync,_membar_sync) +ATOMIC_OP_ALIAS(membar_acquire,_membar_sync) +ATOMIC_OP_ALIAS(membar_release,_membar_sync) ATOMIC_OP_ALIAS(membar_enter,_membar_sync) ATOMIC_OP_ALIAS(membar_exit,_membar_sync) ATOMIC_OP_ALIAS(membar_consumer,_membar_sync) ATOMIC_OP_ALIAS(membar_read,_membar_sync) STRONG_ALIAS(__sync_synchronize,_membar_sync) +STRONG_ALIAS(_membar_acquire,_membar_sync) +STRONG_ALIAS(_membar_release,_membar_sync) STRONG_ALIAS(_membar_enter,_membar_sync) STRONG_ALIAS(_membar_exit,_membar_sync) STRONG_ALIAS(_membar_consumer,_membar_sync) diff --git a/common/lib/libc/arch/hppa/atomic/membar_ops.S b/common/lib/libc/arch/hppa/atomic/membar_ops.S index a8b5414478c7..a55dad7d5012 100644 --- a/common/lib/libc/arch/hppa/atomic/membar_ops.S +++ b/common/lib/libc/arch/hppa/atomic/membar_ops.S @@ -35,7 +35,7 @@ RCSID("$NetBSD: membar_ops.S,v 1.1 2011/01/17 07:40:21 skrll Exp $") .text -LEAF_ENTRY(_membar_consumer) +LEAF_ENTRY(_membar_sync) sync nop nop @@ -44,24 +44,18 @@ LEAF_ENTRY(_membar_consumer) nop bv %r0(%rp) nop -EXIT(_membar_consumer) +EXIT(_membar_sync) +ATOMIC_OP_ALIAS(membar_sync,_membar_sync) -LEAF_ENTRY(_membar_producer) - sync - nop - nop - nop - nop - nop - bv %r0(%rp) - nop -EXIT(_membar_producer) - -ATOMIC_OP_ALIAS(membar_producer,_membar_producer) -ATOMIC_OP_ALIAS(membar_consumer,_membar_consumer) -ATOMIC_OP_ALIAS(membar_enter,_membar_consumer) -STRONG_ALIAS(_membar_enter,_membar_consumer) -ATOMIC_OP_ALIAS(membar_exit,_membar_producer) -STRONG_ALIAS(_membar_exit,_membar_producer) -ATOMIC_OP_ALIAS(membar_sync,_membar_producer) -STRONG_ALIAS(_membar_sync,_membar_producer) +ATOMIC_OP_ALIAS(membar_producer,_membar_sync) +STRONG_ALIAS(_membar_producer,_membar_sync) +ATOMIC_OP_ALIAS(membar_consumer,_membar_sync) +STRONG_ALIAS(_membar_consumer,_membar_sync) +ATOMIC_OP_ALIAS(membar_acquire,_membar_sync) +STRONG_ALIAS(_membar_acquire,_membar_sync) +ATOMIC_OP_ALIAS(membar_release,_membar_sync) +STRONG_ALIAS(_membar_release,_membar_sync) +ATOMIC_OP_ALIAS(membar_enter,_membar_sync) +STRONG_ALIAS(_membar_enter,_membar_sync) +ATOMIC_OP_ALIAS(membar_exit,_membar_sync) +STRONG_ALIAS(_membar_exit,_membar_sync) diff --git a/common/lib/libc/arch/i386/atomic/atomic.S b/common/lib/libc/arch/i386/atomic/atomic.S index 2fad744d36c3..d363f53f5118 100644 --- a/common/lib/libc/arch/i386/atomic/atomic.S +++ b/common/lib/libc/arch/i386/atomic/atomic.S @@ -178,23 +178,23 @@ ENTRY(_atomic_cas_32_ni) ret END(_atomic_cas_32_ni) -ENTRY(_membar_consumer) +ENTRY(_membar_acquire) /* * Every load from normal memory is a load-acquire on x86, so * there is never any need for explicit barriers to order * load-before-anything. */ ret -END(_membar_consumer) +END(_membar_acquire) -ENTRY(_membar_producer) +ENTRY(_membar_release) /* * Every store to normal memory is a store-release on x86, so * there is never any need for explicit barriers to order * anything-before-store. */ ret -END(_membar_producer) +END(_membar_release) ENTRY(_membar_sync) /* @@ -340,10 +340,14 @@ ALIAS(atomic_cas_64_ni,_atomic_cas_64) ALIAS(__sync_val_compare_and_swap_8,_atomic_cas_64) #endif /* __HAVE_ATOMIC64_OPS || _KERNEL */ -ALIAS(membar_consumer,_membar_consumer) -ALIAS(membar_producer,_membar_producer) +ALIAS(membar_acquire,_membar_acquire) +ALIAS(membar_release,_membar_release) +ALIAS(membar_sync,_membar_sync) + +ALIAS(membar_consumer,_membar_acquire) +ALIAS(membar_producer,_membar_release) ALIAS(membar_enter,_membar_sync) -ALIAS(membar_exit,_membar_producer) +ALIAS(membar_exit,_membar_release) ALIAS(membar_sync,_membar_sync) STRONG_ALIAS(_atomic_add_int,_atomic_add_32) @@ -398,8 +402,10 @@ STRONG_ALIAS(_atomic_cas_uint_ni,_atomic_cas_32_ni) STRONG_ALIAS(_atomic_cas_ulong_ni,_atomic_cas_32_ni) STRONG_ALIAS(_atomic_cas_ptr_ni,_atomic_cas_32_ni) +STRONG_ALIAS(_membar_consumer,_membar_acquire) +STRONG_ALIAS(_membar_producer,_membar_release) STRONG_ALIAS(_membar_enter,_membar_sync) -STRONG_ALIAS(_membar_exit,_membar_producer) +STRONG_ALIAS(_membar_exit,_membar_release) #ifdef _HARDKERNEL .section .rodata diff --git a/common/lib/libc/arch/ia64/atomic/atomic.S b/common/lib/libc/arch/ia64/atomic/atomic.S index 9c4d78b13c6a..9872b666d0b8 100644 --- a/common/lib/libc/arch/ia64/atomic/atomic.S +++ b/common/lib/libc/arch/ia64/atomic/atomic.S @@ -117,6 +117,16 @@ ENTRY(_membar_producer,0) br.ret.sptk rp END(_membar_producer) +ENTRY(_membar_acquire,0) + mf + br.ret.sptk rp +END(_membar_acquire) + +ENTRY(_membar_release,0) + mf + br.ret.sptk rp +END(_membar_release) + ENTRY(_membar_enter,0) mf br.ret.sptk rp @@ -213,6 +223,8 @@ ALIAS(atomic_cas_ptr_ni,_atomic_cas_64) ALIAS(membar_consumer,_membar_consumer) ALIAS(membar_producer,_membar_producer) +ALIAS(membar_acquire,_membar_acquire) +ALIAS(membar_release,_membar_release) ALIAS(membar_enter,_membar_enter) ALIAS(membar_exit,_membar_exit) ALIAS(membar_sync,_membar_sync) diff --git a/common/lib/libc/arch/mips/atomic/membar_ops.S b/common/lib/libc/arch/mips/atomic/membar_ops.S index 950536856082..dae62c17d1d6 100644 --- a/common/lib/libc/arch/mips/atomic/membar_ops.S +++ b/common/lib/libc/arch/mips/atomic/membar_ops.S @@ -40,22 +40,40 @@ LEAF(_membar_sync) END(_membar_sync) #ifdef __OCTEON__ -LEAF(_membar_producer) +LEAF(_membar_release) + /* + * syncw is documented as ordering store-before-store in + * + * Cavium OCTEON III CN78XX Hardware Reference Manual, + * CN78XX-HM-0.99E, September 2014. + * + * It's unclear from the documentation the architecture + * guarantees load-before-store ordering without barriers, but + * this code assumes it does. If that assumption is wrong, we + * can only use syncw for membar_producer -- membar_release has + * to use the full sync. + */ j ra syncw -END(_membar_producer) +END(_membar_release) #endif ATOMIC_OP_ALIAS(membar_sync,_membar_sync) +ATOMIC_OP_ALIAS(membar_acquire,_membar_sync) +STRONG_ALIAS(_membar_acquire,_membar_sync) ATOMIC_OP_ALIAS(membar_enter,_membar_sync) STRONG_ALIAS(_membar_enter,_membar_sync) #ifdef __OCTEON__ -ATOMIC_OP_ALIAS(membar_exit,_membar_producer) -STRONG_ALIAS(_membar_exit,_membar_producer) -STRONG_ALIAS(membar_producer,_membar_producer) +ATOMIC_OP_ALIAS(membar_exit,_membar_release) +STRONG_ALIAS(_membar_exit,_membar_release) +ATOMIC_OP_ALIAS(membar_release,_membar_release) +ATOMIC_OP_ALIAS(membar_producer,_membar_release) +STRONG_ALIAS(_membar_producer,_membar_release) #else ATOMIC_OP_ALIAS(membar_exit,_membar_sync) STRONG_ALIAS(_membar_exit,_membar_sync) +ATOMIC_OP_ALIAS(membar_release,_membar_sync) +STRONG_ALIAS(_membar_release,_membar_sync) ATOMIC_OP_ALIAS(membar_producer,_membar_sync) STRONG_ALIAS(_membar_producer,_membar_sync) #endif diff --git a/common/lib/libc/arch/or1k/atomic/membar_ops.S b/common/lib/libc/arch/or1k/atomic/membar_ops.S index 3ce1b187005a..3bd07573b14c 100644 --- a/common/lib/libc/arch/or1k/atomic/membar_ops.S +++ b/common/lib/libc/arch/or1k/atomic/membar_ops.S @@ -31,27 +31,26 @@ #include "atomic_op_asm.h" -ENTRY_NP(_membar_producer) - l.msync - l.jr lr - l.nop -END(_membar_producer) -ATOMIC_OP_ALIAS(membar_producer,_membar_producer) -ATOMIC_OP_ALIAS(membar_write,_membar_producer) -STRONG_ALIAS(_membar_write,_membar_producer) - ENTRY_NP(_membar_sync) l.msync l.jr lr l.nop END(_membar_sync) ATOMIC_OP_ALIAS(membar_sync,_membar_sync) +ATOMIC_OP_ALIAS(membar_acquire,_membar_sync) +ATOMIC_OP_ALIAS(membar_release,_membar_sync) ATOMIC_OP_ALIAS(membar_enter,_membar_sync) ATOMIC_OP_ALIAS(membar_exit,_membar_sync) ATOMIC_OP_ALIAS(membar_consumer,_membar_sync) ATOMIC_OP_ALIAS(membar_read,_membar_sync) +ATOMIC_OP_ALIAS(membar_producer,_membar_sync) +ATOMIC_OP_ALIAS(membar_write,_membar_sync) CRT_ALIAS(__sync_synchronize,_membar_sync) +STRONG_ALIAS(_membar_acquire,_membar_sync) +STRONG_ALIAS(_membar_release,_membar_sync) STRONG_ALIAS(_membar_enter,_membar_sync) STRONG_ALIAS(_membar_exit,_membar_sync) STRONG_ALIAS(_membar_consumer,_membar_sync) STRONG_ALIAS(_membar_read,_membar_sync) +STRONG_ALIAS(_membar_producer,_membar_sync) +STRONG_ALIAS(_membar_write,_membar_sync) diff --git a/common/lib/libc/arch/powerpc/atomic/membar_ops.S b/common/lib/libc/arch/powerpc/atomic/membar_ops.S index 387c887a3340..d254e7dc2d37 100644 --- a/common/lib/libc/arch/powerpc/atomic/membar_ops.S +++ b/common/lib/libc/arch/powerpc/atomic/membar_ops.S @@ -34,23 +34,108 @@ __RCSID("$NetBSD: membar_ops.S,v 1.4 2011/01/15 07:31:11 matt Exp $") .text -/* These assume Total Store Order (TSO) */ -ENTRY(_membar_consumer) - isync +ENTRY(_membar_acquire) + /* + * It is tempting to use isync to order load-before-load/store. + * However, isync orders prior loads only if their value flows + * into a control-flow dependency prior to the isync: + * + * `[I]f an isync follows a conditional Branch instruction + * that depends on the value returned by a preceding Load + * instruction, the load on which the Branch depends is + * performed before any loads caused by instructions + * following the isync. This applies even if the effects + * of the ``dependency'' are independent of the value + * loaded (e.g., the value is compared to itself and the + * Branch tests the EQ bit in the selected CR field), and + * even if the branch target is the sequentially next + * instruction.' + * + * --PowerPC Virtual Environment Architecture, Book II, + * Version 2.01, December 2003, 1.7.1 `Storage Access + * Ordering', p. 7. + * + * We are required here, however, to order _all_ prior loads, + * even if they do not flow into any control flow dependency. + * For example: + * + * x = *p; + * membar_acquire(); + * if (x) goto foo; + * + * This can't be implemented by: + * + * lwz x, p + * isync + * cmpwi x, 0 + * bne foo + * + * isync doesn't work here because there's no conditional + * dependency on x between the lwz x, p and the isync. + * + * isync would only work if it followed the branch: + * + * lwz x, p + * isync + * cmpwi x, 0 + * bne foo + * ... + * foo: isync + * ... + * + * lwsync orders everything except store-before-load, so it + * serves here -- see below in membar_release in lwsync. + * Except we can't use it on booke, so use sync for now. + */ + sync blr -END(_membar_consumer) +END(_membar_acquire) +ATOMIC_OP_ALIAS(membar_acquire,_membar_acquire) -ENTRY(_membar_producer) +ENTRY(_membar_release) + /* + * `The memory barrier provides an ordering function for + * the storage accesses caused by Load, Store, and dcbz + * instructions that are executed by the processor + * executing the [lwsync] instruction and for which the + * specified storage location is in storage that is + * Memory Coherence Required and is neither Write Through + * Required nor Caching Inhibited. The applicable pairs + * are all pairs a_i, b_j of such accesses except those + * in which a_i is an access caused by a Store or dcbz + * instruction and b_j is an access caused by a Load + * instruction.' + * + * --PowerPC Virtual Environment Architecture, Book II, + * Version 2.01, December 2003, 3.3.3 `Memory Barrier + * Instructions', p. 25. + * + * In brief, lwsync is an acquire-release barrier -- it orders + * load-before-load/store and load/store-before-store, but not + * store-before-load. Except we can't use it on booke, so use + * sync for now. + */ sync blr -END(_membar_producer) - -ATOMIC_OP_ALIAS(membar_producer,_membar_producer) -ATOMIC_OP_ALIAS(membar_consumer,_membar_consumer) -ATOMIC_OP_ALIAS(membar_enter,_membar_consumer) -STRONG_ALIAS(_membar_enter,_membar_consumer) -ATOMIC_OP_ALIAS(membar_exit,_membar_producer) -STRONG_ALIAS(_membar_exit,_membar_producer) -ATOMIC_OP_ALIAS(membar_sync,_membar_producer) -STRONG_ALIAS(_membar_sync,_membar_producer) +END(_membar_release) +ATOMIC_OP_ALIAS(membar_release,_membar_release) + +ENTRY(_membar_sync) + /* + * sync, or `heavyweight sync', is a full sequential + * consistency barrier. + */ + sync + blr +END(_membar_sync) +ATOMIC_OP_ALIAS(membar_sync,_membar_sync) + +ATOMIC_OP_ALIAS(membar_producer,_membar_release) +STRONG_ALIAS(_membar_producer,_membar_release) +ATOMIC_OP_ALIAS(membar_consumer,_membar_acquire) +STRONG_ALIAS(_membar_consumer,_membar_acquire) +ATOMIC_OP_ALIAS(membar_enter,_membar_sync) +STRONG_ALIAS(_membar_enter,_membar_sync) +ATOMIC_OP_ALIAS(membar_exit,_membar_release) +STRONG_ALIAS(_membar_exit,_membar_release) diff --git a/common/lib/libc/arch/riscv/atomic/membar_ops.S b/common/lib/libc/arch/riscv/atomic/membar_ops.S index 20aa64af3449..43cb54a98556 100644 --- a/common/lib/libc/arch/riscv/atomic/membar_ops.S +++ b/common/lib/libc/arch/riscv/atomic/membar_ops.S @@ -38,6 +38,18 @@ END(_membar_sync) ATOMIC_OP_ALIAS(membar_sync,_membar_sync) CRT_ALIAS(__sync_synchronize,_membar_sync) +ENTRY_NP(_membar_acquire) + fence r,rw + ret +END(_membar_acquire) +ATOMIC_OP_ALIAS(membar_acquire,_membar_acquire) + +ENTRY_NP(_membar_release) + fence rw,w + ret +END(_membar_release) +ATOMIC_OP_ALIAS(membar_release,_membar_release) + ENTRY_NP(_membar_enter) fence rw,rw ret diff --git a/common/lib/libc/arch/sparc/atomic/membar_ops.S b/common/lib/libc/arch/sparc/atomic/membar_ops.S index a1c780bf1089..780cde6ba905 100644 --- a/common/lib/libc/arch/sparc/atomic/membar_ops.S +++ b/common/lib/libc/arch/sparc/atomic/membar_ops.S @@ -45,14 +45,21 @@ * instruction that implies a sequential consistency barrier. * * If we ran with Partial Store Order (PSO), we would also need to - * issue STBAR for membar_exit (load/store-before-store) and + * issue STBAR for membar_release (load/store-before-store) and * membar_producer (store-before-store). */ -ENTRY(_membar_consumer) +ENTRY(_membar_acquire) retl nop -END(_membar_consumer) +END(_membar_acquire) +ATOMIC_OP_ALIAS(membar_acquire,_membar_acquire) + +ENTRY(_membar_release) + retl + nop +END(_membar_release) +ATOMIC_OP_ALIAS(membar_release,_membar_release) ENTRY(_membar_sync) retl @@ -62,12 +69,13 @@ ENTRY(_membar_sync) nop #endif END(_membar_sync) +ATOMIC_OP_ALIAS(membar_sync,_membar_sync) -ATOMIC_OP_ALIAS(membar_producer,_membar_consumer) -STRONG_ALIAS(_membar_producer,_membar_consumer) -ATOMIC_OP_ALIAS(membar_consumer,_membar_consumer) +ATOMIC_OP_ALIAS(membar_producer,_membar_release) +STRONG_ALIAS(_membar_producer,_membar_release) +ATOMIC_OP_ALIAS(membar_consumer,_membar_acquire) +STRONG_ALIAS(_membar_consumer,_membar_acquire) ATOMIC_OP_ALIAS(membar_enter,_membar_sync) STRONG_ALIAS(_membar_enter,_membar_sync) -ATOMIC_OP_ALIAS(membar_exit,_membar_consumer) -STRONG_ALIAS(_membar_exit,_membar_consumer) -ATOMIC_OP_ALIAS(membar_sync,_membar_sync) +ATOMIC_OP_ALIAS(membar_exit,_membar_release) +STRONG_ALIAS(_membar_exit,_membar_release) diff --git a/common/lib/libc/arch/sparc64/atomic/membar_ops.S b/common/lib/libc/arch/sparc64/atomic/membar_ops.S index 4f26b9e2d0bc..23b74c82f15b 100644 --- a/common/lib/libc/arch/sparc64/atomic/membar_ops.S +++ b/common/lib/libc/arch/sparc64/atomic/membar_ops.S @@ -44,10 +44,17 @@ * and membar_producer (store-before-store). */ -ENTRY(_membar_consumer) +ENTRY(_membar_acquire) retl nop -END(_membar_consumer) +END(_membar_acquire) +ATOMIC_OP_ALIAS(membar_acquire,_membar_acquire) + +ENTRY(_membar_release) + retl + nop +END(_membar_release) +ATOMIC_OP_ALIAS(membar_release,_membar_release) ENTRY(_membar_sync) /* @@ -70,12 +77,13 @@ ENTRY(_membar_sync) retl nop END(_membar_sync) +ATOMIC_OP_ALIAS(membar_sync,_membar_sync) -ATOMIC_OP_ALIAS(membar_producer,_membar_consumer) -STRONG_ALIAS(_membar_producer,_membar_consumer) -ATOMIC_OP_ALIAS(membar_consumer,_membar_consumer) +ATOMIC_OP_ALIAS(membar_producer,_membar_release) +STRONG_ALIAS(_membar_producer,_membar_release) +ATOMIC_OP_ALIAS(membar_consumer,_membar_acquire) +STRONG_ALIAS(_membar_consumer,_membar_acquire) ATOMIC_OP_ALIAS(membar_enter,_membar_sync) STRONG_ALIAS(_membar_enter,_membar_sync) -ATOMIC_OP_ALIAS(membar_exit,_membar_consumer) -STRONG_ALIAS(_membar_exit,_membar_consumer) -ATOMIC_OP_ALIAS(membar_sync,_membar_sync) +ATOMIC_OP_ALIAS(membar_exit,_membar_release) +STRONG_ALIAS(_membar_exit,_membar_release) diff --git a/common/lib/libc/arch/x86_64/atomic/atomic.S b/common/lib/libc/arch/x86_64/atomic/atomic.S index a76015b91874..58149dfda2f5 100644 --- a/common/lib/libc/arch/x86_64/atomic/atomic.S +++ b/common/lib/libc/arch/x86_64/atomic/atomic.S @@ -253,23 +253,23 @@ END(_atomic_cas_64_ni) /* memory barriers */ -ENTRY(_membar_consumer) +ENTRY(_membar_acquire) /* * Every load from normal memory is a load-acquire on x86, so * there is never any need for explicit barriers to order * load-before-anything. */ ret -END(_membar_consumer) +END(_membar_acquire) -ENTRY(_membar_producer) +ENTRY(_membar_release) /* * Every store to normal memory is a store-release on x86, so * there is never any need for explicit barriers to order * anything-before-store. */ ret -END(_membar_producer) +END(_membar_release) ENTRY(_membar_sync) /* @@ -363,10 +363,14 @@ ALIAS(atomic_cas_uint_ni,_atomic_cas_32_ni) ALIAS(atomic_cas_ulong_ni,_atomic_cas_64_ni) ALIAS(atomic_cas_ptr_ni,_atomic_cas_64_ni) -ALIAS(membar_consumer,_membar_consumer) -ALIAS(membar_producer,_membar_producer) +ALIAS(membar_acquire,_membar_acquire) +ALIAS(membar_release,_membar_release) +ALIAS(membar_sync,_membar_sync) + +ALIAS(membar_consumer,_membar_acquire) +ALIAS(membar_producer,_membar_release) ALIAS(membar_enter,_membar_sync) -ALIAS(membar_exit,_membar_producer) +ALIAS(membar_exit,_membar_release) ALIAS(membar_sync,_membar_sync) STRONG_ALIAS(_atomic_add_int,_atomic_add_32) @@ -421,8 +425,10 @@ STRONG_ALIAS(_atomic_cas_uint_ni,_atomic_cas_32_ni) STRONG_ALIAS(_atomic_cas_ulong_ni,_atomic_cas_64_ni) STRONG_ALIAS(_atomic_cas_ptr_ni,_atomic_cas_64_ni) +STRONG_ALIAS(_membar_consumer,_membar_acquire) +STRONG_ALIAS(_membar_producer,_membar_release) STRONG_ALIAS(_membar_enter,_membar_sync) -STRONG_ALIAS(_membar_exit,_membar_producer) +STRONG_ALIAS(_membar_exit,_membar_release) #ifdef _HARDKERNEL .section .rodata diff --git a/common/lib/libc/atomic/membar_ops_nop.c b/common/lib/libc/atomic/membar_ops_nop.c index 1d71089ed2b5..5c882c1315cc 100644 --- a/common/lib/libc/atomic/membar_ops_nop.c +++ b/common/lib/libc/atomic/membar_ops_nop.c @@ -40,6 +40,12 @@ membar_sync(void) /* nothing */ } +#undef membar_acquire +atomic_op_alias(membar_acquire,_membar_sync) +__strong_alias(_membar_acquire,_membar_sync) +#undef membar_release +atomic_op_alias(membar_release,_membar_sync) +__strong_alias(_membar_release,_membar_sync) #undef membar_enter atomic_op_alias(membar_enter,_membar_sync) __strong_alias(_membar_enter,_membar_sync) diff --git a/distrib/sets/lists/comp/mi b/distrib/sets/lists/comp/mi index a5e424fae75c..5dbacb400226 100644 --- a/distrib/sets/lists/comp/mi +++ b/distrib/sets/lists/comp/mi @@ -6307,6 +6307,7 @@ ./usr/share/man/cat3/atoi.0 comp-c-catman .cat ./usr/share/man/cat3/atol.0 comp-c-catman .cat ./usr/share/man/cat3/atoll.0 comp-c-catman .cat +./usr/share/man/cat3/atomic.0 comp-c-catman .cat ./usr/share/man/cat3/atomic_add.0 comp-c-catman .cat ./usr/share/man/cat3/atomic_add_32.0 comp-c-catman .cat ./usr/share/man/cat3/atomic_add_32_nv.0 comp-c-catman .cat @@ -8913,12 +8914,15 @@ ./usr/share/man/cat3/md5.0 comp-c-catman .cat ./usr/share/man/cat3/mdc2.0 comp-obsolete obsolete ./usr/share/man/cat3/mdoc.0 comp-obsolete obsolete +./usr/share/man/cat3/membar.0 comp-c-catman .cat +./usr/share/man/cat3/membar_acquire.0 comp-c-catman .cat ./usr/share/man/cat3/membar_consumer.0 comp-c-catman .cat ./usr/share/man/cat3/membar_datadep_consumer.0 comp-c-catman .cat ./usr/share/man/cat3/membar_enter.0 comp-c-catman .cat ./usr/share/man/cat3/membar_exit.0 comp-c-catman .cat ./usr/share/man/cat3/membar_ops.0 comp-c-catman .cat ./usr/share/man/cat3/membar_producer.0 comp-c-catman .cat +./usr/share/man/cat3/membar_release.0 comp-c-catman .cat ./usr/share/man/cat3/membar_sync.0 comp-c-catman .cat ./usr/share/man/cat3/memccpy.0 comp-c-catman .cat ./usr/share/man/cat3/memchr.0 comp-c-catman .cat @@ -14668,6 +14672,7 @@ ./usr/share/man/html3/atoi.html comp-c-htmlman html ./usr/share/man/html3/atol.html comp-c-htmlman html ./usr/share/man/html3/atoll.html comp-c-htmlman html +./usr/share/man/html3/atomic.html comp-c-htmlman html ./usr/share/man/html3/atomic_add.html comp-c-htmlman html ./usr/share/man/html3/atomic_add_32.html comp-c-htmlman html ./usr/share/man/html3/atomic_add_32_nv.html comp-c-htmlman html @@ -17195,12 +17200,15 @@ ./usr/share/man/html3/md4.html comp-c-htmlman html ./usr/share/man/html3/md5.html comp-c-htmlman html ./usr/share/man/html3/mdoc.html comp-obsolete obsolete +./usr/share/man/html3/membar.html comp-c-htmlman html +./usr/share/man/html3/membar_acquire.html comp-c-htmlman html ./usr/share/man/html3/membar_consumer.html comp-c-htmlman html ./usr/share/man/html3/membar_datadep_consumer.html comp-c-htmlman html ./usr/share/man/html3/membar_enter.html comp-c-htmlman html ./usr/share/man/html3/membar_exit.html comp-c-htmlman html ./usr/share/man/html3/membar_ops.html comp-c-htmlman html ./usr/share/man/html3/membar_producer.html comp-c-htmlman html +./usr/share/man/html3/membar_release.html comp-c-htmlman html ./usr/share/man/html3/membar_sync.html comp-c-htmlman html ./usr/share/man/html3/memccpy.html comp-c-htmlman html ./usr/share/man/html3/memchr.html comp-c-htmlman html @@ -22866,6 +22874,7 @@ ./usr/share/man/man3/atoi.3 comp-c-man .man ./usr/share/man/man3/atol.3 comp-c-man .man ./usr/share/man/man3/atoll.3 comp-c-man .man +./usr/share/man/man3/atomic.3 comp-c-man .man ./usr/share/man/man3/atomic_add.3 comp-c-man .man ./usr/share/man/man3/atomic_add_32.3 comp-c-man .man ./usr/share/man/man3/atomic_add_32_nv.3 comp-c-man .man @@ -25484,12 +25493,15 @@ ./usr/share/man/man3/md5.3 comp-c-man .man ./usr/share/man/man3/mdc2.3 comp-obsolete obsolete ./usr/share/man/man3/mdoc.3 comp-obsolete obsolete +./usr/share/man/man3/membar.3 comp-c-man .man +./usr/share/man/man3/membar_acquire.3 comp-c-man .man ./usr/share/man/man3/membar_consumer.3 comp-c-man .man ./usr/share/man/man3/membar_datadep_consumer.3 comp-c-man .man ./usr/share/man/man3/membar_enter.3 comp-c-man .man ./usr/share/man/man3/membar_exit.3 comp-c-man .man ./usr/share/man/man3/membar_ops.3 comp-c-man .man ./usr/share/man/man3/membar_producer.3 comp-c-man .man +./usr/share/man/man3/membar_release.3 comp-c-man .man ./usr/share/man/man3/membar_sync.3 comp-c-man .man ./usr/share/man/man3/memccpy.3 comp-c-man .man ./usr/share/man/man3/memchr.3 comp-c-man .man diff --git a/lib/libc/atomic/Makefile.inc b/lib/libc/atomic/Makefile.inc index 55af586964ed..b3389ba5a81e 100644 --- a/lib/libc/atomic/Makefile.inc +++ b/lib/libc/atomic/Makefile.inc @@ -75,6 +75,10 @@ MLINKS+=atomic_add.3 atomic_add_32.3 \ atomic_swap.3 atomic_swap_ulong.3 \ atomic_swap.3 atomic_swap_ptr.3 \ atomic_swap.3 atomic_swap_64.3 \ + atomic_ops.3 atomic.3 \ + membar_ops.3 membar.3 \ + membar_ops.3 membar_acquire.3 \ + membar_ops.3 membar_release.3 \ membar_ops.3 membar_enter.3 \ membar_ops.3 membar_exit.3 \ membar_ops.3 membar_producer.3 \ diff --git a/lib/libc/atomic/membar_ops.3 b/lib/libc/atomic/membar_ops.3 index a6b26ccef121..5d2ca5917542 100644 --- a/lib/libc/atomic/membar_ops.3 +++ b/lib/libc/atomic/membar_ops.3 @@ -27,13 +27,13 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd September 2, 2020 +.Dd March 30, 2022 .Dt MEMBAR_OPS 3 .Os .Sh NAME .Nm membar_ops , -.Nm membar_enter , -.Nm membar_exit , +.Nm membar_acquire , +.Nm membar_release , .Nm membar_producer , .Nm membar_consumer , .Nm membar_datadep_consumer , @@ -45,9 +45,9 @@ .In sys/atomic.h .\" .Ft void -.Fn membar_enter "void" +.Fn membar_acquire "void" .Ft void -.Fn membar_exit "void" +.Fn membar_release "void" .Ft void .Fn membar_producer "void" .Ft void @@ -65,9 +65,9 @@ relaxed load and store order. .Pp In general, memory barriers must come in pairs \(em a barrier on one CPU, such as -.Fn membar_exit , +.Fn membar_release , must pair with a barrier on another CPU, such as -.Fn membar_enter , +.Fn membar_acquire , in order to synchronize anything between the two CPUs. Code using .Nm @@ -92,40 +92,25 @@ not just C11 atomic operations on .Vt _Atomic\^ Ns -qualified objects. .Bl -tag -width abcd -.It Fn membar_enter -Any store preceding -.Fn membar_enter +.It Fn membar_acquire +Any load preceding +.Fn membar_acquire will happen before all memory operations following it. .Pp -An atomic read/modify/write operation -.Pq Xr atomic_ops 3 -followed by a -.Fn membar_enter +A load followed by a +.Fn membar_acquire implies a .Em load-acquire operation in the language of C11. +.Fn membar_acquire +should only be used after atomic read/modify/write, such as +.Xr atomic_cas_uint 3 . +For regular loads, instead of +.Li "x = *p; membar_acquire()" , +you should use +.Li "x = atomic_load_acquire(p)" . .Pp -.Sy WARNING : -A load followed by -.Fn membar_enter -.Em does not -imply a -.Em load-acquire -operation, even though -.Fn membar_exit -followed by a store implies a -.Em store-release -operation; the symmetry of these names and asymmetry of the semantics -is a historical mistake. -In the -.Nx -kernel, you can use -.Xr atomic_load_acquire 9 -for a -.Em load-acquire -operation without any atomic read/modify/write. -.Pp -.Fn membar_enter +.Fn membar_acquire is typically used in code that implements locking primitives to ensure that a lock protects its data, and is typically paired with .Fn membar_exit ; @@ -150,14 +135,14 @@ you should use .Pp .Fn membar_exit is typically paired with -.Fn membar_enter , +.Fn membar_acquire , and is typically used in code that implements locking or reference counting primitives. Releasing a lock or reference count should use .Fn membar_exit , and acquiring a lock or handling an object after draining references should use -.Fn membar_enter , +.Fn membar_acquire , so that whatever happened before releasing will also have happened before acquiring. For example: @@ -174,7 +159,7 @@ atomic_dec_uint(&obj->refcnt); */ while (atomic_cas_uint(&obj->refcnt, 0, -1) != 0) continue; -membar_enter(); +membar_acquire(); KASSERT(valid(&obj->state)); obj->state.mumblefrotz--; .Ed @@ -190,7 +175,7 @@ in thread A setting the reference count to zero, everything in thread A before the .Fn membar_exit is guaranteed to happen before everything in thread B after the -.Fn membar_enter , +.Fn membar_acquire , as if the machine had sequentially executed: .Bd -literal -offset abcdefgh obj->state.mumblefrotz = 42; /* from thread A */ @@ -204,7 +189,7 @@ obj->state.mumblefrotz--; followed by a store, serving as a .Em store-release operation, may also be paired with a subsequent load followed by -.Fn membar_sync , +.Fn membar_acquire , serving as the corresponding .Em load-acquire operation. @@ -337,24 +322,48 @@ in C11. is typically paired with .Fn membar_sync . .Pp -A load followed by -.Fn membar_sync , -serving as a -.Em load-acquire -operation, may also be paired with a prior -.Fn membar_exit -followed by a store, serving as the corresponding -.Em store-release -operation. -However, you should use -.Xr atomic_load_acquire 9 -instead of -.No load-then- Ns Fn membar_sync -if it is a regular load, or -.Fn membar_enter -instead of .Fn membar_sync -if the load is in an atomic read/modify/write operation. +is typically not needed except in exotic synchronization schemes like +Dekker's algorithm that require store-before-load ordering. +If you are tempted to reach for it, see if there is another way to do +what you're trying to do first. +.El +.Sh DEPRECATED MEMORY BARRIERS +The following memory barriers are deprecated. +They were imported from Solaris, which describes them as providing +ordering relative to +.Sq lock acquisition , +but the documentation in +.Nx +disagreed with the implementation and use on the semantics. +.Bl -tag -width abcd +.It Fn membar_enter +Originally documented as store-before-load/store, this was instead +implemented as load-before-load/store on some platforms, which is what +essentially all uses relied on. +Now this is implemented as an alias for +.Fn membar_sync +everywhere, meaning a full load/store-before-load/store sequential +consistency barrier, in order to guarantee what the documentation +claimed +.Em and +what the implementation actually did. +.Pp +New code should use +.Fn membar_acquire +for load-before-load/store ordering, which is what most uses need, or +.Fn membar_sync +for store-before-load/store ordering, which typically only appears in +exotic synchronization schemes like Dekker's algorithm. +.It Fn membar_exit +Alias for +.Fn membar_release . +This was originally meant to be paired with +.Fn membar_enter . +.Pp +New code should use +.Fn membar_release +instead. .El .Sh SEE ALSO .Xr atomic_ops 3 , @@ -366,7 +375,19 @@ The .Nm membar_ops functions first appeared in .Nx 5.0 . +.Pp The data-dependent load barrier, .Fn membar_datadep_consumer , first appeared in .Nx 7.0 . +.Pp +The +.Fn membar_acquire +and +.Fn membar_release +functions first appeared, and the +.Fn membar_enter +and +.Fn membar_exit +functions were deprecated, in +.Nx 10.0 . diff --git a/share/man/man9/atomic_loadstore.9 b/share/man/man9/atomic_loadstore.9 index 762524c12406..dd2b8f84f552 100644 --- a/share/man/man9/atomic_loadstore.9 +++ b/share/man/man9/atomic_loadstore.9 @@ -27,7 +27,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd November 25, 2019 +.Dd February 11, 2022 .Dt ATOMIC_LOADSTORE 9 .Os .Sh NAME @@ -648,7 +648,7 @@ is an atomic read/modify/write operation in .Xr atomic_ops 3 , then .Bd -literal - membar_exit(); + membar_release(); atomic_r/m/w(obj, ...); .Ed .Pp @@ -657,32 +657,34 @@ functions like a release operation on and .Bd -literal atomic_r/m/w(obj, ...); - membar_enter(); + membar_acquire(); .Ed .Pp functions like a acquire operation on .Va obj . .Pp -.Sy WARNING : -The combination of -.Fn atomic_load_relaxed -and -.Xr membar_enter 3 -.Em does not -make an acquire operation; only read/modify/write atomics may be -combined with -.Xr membar_enter 3 -this way. -.Pp On architectures where .Dv __HAVE_ATOMIC_AS_MEMBAR is defined, all the .Xr atomic_ops 3 imply release and acquire operations, so the -.Xr membar_enter 3 +.Xr membar_acquire 3 and -.Xr membar_exit 3 +.Xr membar_release 3 are redundant. +.Pp +The combination of +.Fn atomic_load_relaxed +and +.Xr membar_acquire 3 +in that order is equivalent to +.Fn atomic_load_acquire , +and the combination of +.Xr membar_release 3 +and +.Fn atomic_store_relaxed +in that order is equivalent to +.Fn atomic_store_release . .Sh EXAMPLES Maintaining lossy counters. These may lose some counts, because the read/modify/write cycle as a diff --git a/sys/sys/atomic.h b/sys/sys/atomic.h index 916861c468c2..76b8ed841d65 100644 --- a/sys/sys/atomic.h +++ b/sys/sys/atomic.h @@ -181,12 +181,18 @@ uint8_t atomic_cas_8(volatile uint8_t *, uint8_t, uint8_t); /* * Memory barrier operations */ -void membar_enter(void); -void membar_exit(void); +void membar_acquire(void); +void membar_release(void); void membar_producer(void); void membar_consumer(void); void membar_sync(void); +/* + * Deprecated memory barriers + */ +void membar_enter(void); +void membar_exit(void); + #ifdef __HAVE_MEMBAR_DATADEP_CONSUMER void membar_datadep_consumer(void); #else diff --git a/tests/lib/libc/membar/t_dekker.c b/tests/lib/libc/membar/t_dekker.c index f1f2656099e8..c8ea984c7970 100644 --- a/tests/lib/libc/membar/t_dekker.c +++ b/tests/lib/libc/membar/t_dekker.c @@ -44,10 +44,6 @@ __RCSID("$NetBSD$"); #include #include -/* XXX */ -#define membar_acquire() membar_enter() -#define membar_release() membar_exit() - #ifdef BROKEN_SYNC #undef membar_sync #define membar_sync() asm volatile("" ::: "memory") diff --git a/tests/lib/libc/membar/t_spinlock.c b/tests/lib/libc/membar/t_spinlock.c index 7addd4e557cb..1fbdf1775288 100644 --- a/tests/lib/libc/membar/t_spinlock.c +++ b/tests/lib/libc/membar/t_spinlock.c @@ -44,10 +44,6 @@ __RCSID("$NetBSD$"); #include #include -/* XXX */ -#define membar_acquire() membar_enter() -#define membar_release() membar_exit() - #ifdef BROKEN_ACQUIRE #undef membar_acquire #define membar_acquire() asm volatile("" ::: "memory")