xref: /freebsd/sys/contrib/openzfs/lib/libspl/atomic.c (revision 17aab35a77a1b1bf02fc85bb8ffadccb0ca5006d)
116038816SMartin Matuska /*
216038816SMartin Matuska  * CDDL HEADER START
316038816SMartin Matuska  *
416038816SMartin Matuska  * The contents of this file are subject to the terms of the
516038816SMartin Matuska  * Common Development and Distribution License, Version 1.0 only
616038816SMartin Matuska  * (the "License").  You may not use this file except in compliance
716038816SMartin Matuska  * with the License.
816038816SMartin Matuska  *
916038816SMartin Matuska  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10271171e0SMartin Matuska  * or https://opensource.org/licenses/CDDL-1.0.
1116038816SMartin Matuska  * See the License for the specific language governing permissions
1216038816SMartin Matuska  * and limitations under the License.
1316038816SMartin Matuska  *
1416038816SMartin Matuska  * When distributing Covered Code, include this CDDL HEADER in each
1516038816SMartin Matuska  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1616038816SMartin Matuska  * If applicable, add the following below this CDDL HEADER, with the
1716038816SMartin Matuska  * fields enclosed by brackets "[]" replaced with your own identifying
1816038816SMartin Matuska  * information: Portions Copyright [yyyy] [name of copyright owner]
1916038816SMartin Matuska  *
2016038816SMartin Matuska  * CDDL HEADER END
2116038816SMartin Matuska  */
2216038816SMartin Matuska /*
2316038816SMartin Matuska  * Copyright (c) 2009 by Sun Microsystems, Inc.  All rights reserved.
2416038816SMartin Matuska  * Use is subject to license terms.
2516038816SMartin Matuska  */
2616038816SMartin Matuska 
2716038816SMartin Matuska #include <atomic.h>
2816038816SMartin Matuska 
2916038816SMartin Matuska /*
3016038816SMartin Matuska  * These are the void returning variants
3116038816SMartin Matuska  */
3216038816SMartin Matuska #define	ATOMIC_INC(name, type) \
3316038816SMartin Matuska 	void atomic_inc_##name(volatile type *target)			\
3416038816SMartin Matuska 	{								\
3516038816SMartin Matuska 		(void) __atomic_add_fetch(target, 1, __ATOMIC_SEQ_CST);	\
3616038816SMartin Matuska 	}
3716038816SMartin Matuska 
3816038816SMartin Matuska ATOMIC_INC(8, uint8_t)
3916038816SMartin Matuska ATOMIC_INC(16, uint16_t)
4016038816SMartin Matuska ATOMIC_INC(32, uint32_t)
41c03c5b1cSMartin Matuska ATOMIC_INC(64, uint64_t)
ATOMIC_INC(uchar,uchar_t)42c03c5b1cSMartin Matuska ATOMIC_INC(uchar, uchar_t)
43c03c5b1cSMartin Matuska ATOMIC_INC(ushort, ushort_t)
4416038816SMartin Matuska ATOMIC_INC(uint, uint_t)
4516038816SMartin Matuska ATOMIC_INC(ulong, ulong_t)
4616038816SMartin Matuska 
4716038816SMartin Matuska 
4816038816SMartin Matuska #define	ATOMIC_DEC(name, type) \
4916038816SMartin Matuska 	void atomic_dec_##name(volatile type *target)			\
5016038816SMartin Matuska 	{								\
5116038816SMartin Matuska 		(void) __atomic_sub_fetch(target, 1, __ATOMIC_SEQ_CST);	\
5216038816SMartin Matuska 	}
5316038816SMartin Matuska 
5416038816SMartin Matuska ATOMIC_DEC(8, uint8_t)
5516038816SMartin Matuska ATOMIC_DEC(16, uint16_t)
5616038816SMartin Matuska ATOMIC_DEC(32, uint32_t)
57c03c5b1cSMartin Matuska ATOMIC_DEC(64, uint64_t)
58c03c5b1cSMartin Matuska ATOMIC_DEC(uchar, uchar_t)
59c03c5b1cSMartin Matuska ATOMIC_DEC(ushort, ushort_t)
6016038816SMartin Matuska ATOMIC_DEC(uint, uint_t)
6116038816SMartin Matuska ATOMIC_DEC(ulong, ulong_t)
6216038816SMartin Matuska 
6316038816SMartin Matuska 
6416038816SMartin Matuska #define	ATOMIC_ADD(name, type1, type2) \
6516038816SMartin Matuska 	void atomic_add_##name(volatile type1 *target, type2 bits)	\
6616038816SMartin Matuska 	{								\
6716038816SMartin Matuska 		(void) __atomic_add_fetch(target, bits, __ATOMIC_SEQ_CST); \
6816038816SMartin Matuska 	}
6916038816SMartin Matuska 
7016038816SMartin Matuska void
7116038816SMartin Matuska atomic_add_ptr(volatile void *target, ssize_t bits)
7216038816SMartin Matuska {
7316038816SMartin Matuska 	(void) __atomic_add_fetch((void **)target, bits, __ATOMIC_SEQ_CST);
7416038816SMartin Matuska }
7516038816SMartin Matuska 
76c03c5b1cSMartin Matuska ATOMIC_ADD(8, uint8_t, int8_t)
77c03c5b1cSMartin Matuska ATOMIC_ADD(16, uint16_t, int16_t)
78c03c5b1cSMartin Matuska ATOMIC_ADD(32, uint32_t, int32_t)
79c03c5b1cSMartin Matuska ATOMIC_ADD(64, uint64_t, int64_t)
ATOMIC_ADD(char,uchar_t,signed char)80c03c5b1cSMartin Matuska ATOMIC_ADD(char, uchar_t, signed char)
81c03c5b1cSMartin Matuska ATOMIC_ADD(short, ushort_t, short)
82c03c5b1cSMartin Matuska ATOMIC_ADD(int, uint_t, int)
83c03c5b1cSMartin Matuska ATOMIC_ADD(long, ulong_t, long)
84c03c5b1cSMartin Matuska 
8516038816SMartin Matuska 
8616038816SMartin Matuska #define	ATOMIC_SUB(name, type1, type2) \
8716038816SMartin Matuska 	void atomic_sub_##name(volatile type1 *target, type2 bits)	\
8816038816SMartin Matuska 	{								\
8916038816SMartin Matuska 		(void) __atomic_sub_fetch(target, bits, __ATOMIC_SEQ_CST); \
9016038816SMartin Matuska 	}
9116038816SMartin Matuska 
9216038816SMartin Matuska void
9316038816SMartin Matuska atomic_sub_ptr(volatile void *target, ssize_t bits)
9416038816SMartin Matuska {
9516038816SMartin Matuska 	(void) __atomic_sub_fetch((void **)target, bits, __ATOMIC_SEQ_CST);
9616038816SMartin Matuska }
9716038816SMartin Matuska 
98c03c5b1cSMartin Matuska ATOMIC_SUB(8, uint8_t, int8_t)
99c03c5b1cSMartin Matuska ATOMIC_SUB(16, uint16_t, int16_t)
100c03c5b1cSMartin Matuska ATOMIC_SUB(32, uint32_t, int32_t)
101c03c5b1cSMartin Matuska ATOMIC_SUB(64, uint64_t, int64_t)
ATOMIC_SUB(char,uchar_t,signed char)102c03c5b1cSMartin Matuska ATOMIC_SUB(char, uchar_t, signed char)
103c03c5b1cSMartin Matuska ATOMIC_SUB(short, ushort_t, short)
104c03c5b1cSMartin Matuska ATOMIC_SUB(int, uint_t, int)
105c03c5b1cSMartin Matuska ATOMIC_SUB(long, ulong_t, long)
106c03c5b1cSMartin Matuska 
10716038816SMartin Matuska 
10816038816SMartin Matuska #define	ATOMIC_OR(name, type) \
10916038816SMartin Matuska 	void atomic_or_##name(volatile type *target, type bits)		\
11016038816SMartin Matuska 	{								\
11116038816SMartin Matuska 		(void) __atomic_or_fetch(target, bits, __ATOMIC_SEQ_CST); \
11216038816SMartin Matuska 	}
11316038816SMartin Matuska 
11416038816SMartin Matuska ATOMIC_OR(8, uint8_t)
11516038816SMartin Matuska ATOMIC_OR(16, uint16_t)
11616038816SMartin Matuska ATOMIC_OR(32, uint32_t)
117c03c5b1cSMartin Matuska ATOMIC_OR(64, uint64_t)
118c03c5b1cSMartin Matuska ATOMIC_OR(uchar, uchar_t)
119c03c5b1cSMartin Matuska ATOMIC_OR(ushort, ushort_t)
12016038816SMartin Matuska ATOMIC_OR(uint, uint_t)
12116038816SMartin Matuska ATOMIC_OR(ulong, ulong_t)
12216038816SMartin Matuska 
12316038816SMartin Matuska 
12416038816SMartin Matuska #define	ATOMIC_AND(name, type) \
12516038816SMartin Matuska 	void atomic_and_##name(volatile type *target, type bits)	\
12616038816SMartin Matuska 	{								\
12716038816SMartin Matuska 		(void) __atomic_and_fetch(target, bits, __ATOMIC_SEQ_CST); \
12816038816SMartin Matuska 	}
12916038816SMartin Matuska 
13016038816SMartin Matuska ATOMIC_AND(8, uint8_t)
13116038816SMartin Matuska ATOMIC_AND(16, uint16_t)
13216038816SMartin Matuska ATOMIC_AND(32, uint32_t)
133c03c5b1cSMartin Matuska ATOMIC_AND(64, uint64_t)
134c03c5b1cSMartin Matuska ATOMIC_AND(uchar, uchar_t)
135c03c5b1cSMartin Matuska ATOMIC_AND(ushort, ushort_t)
13616038816SMartin Matuska ATOMIC_AND(uint, uint_t)
13716038816SMartin Matuska ATOMIC_AND(ulong, ulong_t)
13816038816SMartin Matuska 
13916038816SMartin Matuska 
14016038816SMartin Matuska /*
14116038816SMartin Matuska  * New value returning variants
14216038816SMartin Matuska  */
14316038816SMartin Matuska 
14416038816SMartin Matuska #define	ATOMIC_INC_NV(name, type) \
14516038816SMartin Matuska 	type atomic_inc_##name##_nv(volatile type *target)		\
14616038816SMartin Matuska 	{								\
14716038816SMartin Matuska 		return (__atomic_add_fetch(target, 1, __ATOMIC_SEQ_CST)); \
14816038816SMartin Matuska 	}
14916038816SMartin Matuska 
15016038816SMartin Matuska ATOMIC_INC_NV(8, uint8_t)
15116038816SMartin Matuska ATOMIC_INC_NV(16, uint16_t)
15216038816SMartin Matuska ATOMIC_INC_NV(32, uint32_t)
153c03c5b1cSMartin Matuska ATOMIC_INC_NV(64, uint64_t)
154c03c5b1cSMartin Matuska ATOMIC_INC_NV(uchar, uchar_t)
155c03c5b1cSMartin Matuska ATOMIC_INC_NV(ushort, ushort_t)
15616038816SMartin Matuska ATOMIC_INC_NV(uint, uint_t)
15716038816SMartin Matuska ATOMIC_INC_NV(ulong, ulong_t)
15816038816SMartin Matuska 
15916038816SMartin Matuska 
16016038816SMartin Matuska #define	ATOMIC_DEC_NV(name, type) \
16116038816SMartin Matuska 	type atomic_dec_##name##_nv(volatile type *target)		\
16216038816SMartin Matuska 	{								\
16316038816SMartin Matuska 		return (__atomic_sub_fetch(target, 1, __ATOMIC_SEQ_CST)); \
16416038816SMartin Matuska 	}
16516038816SMartin Matuska 
16616038816SMartin Matuska ATOMIC_DEC_NV(8, uint8_t)
16716038816SMartin Matuska ATOMIC_DEC_NV(16, uint16_t)
16816038816SMartin Matuska ATOMIC_DEC_NV(32, uint32_t)
169c03c5b1cSMartin Matuska ATOMIC_DEC_NV(64, uint64_t)
170c03c5b1cSMartin Matuska ATOMIC_DEC_NV(uchar, uchar_t)
171c03c5b1cSMartin Matuska ATOMIC_DEC_NV(ushort, ushort_t)
17216038816SMartin Matuska ATOMIC_DEC_NV(uint, uint_t)
17316038816SMartin Matuska ATOMIC_DEC_NV(ulong, ulong_t)
17416038816SMartin Matuska 
17516038816SMartin Matuska 
17616038816SMartin Matuska #define	ATOMIC_ADD_NV(name, type1, type2) \
17716038816SMartin Matuska 	type1 atomic_add_##name##_nv(volatile type1 *target, type2 bits) \
17816038816SMartin Matuska 	{								\
17916038816SMartin Matuska 		return (__atomic_add_fetch(target, bits, __ATOMIC_SEQ_CST)); \
18016038816SMartin Matuska 	}
18116038816SMartin Matuska 
18216038816SMartin Matuska void *
18316038816SMartin Matuska atomic_add_ptr_nv(volatile void *target, ssize_t bits)
18416038816SMartin Matuska {
18516038816SMartin Matuska 	return (__atomic_add_fetch((void **)target, bits, __ATOMIC_SEQ_CST));
18616038816SMartin Matuska }
18716038816SMartin Matuska 
188c03c5b1cSMartin Matuska ATOMIC_ADD_NV(8, uint8_t, int8_t)
189c03c5b1cSMartin Matuska ATOMIC_ADD_NV(16, uint16_t, int16_t)
190c03c5b1cSMartin Matuska ATOMIC_ADD_NV(32, uint32_t, int32_t)
191c03c5b1cSMartin Matuska ATOMIC_ADD_NV(64, uint64_t, int64_t)
ATOMIC_ADD_NV(char,uchar_t,signed char)192c03c5b1cSMartin Matuska ATOMIC_ADD_NV(char, uchar_t, signed char)
193c03c5b1cSMartin Matuska ATOMIC_ADD_NV(short, ushort_t, short)
194c03c5b1cSMartin Matuska ATOMIC_ADD_NV(int, uint_t, int)
195c03c5b1cSMartin Matuska ATOMIC_ADD_NV(long, ulong_t, long)
196c03c5b1cSMartin Matuska 
19716038816SMartin Matuska 
19816038816SMartin Matuska #define	ATOMIC_SUB_NV(name, type1, type2) \
19916038816SMartin Matuska 	type1 atomic_sub_##name##_nv(volatile type1 *target, type2 bits) \
20016038816SMartin Matuska 	{								\
20116038816SMartin Matuska 		return (__atomic_sub_fetch(target, bits, __ATOMIC_SEQ_CST)); \
20216038816SMartin Matuska 	}
20316038816SMartin Matuska 
204c03c5b1cSMartin Matuska void *
205c03c5b1cSMartin Matuska atomic_sub_ptr_nv(volatile void *target, ssize_t bits)
206c03c5b1cSMartin Matuska {
207c03c5b1cSMartin Matuska 	return (__atomic_sub_fetch((void **)target, bits, __ATOMIC_SEQ_CST));
208c03c5b1cSMartin Matuska }
209c03c5b1cSMartin Matuska 
21016038816SMartin Matuska ATOMIC_SUB_NV(8, uint8_t, int8_t)
ATOMIC_SUB_NV(char,uchar_t,signed char)21116038816SMartin Matuska ATOMIC_SUB_NV(char, uchar_t, signed char)
21216038816SMartin Matuska ATOMIC_SUB_NV(16, uint16_t, int16_t)
21316038816SMartin Matuska ATOMIC_SUB_NV(short, ushort_t, short)
21416038816SMartin Matuska ATOMIC_SUB_NV(32, uint32_t, int32_t)
21516038816SMartin Matuska ATOMIC_SUB_NV(int, uint_t, int)
21616038816SMartin Matuska ATOMIC_SUB_NV(long, ulong_t, long)
21716038816SMartin Matuska ATOMIC_SUB_NV(64, uint64_t, int64_t)
21816038816SMartin Matuska 
21916038816SMartin Matuska 
22016038816SMartin Matuska #define	ATOMIC_OR_NV(name, type) \
22116038816SMartin Matuska 	type atomic_or_##name##_nv(volatile type *target, type bits)	\
22216038816SMartin Matuska 	{								\
22316038816SMartin Matuska 		return (__atomic_or_fetch(target, bits, __ATOMIC_SEQ_CST)); \
22416038816SMartin Matuska 	}
22516038816SMartin Matuska 
22616038816SMartin Matuska ATOMIC_OR_NV(8, uint8_t)
22716038816SMartin Matuska ATOMIC_OR_NV(16, uint16_t)
22816038816SMartin Matuska ATOMIC_OR_NV(32, uint32_t)
229c03c5b1cSMartin Matuska ATOMIC_OR_NV(64, uint64_t)
230c03c5b1cSMartin Matuska ATOMIC_OR_NV(uchar, uchar_t)
231c03c5b1cSMartin Matuska ATOMIC_OR_NV(ushort, ushort_t)
23216038816SMartin Matuska ATOMIC_OR_NV(uint, uint_t)
23316038816SMartin Matuska ATOMIC_OR_NV(ulong, ulong_t)
23416038816SMartin Matuska 
23516038816SMartin Matuska 
23616038816SMartin Matuska #define	ATOMIC_AND_NV(name, type) \
23716038816SMartin Matuska 	type atomic_and_##name##_nv(volatile type *target, type bits)	\
23816038816SMartin Matuska 	{								\
23916038816SMartin Matuska 		return (__atomic_and_fetch(target, bits, __ATOMIC_SEQ_CST)); \
24016038816SMartin Matuska 	}
24116038816SMartin Matuska 
24216038816SMartin Matuska ATOMIC_AND_NV(8, uint8_t)
24316038816SMartin Matuska ATOMIC_AND_NV(16, uint16_t)
24416038816SMartin Matuska ATOMIC_AND_NV(32, uint32_t)
245c03c5b1cSMartin Matuska ATOMIC_AND_NV(64, uint64_t)
246c03c5b1cSMartin Matuska ATOMIC_AND_NV(uchar, uchar_t)
247c03c5b1cSMartin Matuska ATOMIC_AND_NV(ushort, ushort_t)
24816038816SMartin Matuska ATOMIC_AND_NV(uint, uint_t)
24916038816SMartin Matuska ATOMIC_AND_NV(ulong, ulong_t)
25016038816SMartin Matuska 
25116038816SMartin Matuska 
25216038816SMartin Matuska /*
25316038816SMartin Matuska  * If *tgt == exp, set *tgt = des; return old value
25416038816SMartin Matuska  *
25516038816SMartin Matuska  * This may not look right on the first pass (or the sixteenth), but,
25616038816SMartin Matuska  * from https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html:
25716038816SMartin Matuska  * > If they are not equal, the operation is a read
25816038816SMartin Matuska  * > and the current contents of *ptr are written into *expected.
25916038816SMartin Matuska  * And, in the converse case, exp is already *target by definition.
26016038816SMartin Matuska  */
26116038816SMartin Matuska 
26216038816SMartin Matuska #define	ATOMIC_CAS(name, type) \
26316038816SMartin Matuska 	type atomic_cas_##name(volatile type *target, type exp, type des) \
26416038816SMartin Matuska 	{								\
26516038816SMartin Matuska 		__atomic_compare_exchange_n(target, &exp, des, B_FALSE,	\
26616038816SMartin Matuska 		    __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);		\
26716038816SMartin Matuska 		return (exp);						\
26816038816SMartin Matuska 	}
26916038816SMartin Matuska 
27016038816SMartin Matuska void *
27116038816SMartin Matuska atomic_cas_ptr(volatile void *target, void *exp, void *des)
27216038816SMartin Matuska {
27316038816SMartin Matuska 
27416038816SMartin Matuska 	__atomic_compare_exchange_n((void **)target, &exp, des, B_FALSE,
27516038816SMartin Matuska 	    __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
27616038816SMartin Matuska 	return (exp);
27716038816SMartin Matuska }
27816038816SMartin Matuska 
279c03c5b1cSMartin Matuska ATOMIC_CAS(8, uint8_t)
280c03c5b1cSMartin Matuska ATOMIC_CAS(16, uint16_t)
281c03c5b1cSMartin Matuska ATOMIC_CAS(32, uint32_t)
282c03c5b1cSMartin Matuska ATOMIC_CAS(64, uint64_t)
ATOMIC_CAS(uchar,uchar_t)283c03c5b1cSMartin Matuska ATOMIC_CAS(uchar, uchar_t)
284c03c5b1cSMartin Matuska ATOMIC_CAS(ushort, ushort_t)
285c03c5b1cSMartin Matuska ATOMIC_CAS(uint, uint_t)
286c03c5b1cSMartin Matuska ATOMIC_CAS(ulong, ulong_t)
287c03c5b1cSMartin Matuska 
28816038816SMartin Matuska 
28916038816SMartin Matuska /*
29016038816SMartin Matuska  * Swap target and return old value
29116038816SMartin Matuska  */
29216038816SMartin Matuska 
29316038816SMartin Matuska #define	ATOMIC_SWAP(name, type) \
29416038816SMartin Matuska 	type atomic_swap_##name(volatile type *target, type bits)	\
29516038816SMartin Matuska 	{								\
29616038816SMartin Matuska 		return (__atomic_exchange_n(target, bits, __ATOMIC_SEQ_CST)); \
29716038816SMartin Matuska 	}
29816038816SMartin Matuska 
29916038816SMartin Matuska ATOMIC_SWAP(8, uint8_t)
30016038816SMartin Matuska ATOMIC_SWAP(16, uint16_t)
30116038816SMartin Matuska ATOMIC_SWAP(32, uint32_t)
302c03c5b1cSMartin Matuska ATOMIC_SWAP(64, uint64_t)
303c03c5b1cSMartin Matuska ATOMIC_SWAP(uchar, uchar_t)
304c03c5b1cSMartin Matuska ATOMIC_SWAP(ushort, ushort_t)
30516038816SMartin Matuska ATOMIC_SWAP(uint, uint_t)
30616038816SMartin Matuska ATOMIC_SWAP(ulong, ulong_t)
30716038816SMartin Matuska 
30816038816SMartin Matuska void *
30916038816SMartin Matuska atomic_swap_ptr(volatile void *target, void *bits)
31016038816SMartin Matuska {
31116038816SMartin Matuska 	return (__atomic_exchange_n((void **)target, bits, __ATOMIC_SEQ_CST));
31216038816SMartin Matuska }
31316038816SMartin Matuska 
31416038816SMartin Matuska #ifndef _LP64
31516038816SMartin Matuska uint64_t
atomic_load_64(volatile uint64_t * target)31616038816SMartin Matuska atomic_load_64(volatile uint64_t *target)
31716038816SMartin Matuska {
31816038816SMartin Matuska 	return (__atomic_load_n(target, __ATOMIC_RELAXED));
31916038816SMartin Matuska }
32016038816SMartin Matuska 
32116038816SMartin Matuska void
atomic_store_64(volatile uint64_t * target,uint64_t bits)32216038816SMartin Matuska atomic_store_64(volatile uint64_t *target, uint64_t bits)
32316038816SMartin Matuska {
32416038816SMartin Matuska 	return (__atomic_store_n(target, bits, __ATOMIC_RELAXED));
32516038816SMartin Matuska }
32616038816SMartin Matuska #endif
32716038816SMartin Matuska 
32816038816SMartin Matuska int
atomic_set_long_excl(volatile ulong_t * target,uint_t value)32916038816SMartin Matuska atomic_set_long_excl(volatile ulong_t *target, uint_t value)
33016038816SMartin Matuska {
33116038816SMartin Matuska 	ulong_t bit = 1UL << value;
33216038816SMartin Matuska 	ulong_t old = __atomic_fetch_or(target, bit, __ATOMIC_SEQ_CST);
33316038816SMartin Matuska 	return ((old & bit) ? -1 : 0);
33416038816SMartin Matuska }
33516038816SMartin Matuska 
33616038816SMartin Matuska int
atomic_clear_long_excl(volatile ulong_t * target,uint_t value)33716038816SMartin Matuska atomic_clear_long_excl(volatile ulong_t *target, uint_t value)
33816038816SMartin Matuska {
33916038816SMartin Matuska 	ulong_t bit = 1UL << value;
34016038816SMartin Matuska 	ulong_t old = __atomic_fetch_and(target, ~bit, __ATOMIC_SEQ_CST);
34116038816SMartin Matuska 	return ((old & bit) ? 0 : -1);
34216038816SMartin Matuska }
34316038816SMartin Matuska 
34416038816SMartin Matuska void
membar_enter(void)34516038816SMartin Matuska membar_enter(void)
34616038816SMartin Matuska {
34716038816SMartin Matuska 	__atomic_thread_fence(__ATOMIC_SEQ_CST);
34816038816SMartin Matuska }
34916038816SMartin Matuska 
35016038816SMartin Matuska void
membar_exit(void)35116038816SMartin Matuska membar_exit(void)
35216038816SMartin Matuska {
35316038816SMartin Matuska 	__atomic_thread_fence(__ATOMIC_SEQ_CST);
35416038816SMartin Matuska }
35516038816SMartin Matuska 
35616038816SMartin Matuska void
membar_sync(void)357*c7046f76SMartin Matuska membar_sync(void)
358*c7046f76SMartin Matuska {
359*c7046f76SMartin Matuska 	__atomic_thread_fence(__ATOMIC_SEQ_CST);
360*c7046f76SMartin Matuska }
361*c7046f76SMartin Matuska 
362*c7046f76SMartin Matuska void
membar_producer(void)36316038816SMartin Matuska membar_producer(void)
36416038816SMartin Matuska {
36516038816SMartin Matuska 	__atomic_thread_fence(__ATOMIC_RELEASE);
36616038816SMartin Matuska }
36716038816SMartin Matuska 
36816038816SMartin Matuska void
membar_consumer(void)36916038816SMartin Matuska membar_consumer(void)
37016038816SMartin Matuska {
37116038816SMartin Matuska 	__atomic_thread_fence(__ATOMIC_ACQUIRE);
37216038816SMartin Matuska }
373