ICU-10365 Mutex implementation, use ICU namespace where possible, cleans up urename.

X-SVN-Rev: 34209
This commit is contained in:
Andy Heninger 2013-09-06 01:41:14 +00:00
parent 7b3b75a525
commit bb7e5684de
4 changed files with 52 additions and 26 deletions

View file

@ -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

View file

@ -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
//--------------------------------------------------------------------------

View file

@ -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
/*

View file

@ -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)