Struct vasi_sync::atomic_tls_map::AtomicTlsMap

source ·
pub struct AtomicTlsMap<const N: usize, V, H = BuildHasherDefault<FxHasher>>
where H: BuildHasher,
{ /* private fields */ }
Expand description

A lockless, no_std, no-alloc hash table.

Allows insertion and removal from an immutable reference, but does not support getting mutable references to internal values, and requires that a particular key is only ever accessed from the thread that inserted it, until that thread removes it.

Uses linear probing, and doesn’t support resizing. Lookup is Θ(1) (average case) if the key is present and the key hasn’t been forced far away from its “home” location, but is O(N) worst case. Lookup of a non-present key is always O(N); we need to scan the whole table.

This is designed mostly for use by shadow_shim::tls to help implement thread-local storage.

Implementations§

source§

impl<const N: usize, V, H> AtomicTlsMap<N, V, H>
where H: BuildHasher,

source

pub fn new_with_hasher(build_hasher: H) -> Self

source

pub unsafe fn get(&self, key: NonZeroUsize) -> Option<Ref<'_, V>>

§Safety

The value at key, if any, must have been inserted by the current thread.

source

pub unsafe fn get_or_insert_with( &self, key: NonZeroUsize, init: impl FnOnce() -> V, ) -> Ref<'_, V>

Retrieve the value associated with key, initializing it with init if key is not already present.

Panics if the table is full and key is not already present.

§Safety

There must not be a value at key that was inserted by a different thread.

source

pub unsafe fn remove(&self, key: NonZeroUsize) -> Option<V>

Removes the value still for key, if any. Panics if this thread has any outstanding references for key.

§Safety

The value at key, if any, must have been inserted by the current thread.

source

pub unsafe fn forget_all(&self)

Resets metadata in the map to mark all entries vacant, without dropping the values.

Intended for use after fork, after which entries belonging to other threads are not guaranteed to be in any consistent state (so can’t be dropped), but the threads owning those entries no longer exist in the child, so they can be safely overwritten.

§Safety

Any outstanding references from self (e.g. obtained via Self::get) must not be accessed or dropped again. e.g. references held by other threads before fork are OK, since those threads do not exist in the current process, and so will not access the child’s copy of this table. References that have been forgotten via core::mem::forget are also ok.

source§

impl<const N: usize, V, H> AtomicTlsMap<N, V, H>
where H: BuildHasher + Default,

source

pub fn new() -> Self

Trait Implementations§

source§

impl<const N: usize, V, H> Drop for AtomicTlsMap<N, V, H>
where H: BuildHasher,

source§

fn drop(&mut self)

Executes the destructor for this type. Read more
source§

impl<const N: usize, V, H> Sync for AtomicTlsMap<N, V, H>
where V: Send, H: Sync + BuildHasher,

Override default of UnsafeCell, Cell, and V not being Sync. We synchronize access to these (if partly by requiring users to guarantee no parallel access to a given key from multiple threads). Likewise V only needs to be Send.

Auto Trait Implementations§

§

impl<const N: usize, V, H = BuildHasherDefault<FxHasher>> !Freeze for AtomicTlsMap<N, V, H>

§

impl<const N: usize, V, H = BuildHasherDefault<FxHasher>> !RefUnwindSafe for AtomicTlsMap<N, V, H>

§

impl<const N: usize, V, H> Send for AtomicTlsMap<N, V, H>
where H: Send, V: Send,

§

impl<const N: usize, V, H> Unpin for AtomicTlsMap<N, V, H>
where H: Unpin, V: Unpin,

§

impl<const N: usize, V, H> UnwindSafe for AtomicTlsMap<N, V, H>
where H: UnwindSafe, V: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

source§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.