Two solid days of debugging.
Most of today was spent thinking over RCU until I realised when checking the thread-local list of release candidates, I can only delete thoses which are *two* or more generations older than the current generation count for the thread (which in turn has just been updated from the master RCU state). I was instead only checking that the release candidate generation was *smaller* than the current generation count for the thread.
After that, there was a memory leak – in the release candidate callback, I was omitting to free the release candidate structure itself.
So RCU and SMR stack unit tests now happy.
Going to check the patent for RCU and see if epoch based SMR avoids the claims.
Hope it does because then I won’t have to have RCU in a separate, LGPL, library (librcu); it instead will be part of liblfds proper.
Need to add atomic_swap() to the abstractions, both for RCU and for contigious double-word CAS singly linked list.