]>
Commit | Line | Data |
---|---|---|
b75a7d8f A |
1 | /* |
2 | ********************************************************************** | |
4388f060 | 3 | * Copyright (C) 1997-2011, International Business Machines |
b75a7d8f A |
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" | |
4388f060 A |
22 | #include "unicode/uclean.h" |
23 | #include "putilimp.h" | |
b75a7d8f | 24 | |
4388f060 A |
25 | #if defined(_MSC_VER) && _MSC_VER >= 1500 |
26 | # include <intrin.h> | |
b75a7d8f A |
27 | #endif |
28 | ||
4388f060 A |
29 | #if U_PLATFORM_IS_DARWIN_BASED |
30 | #if defined(__STRICT_ANSI__) | |
31 | #define UPRV_REMAP_INLINE | |
32 | #define inline | |
33 | #endif | |
34 | #include <libkern/OSAtomic.h> | |
35 | #define USE_MAC_OS_ATOMIC_INCREMENT 1 | |
36 | #if defined(UPRV_REMAP_INLINE) | |
37 | #undef inline | |
38 | #undef UPRV_REMAP_INLINE | |
39 | #endif | |
b75a7d8f A |
40 | #endif |
41 | ||
4388f060 A |
42 | /* |
43 | * If we do not compile with dynamic_annotations.h then define | |
44 | * empty annotation macros. | |
45 | * See http://code.google.com/p/data-race-test/wiki/DynamicAnnotations | |
73c04bcf | 46 | */ |
4388f060 A |
47 | #ifndef ANNOTATE_HAPPENS_BEFORE |
48 | # define ANNOTATE_HAPPENS_BEFORE(obj) | |
49 | # define ANNOTATE_HAPPENS_AFTER(obj) | |
50 | # define ANNOTATE_UNPROTECTED_READ(x) (x) | |
51 | #endif | |
52 | ||
53 | #ifndef UMTX_FULL_BARRIER | |
54 | # if !ICU_USE_THREADS | |
55 | # define UMTX_FULL_BARRIER | |
56 | # elif U_HAVE_GCC_ATOMICS | |
57 | # define UMTX_FULL_BARRIER __sync_synchronize(); | |
58 | # elif defined(_MSC_VER) && _MSC_VER >= 1500 | |
59 | /* From MSVC intrin.h. Use _ReadWriteBarrier() only on MSVC 9 and higher. */ | |
60 | # define UMTX_FULL_BARRIER _ReadWriteBarrier(); | |
61 | # elif U_PLATFORM_IS_DARWIN_BASED | |
62 | # define UMTX_FULL_BARRIER OSMemoryBarrier(); | |
63 | # else | |
64 | # define UMTX_FULL_BARRIER \ | |
65 | { \ | |
66 | umtx_lock(NULL); \ | |
67 | umtx_unlock(NULL); \ | |
68 | } | |
69 | # endif | |
70 | #endif | |
71 | ||
72 | #ifndef UMTX_ACQUIRE_BARRIER | |
73 | # define UMTX_ACQUIRE_BARRIER UMTX_FULL_BARRIER | |
74 | #endif | |
75 | ||
76 | #ifndef UMTX_RELEASE_BARRIER | |
77 | # define UMTX_RELEASE_BARRIER UMTX_FULL_BARRIER | |
73c04bcf A |
78 | #endif |
79 | ||
374ca955 A |
80 | /** |
81 | * \def UMTX_CHECK | |
4388f060 | 82 | * Encapsulates a safe check of an expression |
729e4ab9 | 83 | * for use with double-checked lazy inititialization. |
4388f060 A |
84 | * Either memory barriers or mutexes are required, to prevent both the hardware |
85 | * and the compiler from reordering operations across the check. | |
729e4ab9 A |
86 | * The expression must involve only a _single_ variable, typically |
87 | * a possibly null pointer or a boolean that indicates whether some service | |
88 | * is initialized or not. | |
89 | * The setting of the variable involved in the test must be the last step of | |
90 | * the initialization process. | |
91 | * | |
374ca955 A |
92 | * @internal |
93 | */ | |
374ca955 | 94 | #define UMTX_CHECK(pMutex, expression, result) \ |
4388f060 A |
95 | { \ |
96 | (result)=(expression); \ | |
97 | UMTX_ACQUIRE_BARRIER; \ | |
98 | } | |
99 | /* | |
100 | * TODO: Replace all uses of UMTX_CHECK and surrounding code | |
101 | * with SimpleSingleton or TriStateSingleton, and remove UMTX_CHECK. | |
102 | */ | |
374ca955 | 103 | |
b75a7d8f | 104 | /* |
374ca955 A |
105 | * Code within ICU that accesses shared static or global data should |
106 | * instantiate a Mutex object while doing so. The unnamed global mutex | |
107 | * is used throughout ICU, so keep locking short and sweet. | |
b75a7d8f A |
108 | * |
109 | * For example: | |
110 | * | |
111 | * void Function(int arg1, int arg2) | |
112 | * { | |
374ca955 A |
113 | * static Object* foo; // Shared read-write object |
114 | * umtx_lock(NULL); // Lock the ICU global mutex | |
b75a7d8f | 115 | * foo->Method(); |
374ca955 | 116 | * umtx_unlock(NULL); |
b75a7d8f A |
117 | * } |
118 | * | |
374ca955 A |
119 | * an alternative C++ mutex API is defined in the file common/mutex.h |
120 | */ | |
b75a7d8f | 121 | |
4388f060 | 122 | /* Lock a mutex. |
374ca955 A |
123 | * @param mutex The given mutex to be locked. Pass NULL to specify |
124 | * the global ICU mutex. Recursive locks are an error | |
125 | * and may cause a deadlock on some platforms. | |
b75a7d8f A |
126 | */ |
127 | U_CAPI void U_EXPORT2 umtx_lock ( UMTX* mutex ); | |
128 | ||
129 | /* Unlock a mutex. Pass in NULL if you want the single global | |
130 | mutex. | |
374ca955 A |
131 | * @param mutex The given mutex to be unlocked. Pass NULL to specify |
132 | * the global ICU mutex. | |
b75a7d8f A |
133 | */ |
134 | U_CAPI void U_EXPORT2 umtx_unlock ( UMTX* mutex ); | |
135 | ||
136 | /* Initialize a mutex. Use it this way: | |
137 | umtx_init( &aMutex ); | |
374ca955 A |
138 | * ICU Mutexes do not need explicit initialization before use. Use of this |
139 | * function is not necessary. | |
140 | * Initialization of an already initialized mutex has no effect, and is safe to do. | |
141 | * Initialization of mutexes is thread safe. Two threads can concurrently | |
142 | * initialize the same mutex without causing problems. | |
b75a7d8f A |
143 | * @param mutex The given mutex to be initialized |
144 | */ | |
145 | U_CAPI void U_EXPORT2 umtx_init ( UMTX* mutex ); | |
146 | ||
147 | /* Destroy a mutex. This will free the resources of a mutex. | |
374ca955 A |
148 | * Use it this way: |
149 | * umtx_destroy( &aMutex ); | |
150 | * Destroying an already destroyed mutex has no effect, and causes no problems. | |
151 | * This function is not thread safe. Two threads must not attempt to concurrently | |
152 | * destroy the same mutex. | |
153 | * @param mutex The given mutex to be destroyed. | |
b75a7d8f A |
154 | */ |
155 | U_CAPI void U_EXPORT2 umtx_destroy( UMTX *mutex ); | |
156 | ||
b75a7d8f A |
157 | /* |
158 | * Atomic Increment and Decrement of an int32_t value. | |
159 | * | |
160 | * Return Values: | |
161 | * If the result of the operation is zero, the return zero. | |
162 | * If the result of the operation is not zero, the sign of returned value | |
163 | * is the same as the sign of the result, but the returned value itself may | |
164 | * be different from the result of the operation. | |
165 | */ | |
166 | U_CAPI int32_t U_EXPORT2 umtx_atomic_inc(int32_t *); | |
167 | U_CAPI int32_t U_EXPORT2 umtx_atomic_dec(int32_t *); | |
168 | ||
b75a7d8f A |
169 | #endif /*_CMUTEX*/ |
170 | /*eof*/ |