MADNESS 0.10.1
thread_specific< Item > Class Template Reference

#include <thread_specific.h>

Classes

struct  Slot

Public Member Functions

 thread_specific (const thread_specific &)=delete
 thread_specific (Item init=Item())
 thread_specific (thread_specific &&)=delete
void clear ()
Item & local ()
thread_specific & operator= (const thread_specific &)=delete
thread_specific & operator= (thread_specific &&)=delete
std::size_t size () const

Private Member Functions

pthread_key_t & key ()
Item & local_slow (Slot *s)

Static Private Member Functions

static void pthread_key_deleter (const pthread_key_t *key_ptr)
static void slot_deleter (void *p)

Private Attributes

std::atomic< std::uint64_t > gen_
 bumped by clear()
Item init_
 seed for new items
std::map< std::thread::id, std::unique_ptr< Item > > items_
std::unique_ptr< pthread_key_t, decltype(&pthread_key_deleter)> key_ptr_
std::mutex mtx_
 guards items_

Detailed Description

template<typename Item>
class thread_specific< Item >

Thread-specific storage of one Item per touching thread that, unlike a thread_local, can be reclaimed on demand. The items are owned by this object — a std::map keyed on std::thread::id, guarded by a mutex, with a per-thread pthread_key caching the item pointer so the steady-state local() is lock-free (one pthread_getspecific plus a generation check). Because ownership lives in the object rather than in thread-static storage, destroying — or clear()ing — the pool frees every item at a defined point.

This matters for large scratch buffers: a plain thread_local pins its storage for the life of the OS thread (≈ the process), so under the TBB / PaRSEC task backends — whose arenas can touch more distinct threads than MAD_NUM_THREADS — it leaks one full item per touching thread with no way to reclaim it. Modeled on tbb::enumerable_thread_specific, trimmed to local()/clear().

Item must be copy-constructible; the seed passed to the constructor is copied to initialize each thread's instance. local() is safe to call concurrently from different threads. clear() is not safe to call concurrently with local() (or while any reference previously returned by local() is still in use); call it only at a quiescent point, e.g. after a fence.

Constructor & Destructor Documentation

◆ thread_specific() [1/3]

template<typename Item>
madness::detail::thread_specific< Item >::thread_specific ( Item init = Item())
inlineexplicit

◆ thread_specific() [2/3]

template<typename Item>
madness::detail::thread_specific< Item >::thread_specific ( const thread_specific< Item > & )
delete

◆ thread_specific() [3/3]

template<typename Item>
madness::detail::thread_specific< Item >::thread_specific ( thread_specific< Item > && )
delete

Member Function Documentation

◆ clear()

template<typename Item>
void madness::detail::thread_specific< Item >::clear ( )
inline

Free every thread's Item. A thread that later calls local() gets a freshly seeded one. Not safe to call concurrently with local(); see the class note.

◆ key()

template<typename Item>
pthread_key_t & madness::detail::thread_specific< Item >::key ( )
inlineprivate

◆ local()

template<typename Item>
Item & madness::detail::thread_specific< Item >::local ( )
inline
Returns
reference to the calling thread's Item, creating it on first use. Lock-free once the thread has been seen at the current generation.

◆ local_slow()

template<typename Item>
Item & madness::detail::thread_specific< Item >::local_slow ( Slot * s)
inlineprivate

◆ operator=() [1/2]

template<typename Item>
thread_specific & madness::detail::thread_specific< Item >::operator= ( const thread_specific< Item > & )
delete

◆ operator=() [2/2]

template<typename Item>
thread_specific & madness::detail::thread_specific< Item >::operator= ( thread_specific< Item > && )
delete

◆ pthread_key_deleter()

template<typename Item>
void madness::detail::thread_specific< Item >::pthread_key_deleter ( const pthread_key_t * key_ptr)
inlinestaticprivate

◆ size()

template<typename Item>
std::size_t madness::detail::thread_specific< Item >::size ( ) const
inline
Returns
number of live per-thread items (diagnostic; takes the lock).

◆ slot_deleter()

template<typename Item>
void madness::detail::thread_specific< Item >::slot_deleter ( void * p)
inlinestaticprivate

Member Data Documentation

◆ gen_

template<typename Item>
std::atomic<std::uint64_t> madness::detail::thread_specific< Item >::gen_
private

bumped by clear()

◆ init_

template<typename Item>
Item madness::detail::thread_specific< Item >::init_
private

seed for new items

◆ items_

template<typename Item>
std::map<std::thread::id, std::unique_ptr<Item> > madness::detail::thread_specific< Item >::items_
private

◆ key_ptr_

template<typename Item>
std::unique_ptr<pthread_key_t, decltype(&pthread_key_deleter)> madness::detail::thread_specific< Item >::key_ptr_
private

◆ mtx_

template<typename Item>
std::mutex madness::detail::thread_specific< Item >::mtx_
mutableprivate

guards items_


The documentation for this class was generated from the following file: