Estou escrevendo um aplicativo com dois threads: um UI thread e um compute thread. Quero que eles compartilhem um vetor de buffers com o tipo T. Como é 90% de leitura, escolhi usar um ArcSwap para sincronização. O layout de memória que quero atingir é assim:
Quero usar um tipo como ArcSwap<Arc<[T]>>
mas o compilador rust está reclamando que [T]
não implementa Sized
. Isso faz sentido para mim (já que é um slice), mas por que é um erro de compilação?
Eu olhei para a implementação do ArcSwap e parece que o ponteiro atômico precisa apontar para um tipo Sized, mas por quê? (Copiei a definição abaixo)
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,
}
É a maneira de atingir o layout de memória ArcSwap<Arc<Box<[T]>>>
? Isso parece muito desajeitado (e estou preocupado com indireções triplas). Além disso, por que parece ArcSwap[T; 100]
funcionar? O que significa ser um tipo Sized em termos de memória?
Para
ArcSwap<T>
funcionar, ele deve ser capaz de trocarT
atomicamente. É possível trocar um ponteiro atomicamente, masArc<[T]>
é de dois ponteiros de largura, e a biblioteca padrão não fornece um atomic multiplataforma para isso.Essa realmente será a maneira mais fácil.
Sized
denota um tipo que tem um tamanho conhecido em tempo de compilação. Um array, por maior que seja, sempre tem seu tamanho conhecido em tempo de compilação. Um slice não.