diff --git a/src/butil/object_pool_inl.h b/src/butil/object_pool_inl.h index 20d4aea567..cc6b411c14 100644 --- a/src/butil/object_pool_inl.h +++ b/src/butil/object_pool_inl.h @@ -415,7 +415,7 @@ class BAIDU_CACHELINE_ALIGNMENT ObjectPool { } inline LocalPool* get_or_new_local_pool() { - LocalPool* lp = _local_pool; + LocalPool* lp = BAIDU_GET_VOLATILE_THREAD_LOCAL(_local_pool); if (BAIDU_LIKELY(lp != NULL)) { return lp; } @@ -424,7 +424,7 @@ class BAIDU_CACHELINE_ALIGNMENT ObjectPool { return NULL; } BAIDU_SCOPED_LOCK(_change_thread_mutex); //avoid race with clear() - _local_pool = lp; + BAIDU_SET_VOLATILE_THREAD_LOCAL(_local_pool, lp); butil::thread_atexit(LocalPool::delete_local_pool, lp); _nlocal.fetch_add(1, butil::memory_order_relaxed); return lp; @@ -523,7 +523,7 @@ class BAIDU_CACHELINE_ALIGNMENT ObjectPool { static butil::static_atomic _singleton; static pthread_mutex_t _singleton_mutex; - static BAIDU_THREAD_LOCAL LocalPool* _local_pool; + STATIC_MEMBER_BAIDU_VOLATILE_THREAD_LOCAL(LocalPool*, _local_pool); static butil::static_atomic _nlocal; static butil::static_atomic _ngroup; static pthread_mutex_t _block_group_mutex; diff --git a/src/butil/resource_pool_inl.h b/src/butil/resource_pool_inl.h index 4803b2f743..3274e9b771 100644 --- a/src/butil/resource_pool_inl.h +++ b/src/butil/resource_pool_inl.h @@ -419,7 +419,7 @@ class BAIDU_CACHELINE_ALIGNMENT ResourcePool { } inline LocalPool* get_or_new_local_pool() { - LocalPool* lp = _local_pool; + LocalPool* lp = BAIDU_GET_VOLATILE_THREAD_LOCAL(_local_pool); if (lp != NULL) { return lp; } @@ -428,7 +428,7 @@ class BAIDU_CACHELINE_ALIGNMENT ResourcePool { return NULL; } BAIDU_SCOPED_LOCK(_change_thread_mutex); //avoid race with clear() - _local_pool = lp; + BAIDU_SET_VOLATILE_THREAD_LOCAL(_local_pool, lp); butil::thread_atexit(LocalPool::delete_local_pool, lp); _nlocal.fetch_add(1, butil::memory_order_relaxed); return lp; @@ -524,7 +524,7 @@ class BAIDU_CACHELINE_ALIGNMENT ResourcePool { static butil::static_atomic _singleton; static pthread_mutex_t _singleton_mutex; - static BAIDU_THREAD_LOCAL LocalPool* _local_pool; + STATIC_MEMBER_BAIDU_VOLATILE_THREAD_LOCAL(LocalPool*, _local_pool); static butil::static_atomic _nlocal; static butil::static_atomic _ngroup; static pthread_mutex_t _block_group_mutex; diff --git a/src/butil/thread_local.h b/src/butil/thread_local.h index c33c7285f1..973ad14be7 100644 --- a/src/butil/thread_local.h +++ b/src/butil/thread_local.h @@ -46,6 +46,22 @@ var_name = v; \ } + #define STATIC_MEMBER_BAIDU_VOLATILE_THREAD_LOCAL(type, var_name) \ + static BAIDU_THREAD_LOCAL type var_name; \ + static __attribute__((noinline, unused)) type get_##var_name(void) { \ + asm volatile(""); \ + return var_name; \ + } \ + static __attribute__((noinline, unused)) type *get_ptr_##var_name(void) { \ + type *ptr = &var_name; \ + asm volatile("" : "+rm"(ptr)); \ + return ptr; \ + } \ + static __attribute__((noinline, unused)) void set_##var_name(type v) { \ + asm volatile(""); \ + var_name = v; \ + } + #if (defined (__aarch64__) && defined (__GNUC__)) || defined(__clang__) // GNU compiler under aarch and Clang compiler is incorrectly caching the // address of thread_local variables across a suspend-point. The following