I'm working on a lockless algorithm that requires me to manipulate the address of an atomic pointer. In particular, I have an AtomicPtr
that can have a few values:
- if the pointer is null, it's a sentinel value for the end of a list.
- if the address segment of the pointer is odd, the pointer should be interpreted as an integer (i.e. never dereferenced).
- if the address segment of the pointer is even, it's a valid pointer to another element in the list.
The pointee structure has alignment greater than 2, so I believe this is all valid. In order to make this all work, I need a method to perform an atomic fetch-or operation on an AtomicPtr
(to mask in the lowest bit). There seem to be a few options:
AtomicPtr::fetch_or
seems like the best bet, but the problem is that it's gated by strict_provenance_atomic_ptr
, which is unlikely to be stabilized any time soon.
The other option would be to manipulate everything as an AtomicUsize
and then use its implementation of fetch_or
to make it all work, then cast the usize back as a pointer when I need it. I don't like this approach because it blows up when working with Miri or other strict-provenance tools.
Two questions:
- Are these the only two options?
- If so, is there something else I've missed that would make one better than the other?
I'm currently thinking that if I move forward with this, I'll make a custom wrapper for the two which compile-gates its underlying implementation based on whether strict provenance is enabled. Is there a better way to do that?