History

Documentation/atomic_t: Document cmpxchg() vs try_cmpxchg()

There seems to be a significant amount of confusion around the new try_cmpxchg(), despite this being more like the C11 atomic_compare_exchange_*() family. Add a few words of clarification on how cmpxchg() and try_cmpxchg() relate to one another.

Peter Zijlstra committed 5 years ago

Commit d1bbfd01 parent e6b44571 file · +41 −0Browse files

Unified · Split

Documentation/atomic_t.txt+41−0
@@ -271,3 +271,44 @@ WRITE_ONCE. Thus: · 270 unmodified lines
271271 SC *y, t;
272272
273273 is allowed.
274+
275+
276+CMPXCHG vs TRY_CMPXCHG
277+----------------------
278+
279+ int atomic_cmpxchg(atomic_t *ptr, int old, int new);
280+ bool atomic_try_cmpxchg(atomic_t *ptr, int *oldp, int new);
281+
282+Both provide the same functionality, but try_cmpxchg() can lead to more
283+compact code. The functions relate like:
284+
285+ bool atomic_try_cmpxchg(atomic_t *ptr, int *oldp, int new)
286+ {
287+ int ret, old = *oldp;
288+ ret = atomic_cmpxchg(ptr, old, new);
289+ if (ret != old)
290+ *oldp = ret;
291+ return ret == old;
292+ }
293+
294+and:
295+
296+ int atomic_cmpxchg(atomic_t *ptr, int old, int new)
297+ {
298+ (void)atomic_try_cmpxchg(ptr, &old, new);
299+ return old;
300+ }
301+
302+Usage:
303+
304+ old = atomic_read(&v); old = atomic_read(&v);
305+ for (;;) { do {
306+ new = func(old); new = func(old);
307+ tmp = atomic_cmpxchg(&v, old, new); } while (!atomic_try_cmpxchg(&v, &old, new));
308+ if (tmp == old)
309+ break;
310+ old = tmp;
311+ }
312+
313+NB. try_cmpxchg() also generates better code on some platforms (notably x86)
314+where the function more closely matches the hardware instruction.

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