locking/arch: Wire up local_try_cmpxchg()
Implement target specific support for local_try_cmpxchg() and local_cmpxchg() using typed C wrappers that call their _local counterpart and provide additional checking of their input arguments. Signed-off-by: Uros Bizjak <ubizjak@gmail.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://lore.kernel.org/r/20230405141710.3551-4-ubizjak@gmail.com Cc: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
8fc4fddaf9
commit
d994f2c8e2
|
@ -52,8 +52,16 @@ static __inline__ long local_sub_return(long i, local_t * l)
|
|||
return result;
|
||||
}
|
||||
|
||||
#define local_cmpxchg(l, o, n) \
|
||||
(cmpxchg_local(&((l)->a.counter), (o), (n)))
|
||||
static __inline__ long local_cmpxchg(local_t *l, long old, long new)
|
||||
{
|
||||
return cmpxchg_local(&l->a.counter, old, new);
|
||||
}
|
||||
|
||||
static __inline__ bool local_try_cmpxchg(local_t *l, long *old, long new)
|
||||
{
|
||||
return try_cmpxchg_local(&l->a.counter, (s64 *)old, new);
|
||||
}
|
||||
|
||||
#define local_xchg(l, n) (xchg_local(&((l)->a.counter), (n)))
|
||||
|
||||
/**
|
||||
|
|
|
@ -56,8 +56,17 @@ static inline long local_sub_return(long i, local_t *l)
|
|||
return result;
|
||||
}
|
||||
|
||||
#define local_cmpxchg(l, o, n) \
|
||||
((long)cmpxchg_local(&((l)->a.counter), (o), (n)))
|
||||
static inline long local_cmpxchg(local_t *l, long old, long new)
|
||||
{
|
||||
return cmpxchg_local(&l->a.counter, old, new);
|
||||
}
|
||||
|
||||
static inline bool local_try_cmpxchg(local_t *l, long *old, long new)
|
||||
{
|
||||
typeof(l->a.counter) *__old = (typeof(l->a.counter) *) old;
|
||||
return try_cmpxchg_local(&l->a.counter, __old, new);
|
||||
}
|
||||
|
||||
#define local_xchg(l, n) (atomic_long_xchg((&(l)->a), (n)))
|
||||
|
||||
/**
|
||||
|
|
|
@ -94,8 +94,17 @@ static __inline__ long local_sub_return(long i, local_t * l)
|
|||
return result;
|
||||
}
|
||||
|
||||
#define local_cmpxchg(l, o, n) \
|
||||
((long)cmpxchg_local(&((l)->a.counter), (o), (n)))
|
||||
static __inline__ long local_cmpxchg(local_t *l, long old, long new)
|
||||
{
|
||||
return cmpxchg_local(&l->a.counter, old, new);
|
||||
}
|
||||
|
||||
static __inline__ bool local_try_cmpxchg(local_t *l, long *old, long new)
|
||||
{
|
||||
typeof(l->a.counter) *__old = (typeof(l->a.counter) *) old;
|
||||
return try_cmpxchg_local(&l->a.counter, __old, new);
|
||||
}
|
||||
|
||||
#define local_xchg(l, n) (atomic_long_xchg((&(l)->a), (n)))
|
||||
|
||||
/**
|
||||
|
|
|
@ -90,6 +90,17 @@ static __inline__ long local_cmpxchg(local_t *l, long o, long n)
|
|||
return t;
|
||||
}
|
||||
|
||||
static __inline__ bool local_try_cmpxchg(local_t *l, long *po, long n)
|
||||
{
|
||||
long o = *po, r;
|
||||
|
||||
r = local_cmpxchg(l, o, n);
|
||||
if (unlikely(r != o))
|
||||
*po = r;
|
||||
|
||||
return likely(r == o);
|
||||
}
|
||||
|
||||
static __inline__ long local_xchg(local_t *l, long n)
|
||||
{
|
||||
long t;
|
||||
|
|
|
@ -120,8 +120,17 @@ static inline long local_sub_return(long i, local_t *l)
|
|||
#define local_inc_return(l) (local_add_return(1, l))
|
||||
#define local_dec_return(l) (local_sub_return(1, l))
|
||||
|
||||
#define local_cmpxchg(l, o, n) \
|
||||
(cmpxchg_local(&((l)->a.counter), (o), (n)))
|
||||
static inline long local_cmpxchg(local_t *l, long old, long new)
|
||||
{
|
||||
return cmpxchg_local(&l->a.counter, old, new);
|
||||
}
|
||||
|
||||
static inline bool local_try_cmpxchg(local_t *l, long *old, long new)
|
||||
{
|
||||
typeof(l->a.counter) *__old = (typeof(l->a.counter) *) old;
|
||||
return try_cmpxchg_local(&l->a.counter, __old, new);
|
||||
}
|
||||
|
||||
/* Always has a lock prefix */
|
||||
#define local_xchg(l, n) (xchg(&((l)->a.counter), (n)))
|
||||
|
||||
|
|
Loading…
Reference in New Issue