From 547bb6a626ce0d77877d7ddbb18a9071dd8bb579 Mon Sep 17 00:00:00 2001 From: Lei Jin Date: Tue, 22 Apr 2014 21:13:34 -0700 Subject: [PATCH] simplify ThreadLocalPtr a little bit Summary: make singleton a static member instead of dynamic object. This should also avoid the race on unique_ptr Test Plan: make all check Reviewers: igor, haobo, sdong Reviewed By: igor CC: leveldb Differential Revision: https://reviews.facebook.net/D18177 --- util/thread_local.cc | 28 +++++++++++----------------- util/thread_local.h | 9 +++------ util/thread_local_test.cc | 2 +- 3 files changed, 15 insertions(+), 24 deletions(-) diff --git a/util/thread_local.cc b/util/thread_local.cc index 1b4220b8f..bc8a4c7d2 100644 --- a/util/thread_local.cc +++ b/util/thread_local.cc @@ -14,20 +14,14 @@ namespace rocksdb { -std::unique_ptr ThreadLocalPtr::StaticMeta::inst_; port::Mutex ThreadLocalPtr::StaticMeta::mutex_; #if !defined(OS_MACOSX) __thread ThreadLocalPtr::ThreadData* ThreadLocalPtr::StaticMeta::tls_ = nullptr; #endif -ThreadLocalPtr::StaticMeta* ThreadLocalPtr::StaticMeta::Instance() { - if (UNLIKELY(inst_ == nullptr)) { - MutexLock l(&mutex_); - if (inst_ == nullptr) { - inst_.reset(new StaticMeta()); - } - } - return inst_.get(); +ThreadLocalPtr::StaticMeta* ThreadLocalPtr::Instance() { + static ThreadLocalPtr::StaticMeta inst; + return &inst; } void ThreadLocalPtr::StaticMeta::OnThreadExit(void* ptr) { @@ -216,34 +210,34 @@ void ThreadLocalPtr::StaticMeta::ReclaimId(uint32_t id) { } ThreadLocalPtr::ThreadLocalPtr(UnrefHandler handler) - : id_(StaticMeta::Instance()->GetId()) { + : id_(Instance()->GetId()) { if (handler != nullptr) { - StaticMeta::Instance()->SetHandler(id_, handler); + Instance()->SetHandler(id_, handler); } } ThreadLocalPtr::~ThreadLocalPtr() { - StaticMeta::Instance()->ReclaimId(id_); + Instance()->ReclaimId(id_); } void* ThreadLocalPtr::Get() const { - return StaticMeta::Instance()->Get(id_); + return Instance()->Get(id_); } void ThreadLocalPtr::Reset(void* ptr) { - StaticMeta::Instance()->Reset(id_, ptr); + Instance()->Reset(id_, ptr); } void* ThreadLocalPtr::Swap(void* ptr) { - return StaticMeta::Instance()->Swap(id_, ptr); + return Instance()->Swap(id_, ptr); } bool ThreadLocalPtr::CompareAndSwap(void* ptr, void*& expected) { - return StaticMeta::Instance()->CompareAndSwap(id_, ptr, expected); + return Instance()->CompareAndSwap(id_, ptr, expected); } void ThreadLocalPtr::Scrape(autovector* ptrs, void* const replacement) { - StaticMeta::Instance()->Scrape(id_, ptrs, replacement); + Instance()->Scrape(id_, ptrs, replacement); } } // namespace rocksdb diff --git a/util/thread_local.h b/util/thread_local.h index a7728ed64..a037a9ceb 100644 --- a/util/thread_local.h +++ b/util/thread_local.h @@ -89,7 +89,7 @@ class ThreadLocalPtr { class StaticMeta { public: - static StaticMeta* Instance(); + StaticMeta(); // Return the next available Id uint32_t GetId(); @@ -117,8 +117,6 @@ class ThreadLocalPtr { void SetHandler(uint32_t id, UnrefHandler handler); private: - StaticMeta(); - // Get UnrefHandler for id with acquiring mutex // REQUIRES: mutex locked UnrefHandler GetHandler(uint32_t id); @@ -136,9 +134,6 @@ class ThreadLocalPtr { static ThreadData* GetThreadLocal(); - // Singleton instance - static std::unique_ptr inst_; - uint32_t next_instance_id_; // Used to recycle Ids in case ThreadLocalPtr is instantiated and destroyed // frequently. This also prevents it from blowing up the vector space. @@ -163,6 +158,8 @@ class ThreadLocalPtr { pthread_key_t pthread_key_; }; + static StaticMeta* Instance(); + const uint32_t id_; }; diff --git a/util/thread_local_test.cc b/util/thread_local_test.cc index d273947a8..70dfa956e 100644 --- a/util/thread_local_test.cc +++ b/util/thread_local_test.cc @@ -49,7 +49,7 @@ struct Params { class IDChecker : public ThreadLocalPtr { public: - static uint32_t PeekId() { return StaticMeta::Instance()->PeekId(); } + static uint32_t PeekId() { return Instance()->PeekId(); } }; } // anonymous namespace