]> git.saurik.com Git - apple/icu.git/blame - icuSources/common/umutex.h
ICU-491.11.1.tar.gz
[apple/icu.git] / icuSources / common / umutex.h
CommitLineData
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 */
127U_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 */
134U_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 */
145U_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 */
155U_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 */
166U_CAPI int32_t U_EXPORT2 umtx_atomic_inc(int32_t *);
167U_CAPI int32_t U_EXPORT2 umtx_atomic_dec(int32_t *);
168
b75a7d8f
A
169#endif /*_CMUTEX*/
170/*eof*/