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;