A SwapArc is a data structure that allows for an Arc
to be passed around and swapped out with other Arcs.
In order to achieve this, an internal reference count
scheme is used which allows for very quick, low overhead
reads in the common case (no update) and will still be
decently fast when an update is performed. When a new
Arc is to be stored in the SwapArc, it first tries to
immediately update the current pointer (the one all strong readers will see in the uncontended case)
(this is possible, if no other update is being performed and if there are no strong readers left)
if this fails, it will try to do the same thing with the intermediate pointer
and if even that fails, it will push the update so that it will
be performed by the last intermediate reader to finish reading.
A strong read consists of loading the current pointer and
performing a clone operation on the Arc, thus
strong readers are very short-lived and can’t block
updates for very long.
A strong read in this case refers to the process of acquiring
the shared pointer which gets handled by the SwapArc
itself internally. Note that such a strong read isn’t what would
typically happen when load gets called as such a call
usually (in the case of no update) will only result
in a weak read and thus only
in a single Relaxed atomic load and a couple of
non-atomic bookkeeping operations utilizing TLS
to cache previous reads.
Note: SwapArc has wait-free reads.
SAFETY: Types implementing this trait are expected to perform
reference counting through cloning/dropping internally.
To be precise, the RefCnt is expected to increment
the reference count on clone calls, and decrement
it on drop.
NOTE: Drop is not required here as types such as
Option<Arc<T>> fulfill all the requirements without
needing special drop glue.