/*
******************************************************************************
*
-* Copyright (C) 2001-2012, International Business Machines
+* Copyright (C) 2001-2013, International Business Machines
* Corporation and others. All Rights Reserved.
*
******************************************************************************
*/
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
#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;
// 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)
// 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);
U_ASSERT(sysErr == 0);
}
+U_NAMESPACE_BEGIN
+
static pthread_mutex_t initMutex = PTHREAD_MUTEX_INITIALIZER;
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) {
}
}
-
+
// This function is called by the thread that ran an initialization function,
// just after completing the function.
// 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.
#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);
}
-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);
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);
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
//--------------------------------------------------------------------------
-// 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
#include <atomic>
+U_NAMESPACE_BEGIN
+
typedef std::atomic<int32_t> u_atomic_int32_t;
#define ATOMIC_INT32_T_INITIALIZER(val) ATOMIC_VAR_INIT(val)
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
# endif
# include <windows.h>
+U_NAMESPACE_BEGIN
typedef volatile LONG u_atomic_int32_t;
#define ATOMIC_INT32_T_INITIALIZER(val) val
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
inline int32_t umtx_atomic_dec(u_atomic_int32_t *p) {
return __sync_sub_and_fetch(p, 1);
}
+U_NAMESPACE_END
#else
#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 */
*
*************************************************************************************************/
+U_NAMESPACE_BEGIN
+
struct UInitOnce {
u_atomic_int32_t fState;
UErrorCode fErrCode;
#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) {
}
}
+U_NAMESPACE_END
typedef struct UMutex UMutex;
#define U_MUTEX_INITIALIZER {PTHREAD_MUTEX_INITIALIZER}
-
#else
/*
#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)