• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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