proxygen
folly::threadlocal_detail::StaticMeta< Tag, AccessMode > Struct Template Referencefinal

#include <ThreadLocalDetail.h>

Inheritance diagram for folly::threadlocal_detail::StaticMeta< Tag, AccessMode >:
folly::threadlocal_detail::StaticMetaBase

Public Member Functions

 StaticMeta ()
 
 ~StaticMeta ()=delete
 
- Public Member Functions inherited from folly::threadlocal_detail::StaticMetaBase
 StaticMetaBase (ThreadEntry *(*threadEntry)(), bool strict)
 
void push_back (ThreadEntry *t)
 
void erase (ThreadEntry *t)
 
uint32_t elementsCapacity () const
 
uint32_t allocate (EntryID *ent)
 
void destroy (EntryID *ent)
 
void reserve (EntryID *id)
 
ElementWrappergetElement (EntryID *ent)
 
void reserveHeadUnlocked (uint32_t id)
 
void pushBackLocked (ThreadEntry *t, uint32_t id)
 
void pushBackUnlocked (ThreadEntry *t, uint32_t id)
 

Static Public Member Functions

static StaticMeta< Tag, AccessMode > & instance ()
 
FOLLY_EXPORT static FOLLY_ALWAYS_INLINE ElementWrapperget (EntryID *ent)
 
static FOLLY_NOINLINE void getSlowReserveAndCache (EntryID *ent, uint32_t &id, ThreadEntry *&threadEntry, size_t &capacity)
 
FOLLY_EXPORT static FOLLY_NOINLINE ThreadEntrygetThreadEntrySlow ()
 
static bool preFork ()
 
static void onForkParent ()
 
static void onForkChild ()
 
- Static Public Member Functions inherited from folly::threadlocal_detail::StaticMetaBase
static FOLLY_EXPORT ThreadEntryListgetThreadEntryList ()
 
static void onThreadExit (void *ptr)
 
static ElementWrapperreallocate (ThreadEntry *threadEntry, uint32_t idval, size_t &newCapacity)
 

Additional Inherited Members

- Public Attributes inherited from folly::threadlocal_detail::StaticMetaBase
uint32_t nextId_
 
std::vector< uint32_tfreeIds_
 
std::mutex lock_
 
SharedMutex accessAllThreadsLock_
 
pthread_key_t pthreadKey_
 
ThreadEntry head_
 
ThreadEntry *(* threadEntry_ )()
 
bool strict_
 
- Protected Member Functions inherited from folly::threadlocal_detail::StaticMetaBase
 ~StaticMetaBase ()
 

Detailed Description

template<class Tag, class AccessMode>
struct folly::threadlocal_detail::StaticMeta< Tag, AccessMode >

Definition at line 414 of file ThreadLocalDetail.h.

Constructor & Destructor Documentation

template<class Tag , class AccessMode >
folly::threadlocal_detail::StaticMeta< Tag, AccessMode >::StaticMeta ( )
inline

Definition at line 415 of file ThreadLocalDetail.h.

References folly::detail::AtFork::registerHandler().

416  : StaticMetaBase(
420  this,
421  /*prepare*/ &StaticMeta::preFork,
422  /*parent*/ &StaticMeta::onForkParent,
423  /*child*/ &StaticMeta::onForkChild);
424  }
FOLLY_EXPORT static FOLLY_NOINLINE ThreadEntry * getThreadEntrySlow()
StaticMetaBase(ThreadEntry *(*threadEntry)(), bool strict)
static const char *const value
Definition: Conv.cpp:50
static void registerHandler(void *object, folly::Function< bool()> prepare, folly::Function< void()> parent, folly::Function< void()> child)
Definition: AtFork.cpp:108
template<class Tag , class AccessMode >
folly::threadlocal_detail::StaticMeta< Tag, AccessMode >::~StaticMeta ( )
delete

Member Function Documentation

template<class Tag , class AccessMode >
FOLLY_EXPORT static FOLLY_ALWAYS_INLINE ElementWrapper& folly::threadlocal_detail::StaticMeta< Tag, AccessMode >::get ( EntryID ent)
inlinestatic

Definition at line 436 of file ThreadLocalDetail.h.

References FOLLY_UNLIKELY, and uint32_t.

436  {
437  // Eliminate as many branches and as much extra code as possible in the
438  // cached fast path, leaving only one branch here and one indirection below.
439  uint32_t id = ent->getOrInvalid();
440 #ifdef FOLLY_TLD_USE_FOLLY_TLS
441  static FOLLY_TLS ThreadEntry* threadEntry{};
442  static FOLLY_TLS size_t capacity{};
443 #else
444  ThreadEntry* threadEntry{};
445  size_t capacity{};
446 #endif
447  if (FOLLY_UNLIKELY(capacity <= id)) {
448  getSlowReserveAndCache(ent, id, threadEntry, capacity);
449  }
450  return threadEntry->elements[id];
451  }
static FOLLY_NOINLINE void getSlowReserveAndCache(EntryID *ent, uint32_t &id, ThreadEntry *&threadEntry, size_t &capacity)
#define FOLLY_UNLIKELY(x)
Definition: Likely.h:36
template<class Tag , class AccessMode >
static FOLLY_NOINLINE void folly::threadlocal_detail::StaticMeta< Tag, AccessMode >::getSlowReserveAndCache ( EntryID ent,
uint32_t id,
ThreadEntry *&  threadEntry,
size_t &  capacity 
)
inlinestatic

Definition at line 453 of file ThreadLocalDetail.h.

References folly::threadlocal_detail::ThreadEntry::getElementsCapacity(), folly::threadlocal_detail::StaticMetaBase::EntryID::getOrInvalid(), and UNLIKELY.

