Skip to content

Commit fa88e7b

Browse files
hjelmnbosilca
authored andcommitted
arm64: add atomic swap function
This commit adds the opal_atomic_swap_32 and opal_atomic_swap_64 functions. This should improve the performance of btl/vader. Signed-off-by: Nathan Hjelm <[email protected]>
1 parent 58545a3 commit fa88e7b

File tree

1 file changed

+31
-0
lines changed

1 file changed

+31
-0
lines changed

opal/include/opal/sys/arm64/atomic.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,10 @@
3030
#define OPAL_HAVE_ATOMIC_MEM_BARRIER 1
3131
#define OPAL_HAVE_ATOMIC_LLSC_32 1
3232
#define OPAL_HAVE_ATOMIC_CMPSET_32 1
33+
#define OPAL_HAVE_ATOMIC_SWAP_32 1
3334
#define OPAL_HAVE_ATOMIC_MATH_32 1
3435
#define OPAL_HAVE_ATOMIC_CMPSET_64 1
36+
#define OPAL_HAVE_ATOMIC_SWAP_64 1
3537
#define OPAL_HAVE_ATOMIC_LLSC_64 1
3638
#define OPAL_HAVE_ATOMIC_ADD_32 1
3739
#define OPAL_HAVE_ATOMIC_SUB_32 1
@@ -92,6 +94,20 @@ static inline int opal_atomic_cmpset_32(volatile int32_t *addr,
9294
return (ret == oldval);
9395
}
9496

97+
static inline int32_t opal_atomic_swap_32(volatile int32_t *addr, int32_t newval)
98+
{
99+
int32_t ret, tmp;
100+
101+
__asm__ __volatile__ ("1: ldaxr %w0, [%2] \n"
102+
" stlxr %w1, %w3, [%2] \n"
103+
" cbnz %w1, 1b \n"
104+
: "=&r" (ret), "=&r" (tmp)
105+
: "r" (addr), "r" (newval)
106+
: "cc", "memory");
107+
108+
return ret;
109+
}
110+
95111
/* these two functions aren't inlined in the non-gcc case because then
96112
there would be two function calls (since neither cmpset_32 nor
97113
atomic_?mb can be inlined). Instead, we "inline" them by hand in
@@ -176,6 +192,21 @@ static inline int opal_atomic_cmpset_64(volatile int64_t *addr,
176192
return (ret == oldval);
177193
}
178194

195+
static inline int64_t opal_atomic_swap_64 (volatile int64_t *addr, int64_t newval)
196+
{
197+
int64_t ret;
198+
int tmp;
199+
200+
__asm__ __volatile__ ("1: ldaxr %0, [%2] \n"
201+
" stlxr %w1, %3, [%2] \n"
202+
" cbnz %w1, 1b \n"
203+
: "=&r" (ret), "=&r" (tmp)
204+
: "r" (addr), "r" (newval)
205+
: "cc", "memory");
206+
207+
return ret;
208+
}
209+
179210
/* these two functions aren't inlined in the non-gcc case because then
180211
there would be two function calls (since neither cmpset_64 nor
181212
atomic_?mb can be inlined). Instead, we "inline" them by hand in

0 commit comments

Comments
 (0)