From d3301f2a4e532ac43a813cef2f59e9f1d3fa1c0a Mon Sep 17 00:00:00 2001 From: Andy Heninger Date: Thu, 9 Apr 2015 23:16:55 +0000 Subject: [PATCH] ICU-11599 Adjust atomic ops code to be more compatible with thread sanitizer tools. X-SVN-Rev: 37326 --- icu4c/source/common/putilimp.h | 22 +++++++++++++++++++++- icu4c/source/common/umutex.cpp | 4 ++-- icu4c/source/common/umutex.h | 29 ++++++++++++++++++++++++++++- 3 files changed, 51 insertions(+), 4 deletions(-) diff --git a/icu4c/source/common/putilimp.h b/icu4c/source/common/putilimp.h index d2c1c66f17..d5b12afcd2 100644 --- a/icu4c/source/common/putilimp.h +++ b/icu4c/source/common/putilimp.h @@ -1,7 +1,7 @@ /* ****************************************************************************** * -* Copyright (C) 1997-2014, International Business Machines +* Copyright (C) 1997-2015, International Business Machines * Corporation and others. All Rights Reserved. * ****************************************************************************** @@ -229,6 +229,26 @@ typedef size_t uintptr_t; #endif +/** + * \def U_HAVE_CLANG_ATOMICS + * Defines whether Clang c11 style built-in atomics are avaialable. + * These are used in preference to gcc atomics when both are available. + */ +#ifdef U_HAVE_CLANG_ATOMICS + /* Use the predefined value. */ +#elif !defined(__clang__) +# define U_HAVE_CLANG_ATOMICS 0 +#else +#if __has_builtin(__c11_atomic_load) && \ + __has_builtin(__c11_atomic_store) && \ + __has_builtin(__c11_atomic_fetch_add) && \ + __has_builtin(__c11_atomic_fetch_sub) +# define U_HAVE_CLANG_ATOMICS 1 +#else +# define U_HAVE_CLANG_ATOMICS 0 +#endif +#endif + /*===========================================================================*/ /** @{ Code alignment */ /*===========================================================================*/ diff --git a/icu4c/source/common/umutex.cpp b/icu4c/source/common/umutex.cpp index dff0b47237..69eab79ff9 100644 --- a/icu4c/source/common/umutex.cpp +++ b/icu4c/source/common/umutex.cpp @@ -344,8 +344,8 @@ umtx_atomic_dec(u_atomic_int32_t *p) { U_COMMON_API int32_t U_EXPORT2 umtx_loadAcquire(u_atomic_int32_t &var) { - int32_t val = var; umtx_lock(&gIncDecMutex); + int32_t val = var; umtx_unlock(&gIncDecMutex); return val; } @@ -353,8 +353,8 @@ umtx_loadAcquire(u_atomic_int32_t &var) { U_COMMON_API void U_EXPORT2 umtx_storeRelease(u_atomic_int32_t &var, int32_t val) { umtx_lock(&gIncDecMutex); - umtx_unlock(&gIncDecMutex); var = val; + umtx_unlock(&gIncDecMutex); } U_NAMESPACE_END diff --git a/icu4c/source/common/umutex.h b/icu4c/source/common/umutex.h index e0ad0d3c03..0e4d118523 100644 --- a/icu4c/source/common/umutex.h +++ b/icu4c/source/common/umutex.h @@ -1,6 +1,6 @@ /* ********************************************************************** -* Copyright (C) 1997-2014, International Business Machines +* Copyright (C) 1997-2015, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** * @@ -118,6 +118,33 @@ inline int32_t umtx_atomic_dec(u_atomic_int32_t *var) { U_NAMESPACE_END +#elif U_HAVE_CLANG_ATOMICS +/* + * Clang __c11 atomic built-ins + */ + +U_NAMESPACE_BEGIN +typedef _Atomic(int32_t) u_atomic_int32_t; +#define ATOMIC_INT32_T_INITIALIZER(val) val + +inline int32_t umtx_loadAcquire(u_atomic_int32_t &var) { + return __c11_atomic_load(&var, __ATOMIC_ACQUIRE); +} + +inline void umtx_storeRelease(u_atomic_int32_t &var, int32_t val) { + return __c11_atomic_store(&var, val, __ATOMIC_RELEASE); +} + +inline int32_t umtx_atomic_inc(u_atomic_int32_t *var) { + return __c11_atomic_fetch_add(var, 1, __ATOMIC_SEQ_CST) + 1; +} + +inline int32_t umtx_atomic_dec(u_atomic_int32_t *var) { + return __c11_atomic_fetch_sub(var, 1, __ATOMIC_SEQ_CST) - 1; +} +U_NAMESPACE_END + + #elif U_HAVE_GCC_ATOMICS /* * gcc atomic ops. These are available on several other compilers as well.