Skip to content

Commit d994f2c

Browse files
ubizjakingomolnar
authored andcommitted
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>
1 parent 8fc4fdd commit d994f2c

5 files changed

Lines changed: 54 additions & 8 deletions

File tree

arch/alpha/include/asm/local.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,16 @@ static __inline__ long local_sub_return(long i, local_t * l)
5252
return result;
5353
}
5454

55-
#define local_cmpxchg(l, o, n) \
56-
(cmpxchg_local(&((l)->a.counter), (o), (n)))
55+
static __inline__ long local_cmpxchg(local_t *l, long old, long new)
56+
{
57+
return cmpxchg_local(&l->a.counter, old, new);
58+
}
59+
60+
static __inline__ bool local_try_cmpxchg(local_t *l, long *old, long new)
61+
{
62+
return try_cmpxchg_local(&l->a.counter, (s64 *)old, new);
63+
}
64+
5765
#define local_xchg(l, n) (xchg_local(&((l)->a.counter), (n)))
5866

5967
/**

arch/loongarch/include/asm/local.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,17 @@ static inline long local_sub_return(long i, local_t *l)
5656
return result;
5757
}
5858

59-
#define local_cmpxchg(l, o, n) \
60-
((long)cmpxchg_local(&((l)->a.counter), (o), (n)))
59+
static inline long local_cmpxchg(local_t *l, long old, long new)
60+
{
61+
return cmpxchg_local(&l->a.counter, old, new);
62+
}
63+
64+
static inline bool local_try_cmpxchg(local_t *l, long *old, long new)
65+
{
66+
typeof(l->a.counter) *__old = (typeof(l->a.counter) *) old;
67+
return try_cmpxchg_local(&l->a.counter, __old, new);
68+
}
69+
6170
#define local_xchg(l, n) (atomic_long_xchg((&(l)->a), (n)))
6271

6372
/**

arch/mips/include/asm/local.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,17 @@ static __inline__ long local_sub_return(long i, local_t * l)
9494
return result;
9595
}
9696

97-
#define local_cmpxchg(l, o, n) \
98-
((long)cmpxchg_local(&((l)->a.counter), (o), (n)))
97+
static __inline__ long local_cmpxchg(local_t *l, long old, long new)
98+
{
99+
return cmpxchg_local(&l->a.counter, old, new);
100+
}
101+
102+
static __inline__ bool local_try_cmpxchg(local_t *l, long *old, long new)
103+
{
104+
typeof(l->a.counter) *__old = (typeof(l->a.counter) *) old;
105+
return try_cmpxchg_local(&l->a.counter, __old, new);
106+
}
107+
99108
#define local_xchg(l, n) (atomic_long_xchg((&(l)->a), (n)))
100109

101110
/**

arch/powerpc/include/asm/local.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,17 @@ static __inline__ long local_cmpxchg(local_t *l, long o, long n)
9090
return t;
9191
}
9292

93+
static __inline__ bool local_try_cmpxchg(local_t *l, long *po, long n)
94+
{
95+
long o = *po, r;
96+
97+
r = local_cmpxchg(l, o, n);
98+
if (unlikely(r != o))
99+
*po = r;
100+
101+
return likely(r == o);
102+
}
103+
93104
static __inline__ long local_xchg(local_t *l, long n)
94105
{
95106
long t;

arch/x86/include/asm/local.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,17 @@ static inline long local_sub_return(long i, local_t *l)
120120
#define local_inc_return(l) (local_add_return(1, l))
121121
#define local_dec_return(l) (local_sub_return(1, l))
122122

123-
#define local_cmpxchg(l, o, n) \
124-
(cmpxchg_local(&((l)->a.counter), (o), (n)))
123+
static inline long local_cmpxchg(local_t *l, long old, long new)
124+
{
125+
return cmpxchg_local(&l->a.counter, old, new);
126+
}
127+
128+
static inline bool local_try_cmpxchg(local_t *l, long *old, long new)
129+
{
130+
typeof(l->a.counter) *__old = (typeof(l->a.counter) *) old;
131+
return try_cmpxchg_local(&l->a.counter, __old, new);
132+
}
133+
125134
/* Always has a lock prefix */
126135
#define local_xchg(l, n) (xchg(&((l)->a.counter), (n)))
127136

0 commit comments

Comments
 (0)