Am I misunderstanding the builtin CAS operators in gcc?
From the docs:
bool __sync_bool_compare_and_swap (type *ptr, type oldval type newval, ...)
type __sync_val_compare_and_swap (type *ptr, type oldval type newval, ...) These builtins perform an atomic compare and swap. That is, if the current value of *ptr is oldval, then write newval into *ptr.
The “bool” version returns true if the comparison is successful and newval was written. The “val” version returns the contents of *ptr before the operation.
But, yet, in my debugger:
atomic_cas (ax=0x5555555728b0 <__libc_csu_init>, checkval=0, newval=0) at atomic.c:18
18 int atomic_cas(int *ax, int checkval, int newval) {
(gdb) n
19 return __sync_bool_compare_and_swap(&ax, checkval, newval);
(gdb) p *ax
$1 = 0
(gdb) p checkval
$2 = 0
(gdb) p newval
$3 = 1
(gdb) p *ax == checkval
$4 = 1
(gdb) call atomic_cas(ax, checkval, newval)
$5 = 0
... and in fact:
(gdb) call atomic_cas(ax, 0, 1)
$6 = 0
(gdb) call atomic_cas(ax, 1, 0)
$7 = 0
(gdb) call atomic_cas(ax, 1, 1)
$8 = 0
What gives here? Is this a bug in gcc or am I doing something wrong?
(Notice: I'm aware the sync_*
are deprecated, please don't tell me how I should move to the newer atomics. I'm also aware that it's silly for this function call to exist - it's just a test.)