View on GitHub

Base race condition#

make race
./race

Source: race.c

Naive Peterson implementation#

make peterson_naive
./peterson_naive

Source: peterson_naive.c

Reorderings#

make store_buffer_test
./store_buffer_test

Source: store_buffer_test.c

Try inserting atomic_thread_fence() and observe reorderings gone!

Peterson correct#

make peterson_atomic
./peterson_atomic

Source: peterson_atomic.c

Note that using atomic_int solves all problems:

  • provides atomic store-load behavior
  • prevents any kinds of reorderings around stores and loads

Compare timings:

make all
time ./race
time ./peterson_naive
time ./peterson_atomic

Atomic swap#

make atomic_swap
./atomic_swap

Source: atomic_swap.c

Atomic Test-And-Set#

make atomic_tas
./atomic_tas

Source: atomic_tas.c

Try blocking inside CS and see what happens with CPU:

make atomic_tas_pause
./atomic_tas_pause
top -H -p $(pidof atomic_tas_pause)

Semaphore#

make semaphore
./semaphore

Source: semaphore.c

make semaphore_pause
./semaphore_pause
top -H -p $(pidof semaphore_pause)

Futex mutex#

make futex
strace ./futex