diff --git a/src/bvar/detail/agent_group.h b/src/bvar/detail/agent_group.h index 192ca88af8..8469897b72 100644 --- a/src/bvar/detail/agent_group.h +++ b/src/bvar/detail/agent_group.h @@ -113,10 +113,12 @@ class AgentGroup { // We need this function to be as fast as possible. inline static Agent* get_tls_agent(AgentId id) { if (__builtin_expect(id >= 0, 1)) { - if (_s_tls_blocks) { + std::vector* tls_blocks = + BAIDU_GET_VOLATILE_THREAD_LOCAL(_s_tls_blocks); + if (tls_blocks) { const size_t block_id = (size_t)id / ELEMENTS_PER_BLOCK; - if (block_id < _s_tls_blocks->size()) { - ThreadBlock* const tb = (*_s_tls_blocks)[block_id]; + if (block_id < tls_blocks->size()) { + ThreadBlock* const tb = (*tls_blocks)[block_id]; if (tb) { return tb->at(id - block_id * ELEMENTS_PER_BLOCK); } @@ -132,41 +134,46 @@ class AgentGroup { CHECK(false) << "Invalid id=" << id; return nullptr; } - if (_s_tls_blocks == nullptr) { - _s_tls_blocks = new (std::nothrow) std::vector; - if (__builtin_expect(_s_tls_blocks == nullptr, 0)) { + std::vector* tls_blocks = + BAIDU_GET_VOLATILE_THREAD_LOCAL(_s_tls_blocks); + if (tls_blocks == nullptr) { + tls_blocks = new (std::nothrow) std::vector; + if (__builtin_expect(tls_blocks == nullptr, 0)) { LOG(FATAL) << "Fail to create vector, " << berror(); return nullptr; } + BAIDU_SET_VOLATILE_THREAD_LOCAL(_s_tls_blocks, tls_blocks); butil::thread_atexit(_destroy_tls_blocks); } const size_t block_id = (size_t)id / ELEMENTS_PER_BLOCK; - if (block_id >= _s_tls_blocks->size()) { + if (block_id >= tls_blocks->size()) { // The 32ul avoid pointless small resizes. - _s_tls_blocks->resize(std::max(block_id + 1, 32ul)); + tls_blocks->resize(std::max(block_id + 1, 32ul)); } - ThreadBlock* tb = (*_s_tls_blocks)[block_id]; + ThreadBlock* tb = (*tls_blocks)[block_id]; if (tb == nullptr) { ThreadBlock *new_block = new (std::nothrow) ThreadBlock; if (__builtin_expect(new_block == nullptr, 0)) { return nullptr; } tb = new_block; - (*_s_tls_blocks)[block_id] = new_block; + (*tls_blocks)[block_id] = new_block; } return tb->at(id - block_id * ELEMENTS_PER_BLOCK); } private: static void _destroy_tls_blocks() { - if (!_s_tls_blocks) { + std::vector* tls_blocks = + BAIDU_GET_VOLATILE_THREAD_LOCAL(_s_tls_blocks); + if (!tls_blocks) { return; } - for (size_t i = 0; i < _s_tls_blocks->size(); ++i) { - delete (*_s_tls_blocks)[i]; + for (size_t i = 0; i < tls_blocks->size(); ++i) { + delete (*tls_blocks)[i]; } - delete _s_tls_blocks; - _s_tls_blocks = nullptr; + delete tls_blocks; + BAIDU_SET_VOLATILE_THREAD_LOCAL(_s_tls_blocks, nullptr); } inline static std::deque &_get_free_ids() { @@ -180,7 +187,8 @@ class AgentGroup { static pthread_mutex_t _s_mutex; static AgentId _s_agent_kinds; static std::deque *_s_free_ids; - static __thread std::vector *_s_tls_blocks; + STATIC_MEMBER_BAIDU_VOLATILE_THREAD_LOCAL( + std::vector*, _s_tls_blocks); }; template @@ -193,7 +201,7 @@ template AgentId AgentGroup::_s_agent_kinds = 0; template -__thread std::vector::ThreadBlock *> +BAIDU_THREAD_LOCAL std::vector::ThreadBlock *> *AgentGroup::_s_tls_blocks = nullptr; } // namespace detail