1 /* 2 ********************************************************************** 3 * Copyright (C) 1997-2011, International Business Machines 4 * Corporation and others. All Rights Reserved. 5 ********************************************************************** 6 * 7 * File UMUTEX.H 8 * 9 * Modification History: 10 * 11 * Date Name Description 12 * 04/02/97 aliu Creation. 13 * 04/07/99 srl rewrite - C interface, multiple mutices 14 * 05/13/99 stephen Changed to umutex (from cmutex) 15 ****************************************************************************** 16 */ 17 18 #ifndef UMUTEX_H 19 #define UMUTEX_H 20 21 #include "unicode/utypes.h" 22 #include "unicode/uclean.h" 23 24 #if defined(U_WINDOWS) 25 # include <intrin.h> 26 #endif 27 28 #if defined(U_DARWIN) 29 #if defined(__STRICT_ANSI__) 30 #define UPRV_REMAP_INLINE 31 #define inline 32 #endif 33 #include <libkern/OSAtomic.h> 34 #define USE_MAC_OS_ATOMIC_INCREMENT 1 35 #if defined(UPRV_REMAP_INLINE) 36 #undef inline 37 #undef UPRV_REMAP_INLINE 38 #endif 39 #endif 40 41 /* 42 * If we do not compile with dynamic_annotations.h then define 43 * empty annotation macros. 44 * See http://code.google.com/p/data-race-test/wiki/DynamicAnnotations 45 */ 46 #ifndef ANNOTATE_HAPPENS_BEFORE 47 # define ANNOTATE_HAPPENS_BEFORE(obj) 48 # define ANNOTATE_HAPPENS_AFTER(obj) 49 # define ANNOTATE_UNPROTECTED_READ(x) (x) 50 #endif 51 52 /* APP_NO_THREADS is an old symbol. We'll honour it if present. */ 53 #ifdef APP_NO_THREADS 54 # define ICU_USE_THREADS 0 55 #endif 56 57 /* ICU_USE_THREADS 58 * 59 * Allows thread support (use of mutexes) to be compiled out of ICU. 60 * Default: use threads. 61 * Even with thread support compiled out, applications may override the 62 * (empty) mutex implementation with the u_setMutexFunctions() functions. 63 */ 64 #ifndef ICU_USE_THREADS 65 # define ICU_USE_THREADS 1 66 #endif 67 68 #ifndef UMTX_FULL_BARRIER 69 # if !ICU_USE_THREADS 70 # define UMTX_FULL_BARRIER 71 # elif U_HAVE_GCC_ATOMICS 72 # define UMTX_FULL_BARRIER __sync_synchronize(); 73 # elif defined(U_WINDOWS) 74 # define UMTX_FULL_BARRIER _ReadWriteBarrier(); 75 # elif defined(U_DARWIN) 76 # define UMTX_FULL_BARRIER OSMemoryBarrier(); 77 # else 78 # define UMTX_FULL_BARRIER \ 79 { \ 80 umtx_lock(NULL); \ 81 umtx_unlock(NULL); \ 82 } 83 # endif 84 #endif 85 86 #ifndef UMTX_ACQUIRE_BARRIER 87 # define UMTX_ACQUIRE_BARRIER UMTX_FULL_BARRIER 88 #endif 89 90 #ifndef UMTX_RELEASE_BARRIER 91 # define UMTX_RELEASE_BARRIER UMTX_FULL_BARRIER 92 #endif 93 94 /** 95 * \def UMTX_CHECK 96 * Encapsulates a safe check of an expression 97 * for use with double-checked lazy inititialization. 98 * Either memory barriers or mutexes are required, to prevent both the hardware 99 * and the compiler from reordering operations across the check. 100 * The expression must involve only a _single_ variable, typically 101 * a possibly null pointer or a boolean that indicates whether some service 102 * is initialized or not. 103 * The setting of the variable involved in the test must be the last step of 104 * the initialization process. 105 * 106 * @internal 107 */ 108 #define UMTX_CHECK(pMutex, expression, result) \ 109 { \ 110 (result)=(expression); \ 111 UMTX_ACQUIRE_BARRIER; \ 112 } 113 /* 114 * TODO: Replace all uses of UMTX_CHECK and surrounding code 115 * with SimpleSingleton or TriStateSingleton, and remove UMTX_CHECK. 116 */ 117 118 /* 119 * Code within ICU that accesses shared static or global data should 120 * instantiate a Mutex object while doing so. The unnamed global mutex 121 * is used throughout ICU, so keep locking short and sweet. 122 * 123 * For example: 124 * 125 * void Function(int arg1, int arg2) 126 * { 127 * static Object* foo; // Shared read-write object 128 * umtx_lock(NULL); // Lock the ICU global mutex 129 * foo->Method(); 130 * umtx_unlock(NULL); 131 * } 132 * 133 * an alternative C++ mutex API is defined in the file common/mutex.h 134 */ 135 136 /* Lock a mutex. 137 * @param mutex The given mutex to be locked. Pass NULL to specify 138 * the global ICU mutex. Recursive locks are an error 139 * and may cause a deadlock on some platforms. 140 */ 141 U_CAPI void U_EXPORT2 umtx_lock ( UMTX* mutex ); 142 143 /* Unlock a mutex. Pass in NULL if you want the single global 144 mutex. 145 * @param mutex The given mutex to be unlocked. Pass NULL to specify 146 * the global ICU mutex. 147 */ 148 U_CAPI void U_EXPORT2 umtx_unlock ( UMTX* mutex ); 149 150 /* Initialize a mutex. Use it this way: 151 umtx_init( &aMutex ); 152 * ICU Mutexes do not need explicit initialization before use. Use of this 153 * function is not necessary. 154 * Initialization of an already initialized mutex has no effect, and is safe to do. 155 * Initialization of mutexes is thread safe. Two threads can concurrently 156 * initialize the same mutex without causing problems. 157 * @param mutex The given mutex to be initialized 158 */ 159 U_CAPI void U_EXPORT2 umtx_init ( UMTX* mutex ); 160 161 /* Destroy a mutex. This will free the resources of a mutex. 162 * Use it this way: 163 * umtx_destroy( &aMutex ); 164 * Destroying an already destroyed mutex has no effect, and causes no problems. 165 * This function is not thread safe. Two threads must not attempt to concurrently 166 * destroy the same mutex. 167 * @param mutex The given mutex to be destroyed. 168 */ 169 U_CAPI void U_EXPORT2 umtx_destroy( UMTX *mutex ); 170 171 /* 172 * Atomic Increment and Decrement of an int32_t value. 173 * 174 * Return Values: 175 * If the result of the operation is zero, the return zero. 176 * If the result of the operation is not zero, the sign of returned value 177 * is the same as the sign of the result, but the returned value itself may 178 * be different from the result of the operation. 179 */ 180 U_CAPI int32_t U_EXPORT2 umtx_atomic_inc(int32_t *); 181 U_CAPI int32_t U_EXPORT2 umtx_atomic_dec(int32_t *); 182 183 #endif /*_CMUTEX*/ 184 /*eof*/ 185