MADNESS 0.10.1
Classes | Public Member Functions | Private Member Functions | Static Private Member Functions | Private Attributes | List of all members
madness::detail::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 ()
 
Itemlocal ()
 
thread_specificoperator= (const thread_specific &)=delete
 
thread_specificoperator= (thread_specific &&)=delete
 
std::size_t size () const
 

Private Member Functions

pthread_key_tkey ()
 
Itemlocal_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 madness::detail::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.

References madness::detail::thread_specific< Item >::gen_, madness::detail::thread_specific< Item >::items_, and madness::detail::thread_specific< Item >::mtx_.

◆ 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.

References madness::detail::thread_specific< Item >::gen_, madness::detail::thread_specific< Item >::key(), madness::detail::thread_specific< Item >::local_slow(), and madness::nonlinear_vector_solver().

◆ local_slow()

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

◆ operator=() [1/2]

◆ operator=() [2/2]

◆ pthread_key_deleter()

template<typename Item >
static 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).

References madness::detail::thread_specific< Item >::items_, and madness::detail::thread_specific< Item >::mtx_.

◆ slot_deleter()

template<typename Item >
static 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

◆ init_

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

seed for new items

Referenced by madness::detail::thread_specific< Item >::local_slow().

◆ 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

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