| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: atomic.h,v 1.24 2021/12/19 01:33:51 riastradh Exp $ */ | | 1 | /* $NetBSD: atomic.h,v 1.25 2021/12/19 01:39:20 riastradh Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2013 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2013 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Taylor R. Campbell. | | 8 | * by Taylor R. Campbell. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -159,26 +159,42 @@ static inline void | | | @@ -159,26 +159,42 @@ static inline void |
159 | atomic_or(int value, atomic_t *atomic) | | 159 | atomic_or(int value, atomic_t *atomic) |
160 | { | | 160 | { |
161 | /* no membar */ | | 161 | /* no membar */ |
162 | atomic_or_uint(&atomic->a_u.au_uint, value); | | 162 | atomic_or_uint(&atomic->a_u.au_uint, value); |
163 | } | | 163 | } |
164 | | | 164 | |
165 | static inline void | | 165 | static inline void |
166 | atomic_andnot(int value, atomic_t *atomic) | | 166 | atomic_andnot(int value, atomic_t *atomic) |
167 | { | | 167 | { |
168 | /* no membar */ | | 168 | /* no membar */ |
169 | atomic_and_uint(&atomic->a_u.au_uint, ~value); | | 169 | atomic_and_uint(&atomic->a_u.au_uint, ~value); |
170 | } | | 170 | } |
171 | | | 171 | |
| | | 172 | static inline int |
| | | 173 | atomic_fetch_xor(int value, atomic_t *atomic) |
| | | 174 | { |
| | | 175 | unsigned old, new; |
| | | 176 | |
| | | 177 | smp_mb__before_atomic(); |
| | | 178 | do { |
| | | 179 | old = atomic->a_u.au_uint; |
| | | 180 | __insn_barrier(); |
| | | 181 | new = old ^ value; |
| | | 182 | } while (atomic_cas_uint(&atomic->a_u.au_uint, old, new) != old); |
| | | 183 | smp_mb__after_atomic(); |
| | | 184 | |
| | | 185 | return old; |
| | | 186 | } |
| | | 187 | |
172 | static inline void | | 188 | static inline void |
173 | atomic_set_mask(unsigned long mask, atomic_t *atomic) | | 189 | atomic_set_mask(unsigned long mask, atomic_t *atomic) |
174 | { | | 190 | { |
175 | /* no membar */ | | 191 | /* no membar */ |
176 | atomic_or_uint(&atomic->a_u.au_uint, mask); | | 192 | atomic_or_uint(&atomic->a_u.au_uint, mask); |
177 | } | | 193 | } |
178 | | | 194 | |
179 | static inline void | | 195 | static inline void |
180 | atomic_clear_mask(unsigned long mask, atomic_t *atomic) | | 196 | atomic_clear_mask(unsigned long mask, atomic_t *atomic) |
181 | { | | 197 | { |
182 | /* no membar */ | | 198 | /* no membar */ |
183 | atomic_and_uint(&atomic->a_u.au_uint, ~mask); | | 199 | atomic_and_uint(&atomic->a_u.au_uint, ~mask); |
184 | } | | 200 | } |