This converts radix to use SMR to allow for lockless traversal. This will rely on pages being type stable/NOFREE. The caller will have to verify the page after busying it. The caller is responsible for retrying, potentially with a lock, if the result is invalid or NULL.
This relies on ordering writes to tree updates so that the tree is always valid for a reader. Very few writes needed to be ordered. Before a new leaf is inserted the pointers within that leaf must be valid. Similarly on removal.
The lookup uses a smr section and atomic loads. Given the weak guarantees made to the caller some of the barriers may be overkill but should provide fewer false positives. Another option here is to have a single __always_inline lookup function that takes the load method as a parameter and is specialized for the locked/unlocked cases to reduce code duplication. I am open to suggestions.
I am going to let the SMR implementation settle in HEAD before I implement any consumers but I want to keep the patches moving. I need to solve one annoying startup issue that I hacked around with prealloc() for now.