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

Commit f8d638e2 authored by Peter Zijlstra's avatar Peter Zijlstra Committed by Ingo Molnar
Browse files

locking/atomic, arch/mn10300: Implement atomic_fetch_{add,sub,and,or,xor}()



Implement FETCH-OP atomic primitives, these are very similar to the
existing OP-RETURN primitives we already have, except they return the
value of the atomic variable _before_ modification.

This is especially useful for irreversible operations -- such as
bitops (because it becomes impossible to reconstruct the state prior
to modification).

Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-am33-list@redhat.com
Cc: linux-arch@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parent 4edac529
Loading
Loading
Loading
Loading
+31 −4
Original line number Diff line number Diff line
@@ -84,16 +84,43 @@ static inline int atomic_##op##_return(int i, atomic_t *v) \
	return retval;							\
}

#define ATOMIC_OPS(op) ATOMIC_OP(op) ATOMIC_OP_RETURN(op)
#define ATOMIC_FETCH_OP(op)						\
static inline int atomic_fetch_##op(int i, atomic_t *v)			\
{									\
	int retval, status;						\
									\
	asm volatile(							\
		"1:	mov	%4,(_AAR,%3)	\n"			\
		"	mov	(_ADR,%3),%1	\n"			\
		"	mov	%1,%0		\n"			\
		"	" #op "	%5,%0		\n"			\
		"	mov	%0,(_ADR,%3)	\n"			\
		"	mov	(_ADR,%3),%0	\n"	/* flush */	\
		"	mov	(_ASR,%3),%0	\n"			\
		"	or	%0,%0		\n"			\
		"	bne	1b		\n"			\
		: "=&r"(status), "=&r"(retval), "=m"(v->counter)	\
		: "a"(ATOMIC_OPS_BASE_ADDR), "r"(&v->counter), "r"(i)	\
		: "memory", "cc");					\
	return retval;							\
}

#define ATOMIC_OPS(op) ATOMIC_OP(op) ATOMIC_OP_RETURN(op) ATOMIC_FETCH_OP(op)

ATOMIC_OPS(add)
ATOMIC_OPS(sub)

ATOMIC_OP(and)
ATOMIC_OP(or)
ATOMIC_OP(xor)
#undef ATOMIC_OPS
#define ATOMIC_OPS(op) ATOMIC_OP(op) ATOMIC_FETCH_OP(op)

#define atomic_fetch_or atomic_fetch_or

ATOMIC_OPS(and)
ATOMIC_OPS(or)
ATOMIC_OPS(xor)

#undef ATOMIC_OPS
#undef ATOMIC_FETCH_OP
#undef ATOMIC_OP_RETURN
#undef ATOMIC_OP