Search code examples
clinux-kernelatomic

How is atomic_dec_if_positive atomic?


So I am reading atomic.h from Linux source code from here (found it on google. I am not sure if it's legit) and I just can't wrap my mind around this:

how is this atomic?

static inline int atomic_dec_if_positive(atomic_t *v)
{
  int c, old, dec;
  c = atomic_read(v);
  for (;;) {
    dec = c - 1;
    if (unlikely(dec < 0))
      break;
    old = atomic_cmpxchg((v), c, dec);
    if (likely(old == c))
      break;
    c = old;
  }
  return dec;
}

Solution

  • It uses the functions atomic_read() and atomic_cmpxchg(), which surely somewhere will be implemented in assembly language using atomicity features of the microprocessor's instruction set.

    It first reads a value and makes sure it is positive, stores the read value in c, the decremented value in dec and calls atomic_cmpxchg() which will atomically do the following: "write dec in *v only if the value in *v is equal to c, and return the old value in *v". That way you make sure that the value in *v was not changed between the two atomic calls. If it fails and the return value was different from the expected contents of *v, it retries the whole process.