457  {
458  auto& inst = instance();
459  threadEntry = inst.threadEntry_();
460  if (UNLIKELY(threadEntry->getElementsCapacity() <= id)) {
461  inst.reserve(ent);
462  id = ent->getOrInvalid();
463  }
464  capacity = threadEntry->getElementsCapacity();
465  assert(capacity > id);
466  }
static StaticMeta< Tag, AccessMode > & instance()
#define UNLIKELY(x)
Definition: Likely.h:48
template<class Tag , class AccessMode >
FOLLY_EXPORT static FOLLY_NOINLINE ThreadEntry* folly::threadlocal_detail::StaticMeta< Tag, AccessMode >::getThreadEntrySlow ( )
inlinestatic

Definition at line 468 of file ThreadLocalDetail.h.

References folly::checkPosixError(), folly::threadlocal_detail::ThreadEntryList::count, folly::threadlocal_detail::ThreadEntryList::head, folly::threadlocal_detail::ThreadEntry::list, folly::threadlocal_detail::ThreadEntry::listNext, and folly::threadlocal_detail::ThreadEntry::meta.

468  {
469  auto& meta = instance();
470  auto key = meta.pthreadKey_;
471  ThreadEntry* threadEntry =
472  static_cast<ThreadEntry*>(pthread_getspecific(key));
473  if (!threadEntry) {
474  ThreadEntryList* threadEntryList = StaticMeta::getThreadEntryList();
475 #ifdef FOLLY_TLD_USE_FOLLY_TLS
476  static FOLLY_TLS ThreadEntry threadEntrySingleton;
477  threadEntry = &threadEntrySingleton;
478 #else
479  threadEntry = new ThreadEntry();
480 #endif
481  // if the ThreadEntry already exists
482  // but pthread_getspecific returns NULL
483  // do not add the same entry twice to the list
484  // since this would create a loop in the list
485  if (!threadEntry->list) {
486  threadEntry->list = threadEntryList;
487  threadEntry->listNext = threadEntryList->head;
488  threadEntryList->head = threadEntry;
489  }
490 
491  // if we're adding a thread entry
492  // we need to increment the list count
493  // even if the entry is reused
494  threadEntryList->count++;
495 
496  threadEntry->meta = &meta;
497  int ret = pthread_setspecific(key, threadEntry);
498  checkPosixError(ret, "pthread_setspecific failed");
499  }
500  return threadEntry;
501  }
static StaticMeta< Tag, AccessMode > & instance()
static FOLLY_EXPORT ThreadEntryList * getThreadEntryList()
void checkPosixError(int err, Args &&...args)
Definition: Exception.h:83
template<class Tag , class AccessMode >
static StaticMeta<Tag, AccessMode>& folly::threadlocal_detail::StaticMeta< Tag, AccessMode >::instance ( )
inlinestatic

Definition at line 428 of file ThreadLocalDetail.h.

Referenced by folly::SingletonVault::scheduleDestroyInstances().

428  {
429  // Leak it on exit, there's only one per process and we don't have to
430  // worry about synchronization with exiting threads.
431  /* library-local */ static auto instance =
432  detail::createGlobal<StaticMeta<Tag, AccessMode>, void>();
433  return *instance;
434  }
static StaticMeta< Tag, AccessMode > & instance()
template<class Tag , class AccessMode >
static void folly::threadlocal_detail::StaticMeta< Tag, AccessMode >::onForkChild ( )
inlinestatic

Definition at line 511 of file ThreadLocalDetail.h.

References folly::threadlocal_detail::ThreadEntry::elements, folly::threadlocal_detail::ThreadEntry::getElementsCapacity(), i, folly::threadlocal_detail::ThreadEntryNode::initIfZero(), folly::threadlocal_detail::ThreadEntryNode::initZero(), folly::threadlocal_detail::ElementWrapper::node, and folly::threadlocal_detail::ThreadEntryNode::zero().

511  {
512  // only the current thread survives
513  auto& head = instance().head_;
514  // init the head list
515  head.next = head.prev = &head;
516  // init the circular lists
517  auto elementsCapacity = head.getElementsCapacity();
518  for (size_t i = 0u; i < elementsCapacity; ++i) {
519  head.elements[i].node.init(&head, static_cast<uint32_t>(i));
520  }
521  // init the thread entry
522  ThreadEntry* threadEntry = instance().threadEntry_();
523  elementsCapacity = threadEntry->getElementsCapacity();
524  for (size_t i = 0u; i < elementsCapacity; ++i) {
525  if (!threadEntry->elements[i].node.zero()) {
526  threadEntry->elements[i].node.initZero(
527  threadEntry, static_cast<uint32_t>(i));
528  threadEntry->elements[i].node.initIfZero(false /*locked*/);
529  }
530  }
531 
532  // If this thread was in the list before the fork, add it back.
533  if (elementsCapacity != 0) {
534  instance().push_back(threadEntry);
535  }
536  instance().lock_.unlock();
537  }
static StaticMeta< Tag, AccessMode > & instance()
template<class Tag , class AccessMode >
static void folly::threadlocal_detail::StaticMeta< Tag, AccessMode >::onForkParent ( )
inlinestatic

Definition at line 507 of file ThreadLocalDetail.h.

507  {
508  instance().lock_.unlock();
509  }
static StaticMeta< Tag, AccessMode > & instance()
template<class Tag , class AccessMode >
static bool folly::threadlocal_detail::StaticMeta< Tag, AccessMode >::preFork ( )
inlinestatic

Definition at line 503 of file ThreadLocalDetail.h.

503  {
504  return instance().lock_.try_lock(); // Make sure it's created
505  }
static StaticMeta< Tag, AccessMode > & instance()

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