If a thread reads the head but then sleeps for long enough that
another thread fills the ring and leaves the new head with the
expected value then the cmpset can pass when it should have failed.
To work around this keep the full head and tail value and use the
upper bits as a generation count.
Sponsored by: Arm Ltd