X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2FThreadLocal.h;h=abc9b64af3ac4af2d0a4666035948622599b3aa3;hb=8d5c32ba92f8d4902b15bc5ba340a420a212ce73;hp=d3215f0db7835d3626020ee662c338baf303efc5;hpb=275ca94d04e44f28cfa411668eb1c1dd8db90b80;p=folly.git diff --git a/folly/ThreadLocal.h b/folly/ThreadLocal.h index d3215f0d..abc9b64a 100644 --- a/folly/ThreadLocal.h +++ b/folly/ThreadLocal.h @@ -1,5 +1,5 @@ /* - * Copyright 2015 Facebook, Inc. + * Copyright 2016 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,8 +34,7 @@ * @author Spencer Ahrens (sahrens) */ -#ifndef FOLLY_THREADLOCAL_H_ -#define FOLLY_THREADLOCAL_H_ +#pragma once #include #include @@ -59,7 +58,13 @@ template class ThreadLocalPtr; template class ThreadLocal { public: - ThreadLocal() { } + constexpr ThreadLocal() : constructor_([]() { + return new T(); + }) {} + + explicit ThreadLocal(std::function constructor) : + constructor_(constructor) { + } T* get() const { T* ptr = tlp_.get(); @@ -98,12 +103,13 @@ class ThreadLocal { ThreadLocal& operator=(const ThreadLocal&) = delete; T* makeTlp() const { - T* ptr = new T(); + auto ptr = constructor_(); tlp_.reset(ptr); return ptr; } mutable ThreadLocalPtr tlp_; + std::function constructor_; }; /* @@ -134,18 +140,19 @@ class ThreadLocal { template class ThreadLocalPtr { + private: + typedef threadlocal_detail::StaticMeta StaticMeta; public: - ThreadLocalPtr() : id_(threadlocal_detail::StaticMeta::create()) { } + constexpr ThreadLocalPtr() : id_() {} - ThreadLocalPtr(ThreadLocalPtr&& other) noexcept : id_(other.id_) { - other.id_ = 0; + ThreadLocalPtr(ThreadLocalPtr&& other) noexcept : + id_(std::move(other.id_)) { } ThreadLocalPtr& operator=(ThreadLocalPtr&& other) { assert(this != &other); destroy(); - id_ = other.id_; - other.id_ = 0; + id_ = std::move(other.id_); return *this; } @@ -154,7 +161,8 @@ class ThreadLocalPtr { } T* get() const { - return static_cast(threadlocal_detail::StaticMeta::get(id_).ptr); + threadlocal_detail::ElementWrapper& w = StaticMeta::instance().get(&id_); + return static_cast(w.ptr); } T* operator->() const { @@ -166,15 +174,14 @@ class ThreadLocalPtr { } T* release() { - threadlocal_detail::ElementWrapper& w = - threadlocal_detail::StaticMeta::get(id_); + threadlocal_detail::ElementWrapper& w = StaticMeta::instance().get(&id_); return static_cast(w.release()); } void reset(T* newPtr = nullptr) { - threadlocal_detail::ElementWrapper& w = - threadlocal_detail::StaticMeta::get(id_); + threadlocal_detail::ElementWrapper& w = StaticMeta::instance().get(&id_); + if (w.ptr != newPtr) { w.dispose(TLPDestructionMode::THIS_THREAD); w.set(newPtr); @@ -194,8 +201,7 @@ class ThreadLocalPtr { */ template void reset(T* newPtr, Deleter deleter) { - threadlocal_detail::ElementWrapper& w = - threadlocal_detail::StaticMeta::get(id_); + threadlocal_detail::ElementWrapper& w = StaticMeta::instance().get(&id_); if (w.ptr != newPtr) { w.dispose(TLPDestructionMode::THIS_THREAD); w.set(newPtr, deleter); @@ -208,7 +214,7 @@ class ThreadLocalPtr { class Accessor { friend class ThreadLocalPtr; - threadlocal_detail::StaticMeta& meta_; + threadlocal_detail::StaticMetaBase& meta_; std::mutex* lock_; uint32_t id_; @@ -223,7 +229,7 @@ class ThreadLocalPtr { boost::bidirectional_traversal_tag> { // traversal friend class Accessor; friend class boost::iterator_core_access; - const Accessor* const accessor_; + const Accessor* accessor_; threadlocal_detail::ThreadEntry* e_; void increment() { @@ -330,23 +336,19 @@ class ThreadLocalPtr { Accessor accessAllThreads() const { static_assert(!std::is_same::value, "Must use a unique Tag to use the accessAllThreads feature"); - return Accessor(id_); + return Accessor(id_.getOrAllocate(StaticMeta::instance())); } private: void destroy() { - if (id_) { - threadlocal_detail::StaticMeta::destroy(id_); - } + StaticMeta::instance().destroy(&id_); } // non-copyable ThreadLocalPtr(const ThreadLocalPtr&) = delete; ThreadLocalPtr& operator=(const ThreadLocalPtr&) = delete; - uint32_t id_; // every instantiation has a unique id + mutable typename StaticMeta::EntryID id_; }; } // namespace folly - -#endif /* FOLLY_THREADLOCAL_H_ */