History

[PATCH] atomic: add_unless cmpxchg optimise

Without branch hints, the very unlikely chance of the loop repeating due to cmpxchg failure is unrolled with gcc-4 that I have tested. Improve this for architectures with a native cas/cmpxchg. llsc archs should try to implement this natively.

Nick Piggin committed 20 years ago

Commit 0b2fcfd1 parent 713729e6 files · +50 −10Browse files

Unified · Split

6 files
  1. include/asm-i386/atomic.h +7 −1
  2. include/asm-ia64/atomic.h +7 −1
  3. include/asm-m68k/atomic.h +7 −1
  4. include/asm-s390/atomic.h +14 −4
  5. include/asm-sparc64/atomic.h +8 −2
  6. include/asm-x86_64/atomic.h +7 −1
include/asm-i386/atomic.h+7−1
@@ -225,8 +225,14 @@ static __inline__ int atomic_sub_return(int i, atomic_t *v) · 224 unmodified lines
225225 ({ \
226226 int c, old; \
227227 c = atomic_read(v); \
228− while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
228+ for (;;) { \
229+ if (unlikely(c == (u))) \
230+ break; \
231+ old = atomic_cmpxchg((v), c, c + (a)); \
232+ if (likely(old == c)) \
233+ break; \
229234 c = old; \
235+ } \
230236 c != (u); \
231237 })
232238 #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
include/asm-ia64/atomic.h+7−1
@@ -95,8 +95,14 @@ ia64_atomic64_sub (__s64 i, atomic64_t *v) · 94 unmodified lines
9595 ({ \
9696 int c, old; \
9797 c = atomic_read(v); \
98− while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
98+ for (;;) { \
99+ if (unlikely(c == (u))) \
100+ break; \
101+ old = atomic_cmpxchg((v), c, c + (a)); \
102+ if (likely(old == c)) \
103+ break; \
99104 c = old; \
105+ } \
100106 c != (u); \
101107 })
102108 #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
include/asm-m68k/atomic.h+7−1
@@ -175,8 +175,14 @@ static inline void atomic_set_mask(unsigned long mask, unsigned long *v) · 174 unmodified lines
175175 ({ \
176176 int c, old; \
177177 c = atomic_read(v); \
178− while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
178+ for (;;) { \
179+ if (unlikely(c == (u))) \
180+ break; \
181+ old = atomic_cmpxchg((v), c, c + (a)); \
182+ if (likely(old == c)) \
183+ break; \
179184 c = old; \
185+ } \
180186 c != (u); \
181187 })
182188 #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
include/asm-s390/atomic.h+14−4
@@ -89,10 +89,15 @@ static __inline__ int atomic_cmpxchg(atomic_t *v, int old, int new) · 88 unmodified lines
8989 static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
9090 {
9191 int c, old;
92−
9392 c = atomic_read(v);
94− while (c != u && (old = atomic_cmpxchg(v, c, c + a)) != c)
93+ for (;;) {
94+ if (unlikely(c == u))
95+ break;
96+ old = atomic_cmpxchg(v, c, c + a);
97+ if (likely(old == c))
98+ break;
9599 c = old;
100+ }
96101 return c != u;
97102 }
98103
@@ -167,10 +172,15 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, · 68 unmodified lines
167172 long long a, long long u)
168173 {
169174 long long c, old;
170−
171175 c = atomic64_read(v);
172− while (c != u && (old = atomic64_cmpxchg(v, c, c + a)) != c)
176+ for (;;) {
177+ if (unlikely(c == u))
178+ break;
179+ old = atomic64_cmpxchg(v, c, c + a);
180+ if (likely(old == c))
181+ break;
173182 c = old;
183+ }
174184 return c != u;
175185 }
176186
include/asm-sparc64/atomic.h+8−2
@@ -78,9 +78,15 @@ extern int atomic64_sub_ret(int, atomic64_t *); · 77 unmodified lines
7878 ({ \
7979 int c, old; \
8080 c = atomic_read(v); \
81− while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
81+ for (;;) { \
82+ if (unlikely(c == (u))) \
83+ break; \
84+ old = atomic_cmpxchg((v), c, c + (a)); \
85+ if (likely(old == c)) \
86+ break; \
8287 c = old; \
83− c != (u); \
88+ } \
89+ likely(c != (u)); \
8490 })
8591 #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
8692
include/asm-x86_64/atomic.h+7−1
@@ -405,8 +405,14 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t *v) · 404 unmodified lines
405405 ({ \
406406 int c, old; \
407407 c = atomic_read(v); \
408− while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
408+ for (;;) { \
409+ if (unlikely(c == (u))) \
410+ break; \
411+ old = atomic_cmpxchg((v), c, c + (a)); \
412+ if (likely(old == c)) \
413+ break; \
409414 c = old; \
415+ } \
410416 c != (u); \
411417 })
412418 #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t