Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e1ab7f39 authored by Boqun Feng's avatar Boqun Feng Committed by Michael Ellerman
Browse files

atomics: Allow architectures to define their own __atomic_op_* helpers



Some architectures may have their special barriers for acquire, release
and fence semantics, so that general memory barriers(smp_mb__*_atomic())
in the default __atomic_op_*() may be too strong, so allow architectures
to define their own helpers which can overwrite the default helpers.

Signed-off-by: default avatarBoqun Feng <boqun.feng@gmail.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent 78c1cffd
Loading
Loading
Loading
Loading
+10 −0
Original line number Original line Diff line number Diff line
@@ -34,20 +34,29 @@
 * The idea here is to build acquire/release variants by adding explicit
 * The idea here is to build acquire/release variants by adding explicit
 * barriers on top of the relaxed variant. In the case where the relaxed
 * barriers on top of the relaxed variant. In the case where the relaxed
 * variant is already fully ordered, no additional barriers are needed.
 * variant is already fully ordered, no additional barriers are needed.
 *
 * Besides, if an arch has a special barrier for acquire/release, it could
 * implement its own __atomic_op_* and use the same framework for building
 * variants
 */
 */
#ifndef __atomic_op_acquire
#define __atomic_op_acquire(op, args...)				\
#define __atomic_op_acquire(op, args...)				\
({									\
({									\
	typeof(op##_relaxed(args)) __ret  = op##_relaxed(args);		\
	typeof(op##_relaxed(args)) __ret  = op##_relaxed(args);		\
	smp_mb__after_atomic();						\
	smp_mb__after_atomic();						\
	__ret;								\
	__ret;								\
})
})
#endif


#ifndef __atomic_op_release
#define __atomic_op_release(op, args...)				\
#define __atomic_op_release(op, args...)				\
({									\
({									\
	smp_mb__before_atomic();					\
	smp_mb__before_atomic();					\
	op##_relaxed(args);						\
	op##_relaxed(args);						\
})
})
#endif


#ifndef __atomic_op_fence
#define __atomic_op_fence(op, args...)					\
#define __atomic_op_fence(op, args...)					\
({									\
({									\
	typeof(op##_relaxed(args)) __ret;				\
	typeof(op##_relaxed(args)) __ret;				\
@@ -56,6 +65,7 @@
	smp_mb__after_atomic();						\
	smp_mb__after_atomic();						\
	__ret;								\
	__ret;								\
})
})
#endif


/* atomic_add_return_relaxed */
/* atomic_add_return_relaxed */
#ifndef atomic_add_return_relaxed
#ifndef atomic_add_return_relaxed