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
271 SC *y, t;271 SC *y, t;
272 272
273is allowed.273is allowed.
274
275
276CMPXCHG 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
282Both provide the same functionality, but try_cmpxchg() can lead to more
283compact 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
294and:
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
302Usage:
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
313NB. try_cmpxchg() also generates better code on some platforms (notably x86)
314where 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