@ -14,7 +14,6 @@
namespace rocksdb {
port : : Mutex ThreadLocalPtr : : StaticMeta : : mutex_ ;
# if ROCKSDB_SUPPORT_THREAD_LOCAL
__thread ThreadLocalPtr : : ThreadData * ThreadLocalPtr : : StaticMeta : : tls_ = nullptr ;
# endif
@ -103,11 +102,33 @@ PIMAGE_TLS_CALLBACK p_thread_callback_on_exit = wintlscleanup::WinOnThreadExit;
# endif // OS_WIN
void ThreadLocalPtr : : InitSingletons ( ) {
ThreadLocalPtr : : StaticMeta : : InitSingletons ( ) ;
ThreadLocalPtr : : Instance ( ) ;
}
ThreadLocalPtr : : StaticMeta * ThreadLocalPtr : : Instance ( ) {
// Here we prefer function static variable instead of global
// static variable as function static variable is initialized
// when the function is first call. As a result, we can properly
// control their construction order by properly preparing their
// first function call.
static ThreadLocalPtr : : StaticMeta inst ;
return & inst ;
}
void ThreadLocalPtr : : StaticMeta : : InitSingletons ( ) { Mutex ( ) ; }
port : : Mutex * ThreadLocalPtr : : StaticMeta : : Mutex ( ) {
// Here we prefer function static variable instead of global
// static variable as function static variable is initialized
// when the function is first call. As a result, we can properly
// control their construction order by properly preparing their
// first function call.
static port : : Mutex mutex ;
return & mutex ;
}
void ThreadLocalPtr : : StaticMeta : : OnThreadExit ( void * ptr ) {
auto * tls = static_cast < ThreadData * > ( ptr ) ;
assert ( tls ! = nullptr ) ;
@ -115,7 +136,7 @@ void ThreadLocalPtr::StaticMeta::OnThreadExit(void* ptr) {
auto * inst = Instance ( ) ;
pthread_setspecific ( inst - > pthread_key_ , nullptr ) ;
MutexLock l ( & mutex_ ) ;
MutexLock l ( Mutex ( ) ) ;
inst - > RemoveThreadData ( tls ) ;
// Unref stored pointers of current thread from all instances
uint32_t id = 0 ;
@ -175,7 +196,7 @@ ThreadLocalPtr::StaticMeta::StaticMeta() : next_instance_id_(0) {
}
void ThreadLocalPtr : : StaticMeta : : AddThreadData ( ThreadLocalPtr : : ThreadData * d ) {
mutex_ . AssertHeld ( ) ;
Mutex ( ) - > AssertHeld ( ) ;
d - > next = & head_ ;
d - > prev = head_ . prev ;
head_ . prev - > next = d ;
@ -184,7 +205,7 @@ void ThreadLocalPtr::StaticMeta::AddThreadData(ThreadLocalPtr::ThreadData* d) {
void ThreadLocalPtr : : StaticMeta : : RemoveThreadData (
ThreadLocalPtr : : ThreadData * d ) {
mutex_ . AssertHeld ( ) ;
Mutex ( ) - > AssertHeld ( ) ;
d - > next - > prev = d - > prev ;
d - > prev - > next = d - > next ;
d - > next = d - > prev = d ;
@ -204,14 +225,14 @@ ThreadLocalPtr::ThreadData* ThreadLocalPtr::StaticMeta::GetThreadLocal() {
{
// Register it in the global chain, needs to be done before thread exit
// handler registration
MutexLock l ( & mutex_ ) ;
MutexLock l ( Mutex ( ) ) ;
inst - > AddThreadData ( tls_ ) ;
}
// Even it is not OS_MACOSX, need to register value for pthread_key_ so that
// its exit handler will be triggered.
if ( pthread_setspecific ( inst - > pthread_key_ , tls_ ) ! = 0 ) {
{
MutexLock l ( & mutex_ ) ;
MutexLock l ( Mutex ( ) ) ;
inst - > RemoveThreadData ( tls_ ) ;
}
delete tls_ ;
@ -233,7 +254,7 @@ void ThreadLocalPtr::StaticMeta::Reset(uint32_t id, void* ptr) {
auto * tls = GetThreadLocal ( ) ;
if ( UNLIKELY ( id > = tls - > entries . size ( ) ) ) {
// Need mutex to protect entries access within ReclaimId
MutexLock l ( & mutex_ ) ;
MutexLock l ( Mutex ( ) ) ;
tls - > entries . resize ( id + 1 ) ;
}
tls - > entries [ id ] . ptr . store ( ptr , std : : memory_order_release ) ;
@ -243,7 +264,7 @@ void* ThreadLocalPtr::StaticMeta::Swap(uint32_t id, void* ptr) {
auto * tls = GetThreadLocal ( ) ;
if ( UNLIKELY ( id > = tls - > entries . size ( ) ) ) {
// Need mutex to protect entries access within ReclaimId
MutexLock l ( & mutex_ ) ;
MutexLock l ( Mutex ( ) ) ;
tls - > entries . resize ( id + 1 ) ;
}
return tls - > entries [ id ] . ptr . exchange ( ptr , std : : memory_order_acquire ) ;
@ -254,7 +275,7 @@ bool ThreadLocalPtr::StaticMeta::CompareAndSwap(uint32_t id, void* ptr,
auto * tls = GetThreadLocal ( ) ;
if ( UNLIKELY ( id > = tls - > entries . size ( ) ) ) {
// Need mutex to protect entries access within ReclaimId
MutexLock l ( & mutex_ ) ;
MutexLock l ( Mutex ( ) ) ;
tls - > entries . resize ( id + 1 ) ;
}
return tls - > entries [ id ] . ptr . compare_exchange_strong (
@ -263,7 +284,7 @@ bool ThreadLocalPtr::StaticMeta::CompareAndSwap(uint32_t id, void* ptr,
void ThreadLocalPtr : : StaticMeta : : Scrape ( uint32_t id , autovector < void * > * ptrs ,
void * const replacement ) {
MutexLock l ( & mutex_ ) ;
MutexLock l ( Mutex ( ) ) ;
for ( ThreadData * t = head_ . next ; t ! = & head_ ; t = t - > next ) {
if ( id < t - > entries . size ( ) ) {
void * ptr =
@ -276,12 +297,12 @@ void ThreadLocalPtr::StaticMeta::Scrape(uint32_t id, autovector<void*>* ptrs,
}
void ThreadLocalPtr : : StaticMeta : : SetHandler ( uint32_t id , UnrefHandler handler ) {
MutexLock l ( & mutex_ ) ;
MutexLock l ( Mutex ( ) ) ;
handler_map_ [ id ] = handler ;
}
UnrefHandler ThreadLocalPtr : : StaticMeta : : GetHandler ( uint32_t id ) {
mutex_ . AssertHeld ( ) ;
Mutex ( ) - > AssertHeld ( ) ;
auto iter = handler_map_ . find ( id ) ;
if ( iter = = handler_map_ . end ( ) ) {
return nullptr ;
@ -290,7 +311,7 @@ UnrefHandler ThreadLocalPtr::StaticMeta::GetHandler(uint32_t id) {
}
uint32_t ThreadLocalPtr : : StaticMeta : : GetId ( ) {
MutexLock l ( & mutex_ ) ;
MutexLock l ( Mutex ( ) ) ;
if ( free_instance_ids_ . empty ( ) ) {
return next_instance_id_ + + ;
}
@ -301,7 +322,7 @@ uint32_t ThreadLocalPtr::StaticMeta::GetId() {
}
uint32_t ThreadLocalPtr : : StaticMeta : : PeekId ( ) const {
MutexLock l ( & mutex_ ) ;
MutexLock l ( Mutex ( ) ) ;
if ( ! free_instance_ids_ . empty ( ) ) {
return free_instance_ids_ . back ( ) ;
}
@ -311,7 +332,7 @@ uint32_t ThreadLocalPtr::StaticMeta::PeekId() const {
void ThreadLocalPtr : : StaticMeta : : ReclaimId ( uint32_t id ) {
// This id is not used, go through all thread local data and release
// corresponding value
MutexLock l ( & mutex_ ) ;
MutexLock l ( Mutex ( ) ) ;
auto unref = GetHandler ( id ) ;
for ( ThreadData * t = head_ . next ; t ! = & head_ ; t = t - > next ) {
if ( id < t - > entries . size ( ) ) {