diff options
| author | Mark Rutland <mark.rutland@arm.com> | 2018-06-21 08:13:09 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@kernel.org> | 2018-06-21 08:22:33 -0400 |
| commit | eccc2da8c03f316bba202e15af2be4615f461900 (patch) | |
| tree | 1efd0bf1e8620a33ed58cd74cacc94ffc8cf111f /include/linux/atomic.h | |
| parent | bef828204a1bc7a0fd3a24551c4265e9c2ab95ed (diff) | |
atomics/treewide: Make atomic_fetch_add_unless() optional
Several architectures these have a near-identical implementation based
on atomic_read() and atomic_cmpxchg() which we can instead define in
<linux/atomic.h>, so let's do so, using something close to the existing
x86 implementation with try_cmpxchg().
Where an architecture provides its own atomic_fetch_add_unless(), it
must define a preprocessor symbol for it. The instrumented atomics are
updated accordingly.
Note that arch/arc's existing atomic_fetch_add_unless() had redundant
barriers, as these are already present in its atomic_cmpxchg()
implementation.
There should be no functional change as a result of this patch.
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Geert Uytterhoeven <geert@linux-m68k.org>
Reviewed-by: Will Deacon <will.deacon@arm.com>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Palmer Dabbelt <palmer@sifive.com>
Cc: Boqun Feng <boqun.feng@gmail.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vineet Gupta <vgupta@synopsys.com>
Link: https://lore.kernel.org/lkml/20180621121321.4761-7-mark.rutland@arm.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'include/linux/atomic.h')
| -rw-r--r-- | include/linux/atomic.h | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/include/linux/atomic.h b/include/linux/atomic.h index ae3f30923d05..b89ba36cab94 100644 --- a/include/linux/atomic.h +++ b/include/linux/atomic.h | |||
| @@ -522,6 +522,29 @@ | |||
| 522 | #endif /* xchg_relaxed */ | 522 | #endif /* xchg_relaxed */ |
| 523 | 523 | ||
| 524 | /** | 524 | /** |
| 525 | * atomic_fetch_add_unless - add unless the number is already a given value | ||
| 526 | * @v: pointer of type atomic_t | ||
| 527 | * @a: the amount to add to v... | ||
| 528 | * @u: ...unless v is equal to u. | ||
| 529 | * | ||
| 530 | * Atomically adds @a to @v, if @v was not already @u. | ||
| 531 | * Returns the original value of @v. | ||
| 532 | */ | ||
| 533 | #ifndef atomic_fetch_add_unless | ||
| 534 | static inline int atomic_fetch_add_unless(atomic_t *v, int a, int u) | ||
| 535 | { | ||
| 536 | int c = atomic_read(v); | ||
| 537 | |||
| 538 | do { | ||
| 539 | if (unlikely(c == u)) | ||
| 540 | break; | ||
| 541 | } while (!atomic_try_cmpxchg(v, &c, c + a)); | ||
| 542 | |||
| 543 | return c; | ||
| 544 | } | ||
| 545 | #endif | ||
| 546 | |||
| 547 | /** | ||
| 525 | * atomic_add_unless - add unless the number is already a given value | 548 | * atomic_add_unless - add unless the number is already a given value |
| 526 | * @v: pointer of type atomic_t | 549 | * @v: pointer of type atomic_t |
| 527 | * @a: the amount to add to v... | 550 | * @a: the amount to add to v... |
