|
MADNESS 0.10.1
|
#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_ | |
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.
|
inlineexplicit |
|
delete |
|
delete |
|
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_.
|
inlineprivate |
|
inline |
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().
|
inlineprivate |
References madness::detail::thread_specific< Item >::gen_, madness::detail::thread_specific< Item >::init_, madness::detail::thread_specific< Item >::items_, madness::detail::thread_specific< Item >::key(), madness::detail::thread_specific< Item >::mtx_, and madness::nonlinear_vector_solver().
Referenced by madness::detail::thread_specific< Item >::local().
|
delete |
|
delete |
|
inlinestaticprivate |
References madness::nonlinear_vector_solver().
|
inline |
References madness::detail::thread_specific< Item >::items_, and madness::detail::thread_specific< Item >::mtx_.
|
inlinestaticprivate |
References p().
Referenced by madness::detail::thread_specific< Item >::thread_specific().
|
private |
|
private |
seed for new items
Referenced by madness::detail::thread_specific< Item >::local_slow().
|
private |
|
private |
|
mutableprivate |