If, as in the OP, immortality is signaled by a special strong count, then it still needs to be read atomically to determine if it is immortal. This would be less contention than a rmw op, but it's still an atomic operation.
You do put the "is immortal" discriminant in a separate field, which permits checking it non-atomically. However, because you're using typestate to specify the mode, there's no benefit to unifying the types instead of having separate types, e.g. Arc<T>
and a "LeakedBox<T>
".
The proposed benefit of immortal arcs is giving them to code handling Arc<T>
and having that code perform closer to if it were handling &'static T
. If you're going to require editing the code to make it monomorphic anyway, just make it monomorphic over impl Deref<Target=T> + Clone
and just use &T
instead of Arc<T>
. There's no benefit to making the data representation polymorphic if the type representation is monomorphic.
LeakedBox pseudocode
unsafe trait SmartPtr: Deref {
fn into_raw(self) -> NonNull<T>;
unsafe fn from_raw(ptr: NonNull<T>) -> Self;
}
impl<T> SmartPtr for Box<T>, Arc<T>, Rc<T>;
struct Leaked<P: SmartPtr>(NonNull<T>, PhantomData<P>);
impl<P: SmartPtr> From<P> for Leaked<P>;
impl<P: SmartPtr> Copy + Clone for Leaked<P>;
unsafe impl<P: SmartPtr> Send for Leaked<P> where P: Send;
unsafe impl<P: SmartPtr> Send for Leaked<P> where P: Send;
impl<P: SmartPtr> Deref for Leaked<P> where P: Deref;
impl<P: SmartPtr> DerefMut for Leaked<P> where P: DerefMut;
impl<P: SmartPtr> Leaked<P> {
unsafe fn into_inner_unchecked(this: Self) -> P;
}
Dynamically thread-local reference counting is likely more impactful than immortal reference counts. (And immortal reference counts are likely more impactful with thread-local reference counts, since then you can skip the thread-local access.)
But that's all a much more involved thing than std's Arc
/Rc
. Them necessarily supporting weak references is already seen as "too much" by some (it's unnecessary overhead if you never use weak references); doing more certainly steps out of std's intended scope of providing the simple building block vocabulary.
Perhaps hybrid reference counting should be a preferred default, with non-hybrid being an optimization. But that's far from proven at this point, and the perfect domain for an external crate to provide. If you want to push for it to be "more available" than "some random crate," crossbeam would be a natural home for such a tool. Or just create a high quality implementation, show its benefits with real-world benchmarks, and offer PRs to projects using it and showing the real-world benefit.