Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Will Deacon <will@kernel.org>
Link: https://lkml.kernel.org/r/YOMgPeMOmmiK3tXO@hirez.programming.kicks-ass.net

+41
+41
Documentation/atomic_t.txt
··· 271 271 SC *y, t; 272 272 273 273 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.