I'm writing an application with two threads: a UI thread and compute thread. I want them to share a vector of buffers with type T. Since it's 90% reading, I chose to go with an ArcSwap for synchronization. The memory layout I want to achieve is like so:
I want to use a type like ArcSwap<Arc<[T]>>
but the rust compiler is complaining that [T]
doesn't implement Sized
. This makes sense to me (since it's a slice), but why is it an compile error?
I've looked at the ArcSwap implementation and it seems like the atomic pointer needs to point to a Sized type, but why? (I've copied the definition below)
pub struct ArcSwapAny<T: RefCnt, S: LockStorage = Global> {
// Notes: AtomicPtr needs Sized
/// The actual pointer, extracted from the Arc.
ptr: AtomicPtr<T::Base>,
/// We are basically an Arc in disguise. Inherit parameters from Arc by pretending to contain
/// it.
_phantom_arc: PhantomData<T>,
lock_storage: S,
}
Is the way to achieve the memory layout ArcSwap<Arc<Box<[T]>>>
? That seems very clunky (and I'm worried about triple indirections). Additionally, why does ArcSwap[T; 100]
seem to work? What does being a Sized type mean in terms of memory?
For ArcSwap<T>
to work, it must be able to swap T
atomically. It is possible to swap a pointer atomically, but Arc<[T]>
is two pointers wide, and the standard library doesn't provide a cross-platform atomic for that.
Is the way to achieve the memory layout
ArcSwap<Arc<Box<[T]>>>
?
That indeed will be the easiest way.
What does being a Sized type mean in terms of memory?
Sized
denotes a type that has a size known at compile time. An array, as large as it gets, always has its size known at compile time. A slice not.