summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2024-07-12 14:24:38 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2024-07-12 14:24:38 -0400
commit4be409afea5fb4325eecf78d29dc463fcd9c3e31 (patch)
tree8667ab6e565f479ba419721802531bc6d3f760ef
parent0f9b409aeec18a3e62949ee717f42337a8a9f0c8 (diff)
provide atomic64_try_cmpxchg() for 32bit
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r--include/linux/atomic.h1
-rw-r--r--linux/atomic64.c15
2 files changed, 16 insertions, 0 deletions
diff --git a/include/linux/atomic.h b/include/linux/atomic.h
index dcc6e644..c594ff8b 100644
--- a/include/linux/atomic.h
+++ b/include/linux/atomic.h
@@ -344,6 +344,7 @@ void atomic64_sub(s64, atomic64_t *);
s64 atomic64_xchg(atomic64_t *, s64);
s64 atomic64_cmpxchg(atomic64_t *, s64, s64);
+bool atomic64_try_cmpxchg(atomic64_t *, s64 *, s64);
#define atomic64_add_negative(a, v) (atomic64_add_return((a), (v)) < 0)
#define atomic64_inc(v) atomic64_add(1LL, (v))
diff --git a/linux/atomic64.c b/linux/atomic64.c
index 4654d092..2dbbc995 100644
--- a/linux/atomic64.c
+++ b/linux/atomic64.c
@@ -157,6 +157,21 @@ long long atomic64_cmpxchg(atomic64_t *v, long long o, long long n)
return val;
}
+bool atomic64_try_cmpxchg(atomic64_t *v, s64 *o, s64 n)
+{
+ unsigned long flags;
+ raw_spinlock_t *lock = lock_addr(v);
+
+ raw_spin_lock_irqsave(lock, flags);
+ bool ret = v->counter == *o;
+ if (ret)
+ v->counter = n;
+ else
+ *o = v->counter;
+ raw_spin_unlock_irqrestore(lock, flags);
+ return ret;
+}
+
long long atomic64_xchg(atomic64_t *v, long long new)
{
unsigned long flags;