Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

tools/memory-model: Distinguish between syntactic and semantic tags

Not all annotated accesses provide the semantics their syntactic tags
would imply. For example, an 'acquire tag on a write does not imply that
the write is finally in the Acquire set and provides acquire ordering.

To distinguish in those cases between the syntactic tags and actual
sets, we capitalize the former, so 'ACQUIRE tags may be present on both
reads and writes, but only reads will appear in the Acquire set.

For tags where the two concepts are the same we do not use specific
capitalization to make this distinction.

Reported-by: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Jonas Oberhauser <jonas.oberhauser@huaweicloud.com>
Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
Tested-by: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Tested-by: Akira Yokosawa <akiyks@gmail.com> # herdtools7.7.58

authored by

Jonas Oberhauser and committed by
Paul E. McKenney
dcc51978 fafa1806

+121 -121
+22 -22
tools/memory-model/Documentation/herd-representation.txt
··· 21 21 # Note that the syntactic representation does not always match the sets and 22 22 # relations in linux-kernel.cat, due to redefinitions in linux-kernel.bell and 23 23 # lock.cat. For example, the po link between LKR and LKW is upgraded to an rmw 24 - # link, and W[acquire] are not included in the Acquire set. 24 + # link, and W[ACQUIRE] are not included in the Acquire set. 25 25 # 26 26 # Disclaimer. The table includes representations of "add" and "and" operations; 27 27 # corresponding/identical representations of "sub", "inc", "dec" and "or", "xor", ··· 32 32 ------------------------------------------------------------------------------ 33 33 | Non-RMW ops | | 34 34 ------------------------------------------------------------------------------ 35 - | READ_ONCE | R[once] | 35 + | READ_ONCE | R[ONCE] | 36 36 | atomic_read | | 37 - | WRITE_ONCE | W[once] | 37 + | WRITE_ONCE | W[ONCE] | 38 38 | atomic_set | | 39 - | smp_load_acquire | R[acquire] | 39 + | smp_load_acquire | R[ACQUIRE] | 40 40 | atomic_read_acquire | | 41 - | smp_store_release | W[release] | 41 + | smp_store_release | W[RELEASE] | 42 42 | atomic_set_release | | 43 - | smp_store_mb | W[once] ->po F[mb] | 44 - | smp_mb | F[mb] | 43 + | smp_store_mb | W[ONCE] ->po F[MB] | 44 + | smp_mb | F[MB] | 45 45 | smp_rmb | F[rmb] | 46 46 | smp_wmb | F[wmb] | 47 47 | smp_mb__before_atomic | F[before-atomic] | ··· 54 54 | rcu_read_lock | F[rcu-lock] | 55 55 | rcu_read_unlock | F[rcu-unlock] | 56 56 | synchronize_rcu | F[sync-rcu] | 57 - | rcu_dereference | R[once] | 58 - | rcu_assign_pointer | W[release] | 57 + | rcu_dereference | R[ONCE] | 58 + | rcu_assign_pointer | W[RELEASE] | 59 59 | srcu_read_lock | R[srcu-lock] | 60 60 | srcu_down_read | | 61 61 | srcu_read_unlock | W[srcu-unlock] | ··· 65 65 ------------------------------------------------------------------------------ 66 66 | RMW ops w/o return value | | 67 67 ------------------------------------------------------------------------------ 68 - | atomic_add | R*[noreturn] ->rmw W*[noreturn] | 68 + | atomic_add | R*[NORETURN] ->rmw W*[NORETURN] | 69 69 | atomic_and | | 70 70 | spin_lock | LKR ->po LKW | 71 71 ------------------------------------------------------------------------------ 72 72 | RMW ops w/ return value | | 73 73 ------------------------------------------------------------------------------ 74 - | atomic_add_return | R*[mb] ->rmw W*[mb] | 74 + | atomic_add_return | R*[MB] ->rmw W*[MB] | 75 75 | atomic_fetch_add | | 76 76 | atomic_fetch_and | | 77 77 | atomic_xchg | | 78 78 | xchg | | 79 79 | atomic_add_negative | | 80 - | atomic_add_return_relaxed | R*[once] ->rmw W*[once] | 80 + | atomic_add_return_relaxed | R*[ONCE] ->rmw W*[ONCE] | 81 81 | atomic_fetch_add_relaxed | | 82 82 | atomic_fetch_and_relaxed | | 83 83 | atomic_xchg_relaxed | | 84 84 | xchg_relaxed | | 85 85 | atomic_add_negative_relaxed | | 86 - | atomic_add_return_acquire | R*[acquire] ->rmw W*[acquire] | 86 + | atomic_add_return_acquire | R*[ACQUIRE] ->rmw W*[ACQUIRE] | 87 87 | atomic_fetch_add_acquire | | 88 88 | atomic_fetch_and_acquire | | 89 89 | atomic_xchg_acquire | | 90 90 | xchg_acquire | | 91 91 | atomic_add_negative_acquire | | 92 - | atomic_add_return_release | R*[release] ->rmw W*[release] | 92 + | atomic_add_return_release | R*[RELEASE] ->rmw W*[RELEASE] | 93 93 | atomic_fetch_add_release | | 94 94 | atomic_fetch_and_release | | 95 95 | atomic_xchg_release | | ··· 98 98 ------------------------------------------------------------------------------ 99 99 | Conditional RMW ops | | 100 100 ------------------------------------------------------------------------------ 101 - | atomic_cmpxchg | On success: R*[mb] ->rmw W*[mb] | 102 - | | On failure: R*[mb] | 101 + | atomic_cmpxchg | On success: R*[MB] ->rmw W*[MB] | 102 + | | On failure: R*[MB] | 103 103 | cmpxchg | | 104 104 | atomic_add_unless | | 105 - | atomic_cmpxchg_relaxed | On success: R*[once] ->rmw W*[once] | 106 - | | On failure: R*[once] | 107 - | atomic_cmpxchg_acquire | On success: R*[acquire] ->rmw W*[acquire] | 108 - | | On failure: R*[acquire] | 109 - | atomic_cmpxchg_release | On success: R*[release] ->rmw W*[release] | 110 - | | On failure: R*[release] | 105 + | atomic_cmpxchg_relaxed | On success: R*[ONCE] ->rmw W*[ONCE] | 106 + | | On failure: R*[ONCE] | 107 + | atomic_cmpxchg_acquire | On success: R*[ACQUIRE] ->rmw W*[ACQUIRE] | 108 + | | On failure: R*[ACQUIRE] | 109 + | atomic_cmpxchg_release | On success: R*[RELEASE] ->rmw W*[RELEASE] | 110 + | | On failure: R*[RELEASE] | 111 111 | spin_trylock | On success: LKR ->po LKW | 112 112 | | On failure: LF | 113 113 ------------------------------------------------------------------------------
+11 -11
tools/memory-model/linux-kernel.bell
··· 13 13 14 14 "Linux-kernel memory consistency model" 15 15 16 - enum Accesses = 'once (*READ_ONCE,WRITE_ONCE*) || 17 - 'release (*smp_store_release*) || 18 - 'acquire (*smp_load_acquire*) || 19 - 'noreturn (* R of non-return RMW *) || 20 - 'mb (*xchg(),cmpxchg(),...*) 16 + enum Accesses = 'ONCE (*READ_ONCE,WRITE_ONCE*) || 17 + 'RELEASE (*smp_store_release*) || 18 + 'ACQUIRE (*smp_load_acquire*) || 19 + 'NORETURN (* R of non-return RMW *) || 20 + 'MB (*xchg(),cmpxchg(),...*) 21 21 instructions R[Accesses] 22 22 instructions W[Accesses] 23 23 instructions RMW[Accesses] 24 24 25 25 enum Barriers = 'wmb (*smp_wmb*) || 26 26 'rmb (*smp_rmb*) || 27 - 'mb (*smp_mb*) || 27 + 'MB (*smp_mb*) || 28 28 'barrier (*barrier*) || 29 29 'rcu-lock (*rcu_read_lock*) || 30 30 'rcu-unlock (*rcu_read_unlock*) || ··· 42 42 * semantic ordering, such as Acquire on a store or Mb on a failed RMW. 43 43 *) 44 44 let FailedRMW = RMW \ (domain(rmw) | range(rmw)) 45 - let Acquire = Acquire \ W \ FailedRMW 46 - let Release = Release \ R \ FailedRMW 47 - let Mb = Mb \ FailedRMW 48 - let Noreturn = Noreturn \ W 45 + let Acquire = ACQUIRE \ W \ FailedRMW 46 + let Release = RELEASE \ R \ FailedRMW 47 + let Mb = MB \ FailedRMW 48 + let Noreturn = NORETURN \ W 49 49 50 50 (* SRCU *) 51 51 enum SRCU = 'srcu-lock || 'srcu-unlock || 'sync-srcu ··· 85 85 flag ~empty different-values(srcu-rscs) as srcu-bad-value-match 86 86 87 87 (* Compute marked and plain memory accesses *) 88 - let Marked = (~M) | IW | Once | Release | Acquire | domain(rmw) | range(rmw) | 88 + let Marked = (~M) | IW | ONCE | RELEASE | ACQUIRE | MB | RMW | 89 89 LKR | LKW | UL | LF | RL | RU | Srcu-lock | Srcu-unlock 90 90 let Plain = M \ Marked 91 91
+88 -88
tools/memory-model/linux-kernel.def
··· 6 6 // which appeared in ASPLOS 2018. 7 7 8 8 // ONCE 9 - READ_ONCE(X) __load{once}(X) 10 - WRITE_ONCE(X,V) { __store{once}(X,V); } 9 + READ_ONCE(X) __load{ONCE}(X) 10 + WRITE_ONCE(X,V) { __store{ONCE}(X,V); } 11 11 12 12 // Release Acquire and friends 13 - smp_store_release(X,V) { __store{release}(*X,V); } 14 - smp_load_acquire(X) __load{acquire}(*X) 15 - rcu_assign_pointer(X,V) { __store{release}(X,V); } 16 - rcu_dereference(X) __load{once}(X) 17 - smp_store_mb(X,V) { __store{once}(X,V); __fence{mb}; } 13 + smp_store_release(X,V) { __store{RELEASE}(*X,V); } 14 + smp_load_acquire(X) __load{ACQUIRE}(*X) 15 + rcu_assign_pointer(X,V) { __store{RELEASE}(X,V); } 16 + rcu_dereference(X) __load{ONCE}(X) 17 + smp_store_mb(X,V) { __store{ONCE}(X,V); __fence{MB}; } 18 18 19 19 // Fences 20 - smp_mb() { __fence{mb}; } 20 + smp_mb() { __fence{MB}; } 21 21 smp_rmb() { __fence{rmb}; } 22 22 smp_wmb() { __fence{wmb}; } 23 23 smp_mb__before_atomic() { __fence{before-atomic}; } ··· 28 28 barrier() { __fence{barrier}; } 29 29 30 30 // Exchange 31 - xchg(X,V) __xchg{mb}(X,V) 32 - xchg_relaxed(X,V) __xchg{once}(X,V) 33 - xchg_release(X,V) __xchg{release}(X,V) 34 - xchg_acquire(X,V) __xchg{acquire}(X,V) 35 - cmpxchg(X,V,W) __cmpxchg{mb}(X,V,W) 36 - cmpxchg_relaxed(X,V,W) __cmpxchg{once}(X,V,W) 37 - cmpxchg_acquire(X,V,W) __cmpxchg{acquire}(X,V,W) 38 - cmpxchg_release(X,V,W) __cmpxchg{release}(X,V,W) 31 + xchg(X,V) __xchg{MB}(X,V) 32 + xchg_relaxed(X,V) __xchg{ONCE}(X,V) 33 + xchg_release(X,V) __xchg{RELEASE}(X,V) 34 + xchg_acquire(X,V) __xchg{ACQUIRE}(X,V) 35 + cmpxchg(X,V,W) __cmpxchg{MB}(X,V,W) 36 + cmpxchg_relaxed(X,V,W) __cmpxchg{ONCE}(X,V,W) 37 + cmpxchg_acquire(X,V,W) __cmpxchg{ACQUIRE}(X,V,W) 38 + cmpxchg_release(X,V,W) __cmpxchg{RELEASE}(X,V,W) 39 39 40 40 // Spinlocks 41 41 spin_lock(X) { __lock(X); } ··· 63 63 atomic_read_acquire(X) smp_load_acquire(X) 64 64 atomic_set_release(X,V) { smp_store_release(X,V); } 65 65 66 - atomic_add(V,X) { __atomic_op{noreturn}(X,+,V); } 67 - atomic_sub(V,X) { __atomic_op{noreturn}(X,-,V); } 68 - atomic_and(V,X) { __atomic_op{noreturn}(X,&,V); } 69 - atomic_or(V,X) { __atomic_op{noreturn}(X,|,V); } 70 - atomic_xor(V,X) { __atomic_op{noreturn}(X,^,V); } 71 - atomic_inc(X) { __atomic_op{noreturn}(X,+,1); } 72 - atomic_dec(X) { __atomic_op{noreturn}(X,-,1); } 73 - atomic_andnot(V,X) { __atomic_op{noreturn}(X,&~,V); } 66 + atomic_add(V,X) { __atomic_op{NORETURN}(X,+,V); } 67 + atomic_sub(V,X) { __atomic_op{NORETURN}(X,-,V); } 68 + atomic_and(V,X) { __atomic_op{NORETURN}(X,&,V); } 69 + atomic_or(V,X) { __atomic_op{NORETURN}(X,|,V); } 70 + atomic_xor(V,X) { __atomic_op{NORETURN}(X,^,V); } 71 + atomic_inc(X) { __atomic_op{NORETURN}(X,+,1); } 72 + atomic_dec(X) { __atomic_op{NORETURN}(X,-,1); } 73 + atomic_andnot(V,X) { __atomic_op{NORETURN}(X,&~,V); } 74 74 75 - atomic_add_return(V,X) __atomic_op_return{mb}(X,+,V) 76 - atomic_add_return_relaxed(V,X) __atomic_op_return{once}(X,+,V) 77 - atomic_add_return_acquire(V,X) __atomic_op_return{acquire}(X,+,V) 78 - atomic_add_return_release(V,X) __atomic_op_return{release}(X,+,V) 79 - atomic_fetch_add(V,X) __atomic_fetch_op{mb}(X,+,V) 80 - atomic_fetch_add_relaxed(V,X) __atomic_fetch_op{once}(X,+,V) 81 - atomic_fetch_add_acquire(V,X) __atomic_fetch_op{acquire}(X,+,V) 82 - atomic_fetch_add_release(V,X) __atomic_fetch_op{release}(X,+,V) 75 + atomic_add_return(V,X) __atomic_op_return{MB}(X,+,V) 76 + atomic_add_return_relaxed(V,X) __atomic_op_return{ONCE}(X,+,V) 77 + atomic_add_return_acquire(V,X) __atomic_op_return{ACQUIRE}(X,+,V) 78 + atomic_add_return_release(V,X) __atomic_op_return{RELEASE}(X,+,V) 79 + atomic_fetch_add(V,X) __atomic_fetch_op{MB}(X,+,V) 80 + atomic_fetch_add_relaxed(V,X) __atomic_fetch_op{ONCE}(X,+,V) 81 + atomic_fetch_add_acquire(V,X) __atomic_fetch_op{ACQUIRE}(X,+,V) 82 + atomic_fetch_add_release(V,X) __atomic_fetch_op{RELEASE}(X,+,V) 83 83 84 - atomic_fetch_and(V,X) __atomic_fetch_op{mb}(X,&,V) 85 - atomic_fetch_and_relaxed(V,X) __atomic_fetch_op{once}(X,&,V) 86 - atomic_fetch_and_acquire(V,X) __atomic_fetch_op{acquire}(X,&,V) 87 - atomic_fetch_and_release(V,X) __atomic_fetch_op{release}(X,&,V) 84 + atomic_fetch_and(V,X) __atomic_fetch_op{MB}(X,&,V) 85 + atomic_fetch_and_relaxed(V,X) __atomic_fetch_op{ONCE}(X,&,V) 86 + atomic_fetch_and_acquire(V,X) __atomic_fetch_op{ACQUIRE}(X,&,V) 87 + atomic_fetch_and_release(V,X) __atomic_fetch_op{RELEASE}(X,&,V) 88 88 89 - atomic_fetch_or(V,X) __atomic_fetch_op{mb}(X,|,V) 90 - atomic_fetch_or_relaxed(V,X) __atomic_fetch_op{once}(X,|,V) 91 - atomic_fetch_or_acquire(V,X) __atomic_fetch_op{acquire}(X,|,V) 92 - atomic_fetch_or_release(V,X) __atomic_fetch_op{release}(X,|,V) 89 + atomic_fetch_or(V,X) __atomic_fetch_op{MB}(X,|,V) 90 + atomic_fetch_or_relaxed(V,X) __atomic_fetch_op{ONCE}(X,|,V) 91 + atomic_fetch_or_acquire(V,X) __atomic_fetch_op{ACQUIRE}(X,|,V) 92 + atomic_fetch_or_release(V,X) __atomic_fetch_op{RELEASE}(X,|,V) 93 93 94 - atomic_fetch_xor(V,X) __atomic_fetch_op{mb}(X,^,V) 95 - atomic_fetch_xor_relaxed(V,X) __atomic_fetch_op{once}(X,^,V) 96 - atomic_fetch_xor_acquire(V,X) __atomic_fetch_op{acquire}(X,^,V) 97 - atomic_fetch_xor_release(V,X) __atomic_fetch_op{release}(X,^,V) 94 + atomic_fetch_xor(V,X) __atomic_fetch_op{MB}(X,^,V) 95 + atomic_fetch_xor_relaxed(V,X) __atomic_fetch_op{ONCE}(X,^,V) 96 + atomic_fetch_xor_acquire(V,X) __atomic_fetch_op{ACQUIRE}(X,^,V) 97 + atomic_fetch_xor_release(V,X) __atomic_fetch_op{RELEASE}(X,^,V) 98 98 99 - atomic_inc_return(X) __atomic_op_return{mb}(X,+,1) 100 - atomic_inc_return_relaxed(X) __atomic_op_return{once}(X,+,1) 101 - atomic_inc_return_acquire(X) __atomic_op_return{acquire}(X,+,1) 102 - atomic_inc_return_release(X) __atomic_op_return{release}(X,+,1) 103 - atomic_fetch_inc(X) __atomic_fetch_op{mb}(X,+,1) 104 - atomic_fetch_inc_relaxed(X) __atomic_fetch_op{once}(X,+,1) 105 - atomic_fetch_inc_acquire(X) __atomic_fetch_op{acquire}(X,+,1) 106 - atomic_fetch_inc_release(X) __atomic_fetch_op{release}(X,+,1) 99 + atomic_inc_return(X) __atomic_op_return{MB}(X,+,1) 100 + atomic_inc_return_relaxed(X) __atomic_op_return{ONCE}(X,+,1) 101 + atomic_inc_return_acquire(X) __atomic_op_return{ACQUIRE}(X,+,1) 102 + atomic_inc_return_release(X) __atomic_op_return{RELEASE}(X,+,1) 103 + atomic_fetch_inc(X) __atomic_fetch_op{MB}(X,+,1) 104 + atomic_fetch_inc_relaxed(X) __atomic_fetch_op{ONCE}(X,+,1) 105 + atomic_fetch_inc_acquire(X) __atomic_fetch_op{ACQUIRE}(X,+,1) 106 + atomic_fetch_inc_release(X) __atomic_fetch_op{RELEASE}(X,+,1) 107 107 108 - atomic_sub_return(V,X) __atomic_op_return{mb}(X,-,V) 109 - atomic_sub_return_relaxed(V,X) __atomic_op_return{once}(X,-,V) 110 - atomic_sub_return_acquire(V,X) __atomic_op_return{acquire}(X,-,V) 111 - atomic_sub_return_release(V,X) __atomic_op_return{release}(X,-,V) 112 - atomic_fetch_sub(V,X) __atomic_fetch_op{mb}(X,-,V) 113 - atomic_fetch_sub_relaxed(V,X) __atomic_fetch_op{once}(X,-,V) 114 - atomic_fetch_sub_acquire(V,X) __atomic_fetch_op{acquire}(X,-,V) 115 - atomic_fetch_sub_release(V,X) __atomic_fetch_op{release}(X,-,V) 108 + atomic_sub_return(V,X) __atomic_op_return{MB}(X,-,V) 109 + atomic_sub_return_relaxed(V,X) __atomic_op_return{ONCE}(X,-,V) 110 + atomic_sub_return_acquire(V,X) __atomic_op_return{ACQUIRE}(X,-,V) 111 + atomic_sub_return_release(V,X) __atomic_op_return{RELEASE}(X,-,V) 112 + atomic_fetch_sub(V,X) __atomic_fetch_op{MB}(X,-,V) 113 + atomic_fetch_sub_relaxed(V,X) __atomic_fetch_op{ONCE}(X,-,V) 114 + atomic_fetch_sub_acquire(V,X) __atomic_fetch_op{ACQUIRE}(X,-,V) 115 + atomic_fetch_sub_release(V,X) __atomic_fetch_op{RELEASE}(X,-,V) 116 116 117 - atomic_dec_return(X) __atomic_op_return{mb}(X,-,1) 118 - atomic_dec_return_relaxed(X) __atomic_op_return{once}(X,-,1) 119 - atomic_dec_return_acquire(X) __atomic_op_return{acquire}(X,-,1) 120 - atomic_dec_return_release(X) __atomic_op_return{release}(X,-,1) 121 - atomic_fetch_dec(X) __atomic_fetch_op{mb}(X,-,1) 122 - atomic_fetch_dec_relaxed(X) __atomic_fetch_op{once}(X,-,1) 123 - atomic_fetch_dec_acquire(X) __atomic_fetch_op{acquire}(X,-,1) 124 - atomic_fetch_dec_release(X) __atomic_fetch_op{release}(X,-,1) 117 + atomic_dec_return(X) __atomic_op_return{MB}(X,-,1) 118 + atomic_dec_return_relaxed(X) __atomic_op_return{ONCE}(X,-,1) 119 + atomic_dec_return_acquire(X) __atomic_op_return{ACQUIRE}(X,-,1) 120 + atomic_dec_return_release(X) __atomic_op_return{RELEASE}(X,-,1) 121 + atomic_fetch_dec(X) __atomic_fetch_op{MB}(X,-,1) 122 + atomic_fetch_dec_relaxed(X) __atomic_fetch_op{ONCE}(X,-,1) 123 + atomic_fetch_dec_acquire(X) __atomic_fetch_op{ACQUIRE}(X,-,1) 124 + atomic_fetch_dec_release(X) __atomic_fetch_op{RELEASE}(X,-,1) 125 125 126 - atomic_xchg(X,V) __xchg{mb}(X,V) 127 - atomic_xchg_relaxed(X,V) __xchg{once}(X,V) 128 - atomic_xchg_release(X,V) __xchg{release}(X,V) 129 - atomic_xchg_acquire(X,V) __xchg{acquire}(X,V) 130 - atomic_cmpxchg(X,V,W) __cmpxchg{mb}(X,V,W) 131 - atomic_cmpxchg_relaxed(X,V,W) __cmpxchg{once}(X,V,W) 132 - atomic_cmpxchg_acquire(X,V,W) __cmpxchg{acquire}(X,V,W) 133 - atomic_cmpxchg_release(X,V,W) __cmpxchg{release}(X,V,W) 126 + atomic_xchg(X,V) __xchg{MB}(X,V) 127 + atomic_xchg_relaxed(X,V) __xchg{ONCE}(X,V) 128 + atomic_xchg_release(X,V) __xchg{RELEASE}(X,V) 129 + atomic_xchg_acquire(X,V) __xchg{ACQUIRE}(X,V) 130 + atomic_cmpxchg(X,V,W) __cmpxchg{MB}(X,V,W) 131 + atomic_cmpxchg_relaxed(X,V,W) __cmpxchg{ONCE}(X,V,W) 132 + atomic_cmpxchg_acquire(X,V,W) __cmpxchg{ACQUIRE}(X,V,W) 133 + atomic_cmpxchg_release(X,V,W) __cmpxchg{RELEASE}(X,V,W) 134 134 135 - atomic_sub_and_test(V,X) __atomic_op_return{mb}(X,-,V) == 0 136 - atomic_dec_and_test(X) __atomic_op_return{mb}(X,-,1) == 0 137 - atomic_inc_and_test(X) __atomic_op_return{mb}(X,+,1) == 0 138 - atomic_add_negative(V,X) __atomic_op_return{mb}(X,+,V) < 0 139 - atomic_add_negative_relaxed(V,X) __atomic_op_return{once}(X,+,V) < 0 140 - atomic_add_negative_acquire(V,X) __atomic_op_return{acquire}(X,+,V) < 0 141 - atomic_add_negative_release(V,X) __atomic_op_return{release}(X,+,V) < 0 135 + atomic_sub_and_test(V,X) __atomic_op_return{MB}(X,-,V) == 0 136 + atomic_dec_and_test(X) __atomic_op_return{MB}(X,-,1) == 0 137 + atomic_inc_and_test(X) __atomic_op_return{MB}(X,+,1) == 0 138 + atomic_add_negative(V,X) __atomic_op_return{MB}(X,+,V) < 0 139 + atomic_add_negative_relaxed(V,X) __atomic_op_return{ONCE}(X,+,V) < 0 140 + atomic_add_negative_acquire(V,X) __atomic_op_return{ACQUIRE}(X,+,V) < 0 141 + atomic_add_negative_release(V,X) __atomic_op_return{RELEASE}(X,+,V) < 0 142 142 143 - atomic_fetch_andnot(V,X) __atomic_fetch_op{mb}(X,&~,V) 144 - atomic_fetch_andnot_acquire(V,X) __atomic_fetch_op{acquire}(X,&~,V) 145 - atomic_fetch_andnot_release(V,X) __atomic_fetch_op{release}(X,&~,V) 146 - atomic_fetch_andnot_relaxed(V,X) __atomic_fetch_op{once}(X,&~,V) 143 + atomic_fetch_andnot(V,X) __atomic_fetch_op{MB}(X,&~,V) 144 + atomic_fetch_andnot_acquire(V,X) __atomic_fetch_op{ACQUIRE}(X,&~,V) 145 + atomic_fetch_andnot_release(V,X) __atomic_fetch_op{RELEASE}(X,&~,V) 146 + atomic_fetch_andnot_relaxed(V,X) __atomic_fetch_op{ONCE}(X,&~,V) 147 147 148 - atomic_add_unless(X,V,W) __atomic_add_unless{mb}(X,V,W) 148 + atomic_add_unless(X,V,W) __atomic_add_unless{MB}(X,V,W)