mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-08 06:53:45 +00:00
ICU-10365 Mutex implementation, use ICU namespace where possible, cleans up urename.
X-SVN-Rev: 34209
This commit is contained in:
parent
7b3b75a525
commit
bb7e5684de
4 changed files with 52 additions and 26 deletions
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2001-2012, International Business Machines
|
||||
* Copyright (C) 2001-2013, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
******************************************************************************
|
||||
|
@ -86,7 +86,4 @@ U_CAPI void U_EXPORT2 ucln_registerCleanup(ECleanupLibraryType type,
|
|||
*/
|
||||
U_CAPI void U_EXPORT2 ucln_cleanupOne(ECleanupLibraryType type);
|
||||
|
||||
/* ucln_cmn.c variables shared with uinit.c */
|
||||
U_CFUNC UBool ucln_mutexedInit(initFunc *func, UErrorCode *status);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "cmemory.h"
|
||||
#include "ucln_cmn.h"
|
||||
|
||||
|
||||
// The ICU global mutex. Used when ICU implementation code passes NULL for the mutex pointer.
|
||||
static UMutex globalMutex = U_MUTEX_INITIALIZER;
|
||||
|
||||
|
@ -63,7 +64,9 @@ static UMutex globalMutex = U_MUTEX_INITIALIZER;
|
|||
// the caller needs to call the Init function.
|
||||
//
|
||||
|
||||
U_CAPI UBool U_EXPORT2 umtx_initImplPreInit(UInitOnce &uio) {
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
U_COMMON_API UBool U_EXPORT2 umtx_initImplPreInit(UInitOnce &uio) {
|
||||
for (;;) {
|
||||
int32_t previousState = InterlockedCompareExchange(
|
||||
#if (U_PLATFORM == U_PF_MINGW) || (U_PLATFORM == U_PF_CYGWIN)
|
||||
|
@ -100,10 +103,11 @@ U_CAPI UBool U_EXPORT2 umtx_initImplPreInit(UInitOnce &uio) {
|
|||
// False: the initializtion failed. The next call to umtx_initOnce()
|
||||
// will retry the initialization.
|
||||
|
||||
U_CAPI void U_EXPORT2 umtx_initImplPostInit(UInitOnce &uio) {
|
||||
U_COMMON_API void U_EXPORT2 umtx_initImplPostInit(UInitOnce &uio) {
|
||||
umtx_storeRelease(uio.fState, 2);
|
||||
}
|
||||
|
||||
U_NAMESAPCE_END
|
||||
|
||||
static void winMutexInit(CRITICAL_SECTION *cs) {
|
||||
InitializeCriticalSection(cs);
|
||||
|
@ -165,6 +169,8 @@ umtx_unlock(UMutex* mutex)
|
|||
U_ASSERT(sysErr == 0);
|
||||
}
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
static pthread_mutex_t initMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_cond_t initCondition = PTHREAD_COND_INITIALIZER;
|
||||
|
||||
|
@ -177,7 +183,8 @@ static pthread_cond_t initCondition = PTHREAD_COND_INITIALIZER;
|
|||
// that knows the C++ types involved. This function returns TRUE if
|
||||
// the caller needs to call the Init function.
|
||||
//
|
||||
UBool umtx_initImplPreInit(UInitOnce &uio) {
|
||||
U_COMMON_API UBool U_EXPORT2
|
||||
umtx_initImplPreInit(UInitOnce &uio) {
|
||||
pthread_mutex_lock(&initMutex);
|
||||
int32_t state = uio.fState;
|
||||
if (state == 0) {
|
||||
|
@ -196,7 +203,7 @@ UBool umtx_initImplPreInit(UInitOnce &uio) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// This function is called by the thread that ran an initialization function,
|
||||
// just after completing the function.
|
||||
|
@ -204,13 +211,16 @@ UBool umtx_initImplPreInit(UInitOnce &uio) {
|
|||
// Some threads may be racing to test the fState variable outside of the mutex,
|
||||
// requiring the use of store/release when changing its value.
|
||||
|
||||
void umtx_initImplPostInit(UInitOnce &uio) {
|
||||
U_COMMON_API void U_EXPORT2
|
||||
umtx_initImplPostInit(UInitOnce &uio) {
|
||||
pthread_mutex_lock(&initMutex);
|
||||
umtx_storeRelease(uio.fState, 2);
|
||||
pthread_cond_broadcast(&initCondition);
|
||||
pthread_mutex_unlock(&initMutex);
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
||||
// End of POSIX specific umutex implementation.
|
||||
|
||||
#else // Platform #define chain.
|
||||
|
@ -233,7 +243,9 @@ void umtx_initImplPostInit(UInitOnce &uio) {
|
|||
#if defined U_NO_PLATFORM_ATOMICS
|
||||
static UMutex gIncDecMutex = U_MUTEX_INITIALIZER;
|
||||
|
||||
U_INTERNAL int32_t U_EXPORT2
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
U_COMMON_API int32_t U_EXPORT2
|
||||
umtx_atomic_inc(u_atomic_int32_t *p) {
|
||||
int32_t retVal;
|
||||
umtx_lock(&gIncDecMutex);
|
||||
|
@ -243,7 +255,7 @@ umtx_atomic_inc(u_atomic_int32_t *p) {
|
|||
}
|
||||
|
||||
|
||||
U_INTERNAL int32_t U_EXPORT2
|
||||
U_COMMON_API int32_t U_EXPORT2
|
||||
umtx_atomic_dec(u_atomic_int32_t *p) {
|
||||
int32_t retVal;
|
||||
umtx_lock(&gIncDecMutex);
|
||||
|
@ -252,7 +264,7 @@ umtx_atomic_dec(u_atomic_int32_t *p) {
|
|||
return retVal;
|
||||
}
|
||||
|
||||
U_INTERNAL int32_t U_EXPORT2
|
||||
U_COMMON_API int32_t U_EXPORT2
|
||||
umtx_loadAcquire(u_atomic_int32_t &var) {
|
||||
int32_t val = var;
|
||||
umtx_lock(&gIncDecMutex);
|
||||
|
@ -260,13 +272,14 @@ umtx_loadAcquire(u_atomic_int32_t &var) {
|
|||
return val;
|
||||
}
|
||||
|
||||
U_INTERNAL void U_EXPORT2
|
||||
U_COMMON_API void U_EXPORT2
|
||||
umtx_storeRelease(u_atomic_int32_t &var, int32_t val) {
|
||||
umtx_lock(&gIncDecMutex);
|
||||
umtx_unlock(&gIncDecMutex);
|
||||
var = val;
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
|
|
@ -24,9 +24,13 @@
|
|||
|
||||
|
||||
|
||||
// Forward Declarations
|
||||
// Forward Declarations. UMutex is not in the ICU namespace (yet) because
|
||||
// there are some remaining references from plain C.
|
||||
struct UMutex;
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
struct UInitOnce;
|
||||
U_NAMESPACE_END
|
||||
|
||||
// Stringify macros, to allow #include of user supplied atomic & mutex files.
|
||||
#define U_MUTEX_STR(s) #s
|
||||
|
@ -47,6 +51,8 @@ struct UInitOnce;
|
|||
|
||||
#include <atomic>
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
typedef std::atomic<int32_t> u_atomic_int32_t;
|
||||
#define ATOMIC_INT32_T_INITIALIZER(val) ATOMIC_VAR_INIT(val)
|
||||
|
||||
|
@ -65,7 +71,7 @@ inline int32_t umtx_atomic_inc(u_atomic_int32_t *var) {
|
|||
inline int32_t umtx_atomic_dec(u_atomic_int32_t *var) {
|
||||
return var->fetch_sub(1) - 1;
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
||||
#elif U_PLATFORM_HAS_WIN32_API
|
||||
|
||||
|
@ -88,6 +94,7 @@ inline int32_t umtx_atomic_dec(u_atomic_int32_t *var) {
|
|||
# endif
|
||||
# include <windows.h>
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
typedef volatile LONG u_atomic_int32_t;
|
||||
#define ATOMIC_INT32_T_INITIALIZER(val) val
|
||||
|
||||
|
@ -107,12 +114,15 @@ inline int32_t umtx_atomic_inc(u_atomic_int32_t *var) {
|
|||
inline int32_t umtx_atomic_dec(u_atomic_int32_t *var) {
|
||||
return InterlockedDecrement(var);
|
||||
}
|
||||
U_NAMESPACE_END
|
||||
|
||||
|
||||
#elif U_HAVE_GCC_ATOMICS
|
||||
/*
|
||||
* gcc atomic ops. These are available on several other compilers as well.
|
||||
*/
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
typedef int32_t u_atomic_int32_t;
|
||||
#define ATOMIC_INT32_T_INITIALIZER(val) val
|
||||
|
||||
|
@ -134,6 +144,7 @@ inline int32_t umtx_atomic_inc(u_atomic_int32_t *p) {
|
|||
inline int32_t umtx_atomic_dec(u_atomic_int32_t *p) {
|
||||
return __sync_sub_and_fetch(p, 1);
|
||||
}
|
||||
U_NAMESPACE_END
|
||||
|
||||
#else
|
||||
|
||||
|
@ -144,16 +155,23 @@ inline int32_t umtx_atomic_dec(u_atomic_int32_t *p) {
|
|||
|
||||
#define U_NO_PLATFORM_ATOMICS
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
typedef int32_t u_atomic_int32_t;
|
||||
#define ATOMIC_INT32_T_INITIALIZER(val) val
|
||||
|
||||
U_INTERNAL int32_t U_EXPORT2 umtx_loadAcquire(u_atomic_int32_t &var);
|
||||
U_COMMON_API int32_t U_EXPORT2
|
||||
umtx_loadAcquire(u_atomic_int32_t &var);
|
||||
|
||||
U_INTERNAL void U_EXPORT2 umtx_storeRelease(u_atomic_int32_t &var, int32_t val);
|
||||
U_COMMON_API void U_EXPORT2
|
||||
umtx_storeRelease(u_atomic_int32_t &var, int32_t val);
|
||||
|
||||
U_INTERNAL int32_t U_EXPORT2 umtx_atomic_inc(u_atomic_int32_t *p);
|
||||
U_COMMON_API int32_t U_EXPORT2
|
||||
umtx_atomic_inc(u_atomic_int32_t *p);
|
||||
|
||||
U_INTERNAL int32_t U_EXPORT2 umtx_atomic_dec(u_atomic_int32_t *p);
|
||||
U_COMMON_API int32_t U_EXPORT2
|
||||
umtx_atomic_dec(u_atomic_int32_t *p);
|
||||
|
||||
U_NAMESAPCE_END
|
||||
|
||||
#endif /* Low Level Atomic Ops Platfrom Chain */
|
||||
|
||||
|
@ -166,6 +184,8 @@ U_INTERNAL int32_t U_EXPORT2 umtx_atomic_dec(u_atomic_int32_t *p);
|
|||
*
|
||||
*************************************************************************************************/
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
struct UInitOnce {
|
||||
u_atomic_int32_t fState;
|
||||
UErrorCode fErrCode;
|
||||
|
@ -178,8 +198,8 @@ struct UInitOnce {
|
|||
#define U_INITONCE_INITIALIZER {ATOMIC_INT32_T_INITIALIZER(0), U_ZERO_ERROR}
|
||||
|
||||
|
||||
U_CAPI UBool U_EXPORT2 umtx_initImplPreInit(UInitOnce &);
|
||||
U_CAPI void U_EXPORT2 umtx_initImplPostInit(UInitOnce &);
|
||||
U_COMMON_API UBool U_EXPORT2 umtx_initImplPreInit(UInitOnce &);
|
||||
U_COMMON_API void U_EXPORT2 umtx_initImplPostInit(UInitOnce &);
|
||||
|
||||
template<class T> void umtx_initOnce(UInitOnce &uio, T *obj, void (T::*fp)()) {
|
||||
if (umtx_loadAcquire(uio.fState) == 2) {
|
||||
|
@ -254,6 +274,7 @@ template<class T> void umtx_initOnce(UInitOnce &uio, void (*fp)(T, UErrorCode &)
|
|||
}
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
||||
|
||||
|
||||
|
@ -324,7 +345,6 @@ struct UMutex {
|
|||
typedef struct UMutex UMutex;
|
||||
#define U_MUTEX_INITIALIZER {PTHREAD_MUTEX_INITIALIZER}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
|
|
|
@ -1104,10 +1104,6 @@
|
|||
#define umsg_toPattern U_ICU_ENTRY_POINT_RENAME(umsg_toPattern)
|
||||
#define umsg_vformat U_ICU_ENTRY_POINT_RENAME(umsg_vformat)
|
||||
#define umsg_vparse U_ICU_ENTRY_POINT_RENAME(umsg_vparse)
|
||||
#define umtx_atomic_dec U_ICU_ENTRY_POINT_RENAME(umtx_atomic_dec)
|
||||
#define umtx_atomic_inc U_ICU_ENTRY_POINT_RENAME(umtx_atomic_inc)
|
||||
#define umtx_initImplPostInit U_ICU_ENTRY_POINT_RENAME(umtx_initImplPostInit)
|
||||
#define umtx_initImplPreInit U_ICU_ENTRY_POINT_RENAME(umtx_initImplPreInit)
|
||||
#define umtx_lock U_ICU_ENTRY_POINT_RENAME(umtx_lock)
|
||||
#define umtx_unlock U_ICU_ENTRY_POINT_RENAME(umtx_unlock)
|
||||
#define uniset_getUnicode32Instance U_ICU_ENTRY_POINT_RENAME(uniset_getUnicode32Instance)
|
||||
|
|
Loading…
Add table
Reference in a new issue