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;
}
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.