Struct regex_automata::util::pool::inner::Pool

source ·
pub(super) struct Pool<T, F> {
    create: F,
    stacks: Vec<CacheLine<Mutex<Vec<Box<T>>>>>,
    owner: AtomicUsize,
    owner_val: UnsafeCell<Option<T>>,
}
Expand description

A thread safe pool utilizing std-only features.

The main difference between this and the simplistic alloc-only pool is the use of std::sync::Mutex and an “owner thread” optimization that makes accesses by the owner of a pool faster than all other threads. This makes the common case of running a regex within a single thread faster by avoiding mutex unlocking.

Fields§

§create: F

A function to create more T values when stack is empty and a caller has requested a T.

§stacks: Vec<CacheLine<Mutex<Vec<Box<T>>>>>

Multiple stacks of T values to hand out. These are used when a Pool is accessed by a thread that didn’t create it.

Conceptually this is Mutex<Vec<Box<T>>>, but sharded out to make it scale better under high contention work-loads. We index into this sequence via thread_id % stacks.len().

§owner: AtomicUsize

The ID of the thread that owns this pool. The owner is the thread that makes the first call to ‘get’. When the owner calls ‘get’, it gets ‘owner_val’ directly instead of returning a T from ‘stack’. See comments elsewhere for details, but this is intended to be an optimization for the common case that makes getting a T faster.

It is initialized to a value of zero (an impossible thread ID) as a sentinel to indicate that it is unowned.

§owner_val: UnsafeCell<Option<T>>

A value to return when the caller is in the same thread that first called Pool::get.

This is set to None when a Pool is first created, and set to Some once the first thread calls Pool::get.

Implementations§

source§

impl<T, F> Pool<T, F>

source

pub(super) fn new(create: F) -> Pool<T, F>

Create a new pool. The given closure is used to create values in the pool when necessary.

source§

impl<T: Send, F: Fn() -> T> Pool<T, F>

source

pub(super) fn get(&self) -> PoolGuard<'_, T, F>

Get a value from the pool. This may block if another thread is also attempting to retrieve a value from the pool.

source

fn get_slow(&self, caller: usize, owner: usize) -> PoolGuard<'_, T, F>

This is the “slow” version that goes through a mutex to pop an allocated value off a stack to return to the caller. (Or, if the stack is empty, a new value is created.)

If the pool has no owner, then this will set the owner.

source

fn put_value(&self, value: Box<T>)

Puts a value back into the pool. Callers don’t need to call this. Once the guard that’s returned by ‘get’ is dropped, it is put back into the pool automatically.

source

fn guard_owned(&self, caller: usize) -> PoolGuard<'_, T, F>

Create a guard that represents the special owned T.

source

fn guard_stack(&self, value: Box<T>) -> PoolGuard<'_, T, F>

Create a guard that contains a value from the pool’s stack.

source

fn guard_stack_transient(&self, value: Box<T>) -> PoolGuard<'_, T, F>

Create a guard that contains a value from the pool’s stack with an instruction to throw away the value instead of putting it back into the pool.

Trait Implementations§

source§

impl<T: Debug, F> Debug for Pool<T, F>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T: UnwindSafe, F: UnwindSafe + RefUnwindSafe> RefUnwindSafe for Pool<T, F>

source§

impl<T: Send, F: Send + Sync> Sync for Pool<T, F>

source§

impl<T: UnwindSafe, F: UnwindSafe + RefUnwindSafe> UnwindSafe for Pool<T, F>

Auto Trait Implementations§

§

impl<T, F> !Freeze for Pool<T, F>

§

impl<T, F> Send for Pool<T, F>
where F: Send, T: Send,

§

impl<T, F> Unpin for Pool<T, F>
where F: Unpin, T: Unpin,

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>,

§

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>,

§

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.