1f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/*
2f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)**********************************************************************
3f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   Copyright (C) 1997-2008, International Business Machines
4f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   Corporation and others.  All Rights Reserved.
5f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)**********************************************************************
6f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*
7f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* File UMUTEX.H
8f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*
9f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Modification History:
10f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*
11f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   Date        Name        Description
12f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   04/02/97  aliu        Creation.
13f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   04/07/99  srl         rewrite - C interface, multiple mutices
14f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   05/13/99  stephen     Changed to umutex (from cmutex)
15f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)******************************************************************************
16f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/
17f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
18f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#ifndef UMUTEX_H
19f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define UMUTEX_H
20f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
21f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/utypes.h"
22f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/uclean.h"
23f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
24f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
25f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* APP_NO_THREADS is an old symbol. We'll honour it if present. */
26f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#ifdef APP_NO_THREADS
27f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)# define ICU_USE_THREADS 0
28f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
29f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
30f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* ICU_USE_THREADS
31f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *
32f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *   Allows thread support (use of mutexes) to be compiled out of ICU.
33f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *   Default: use threads.
34f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *   Even with thread support compiled out, applications may override the
35f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *   (empty) mutex implementation with the u_setMutexFunctions() functions.
36f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
37f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#ifndef ICU_USE_THREADS
38f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)# define ICU_USE_THREADS 1
39f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
40f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
41f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
42f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * By default assume that we are on a machine with a weak memory model,
43f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * and the double check lock won't work reliably.
44f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
45f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if !defined(UMTX_STRONG_MEMORY_MODEL)
46f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define UMTX_STRONG_MEMORY_MODEL 0
47f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
48f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
49f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
50f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * \def UMTX_CHECK
51f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Encapsulates a safe check of an expression
52f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * for use with double-checked lazy inititialization.
53f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * On CPUs with weak memory models, this must use memory fence instructions
54f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * or mutexes.
55f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * The expression must involve only a  _single_ variable, typically
56f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *    a possibly null pointer or a boolean that indicates whether some service
57f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *    is initialized or not.
58f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * The setting of the variable involved in the test must be the last step of
59f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *    the initialization process.
60f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *
61f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *
62f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @internal
63f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
64f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if UMTX_STRONG_MEMORY_MODEL
65f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
66f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define UMTX_CHECK(pMutex, expression, result) \
67f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    (result)=(expression)
68f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
69f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#else
70f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
71f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define UMTX_CHECK(pMutex, expression, result) \
72f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    umtx_lock(pMutex); \
73f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    (result)=(expression); \
74f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    umtx_unlock(pMutex)
75f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
76f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
77f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
78f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/*
79f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Code within ICU that accesses shared static or global data should
80f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * instantiate a Mutex object while doing so.  The unnamed global mutex
81f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * is used throughout ICU, so keep locking short and sweet.
82f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *
83f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * For example:
84f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *
85f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * void Function(int arg1, int arg2)
86f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * {
87f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *   static Object* foo;     // Shared read-write object
88f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *   umtx_lock(NULL);        // Lock the ICU global mutex
89f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *   foo->Method();
90f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *   umtx_unlock(NULL);
91f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * }
92f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *
93f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * an alternative C++ mutex API is defined in the file common/mutex.h
94f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
95f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
96f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* Lock a mutex.
97f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param mutex The given mutex to be locked.  Pass NULL to specify
98f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *              the global ICU mutex.  Recursive locks are an error
99f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *              and may cause a deadlock on some platforms.
100f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
101f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CAPI void U_EXPORT2 umtx_lock   ( UMTX* mutex );
102f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
103f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* Unlock a mutex. Pass in NULL if you want the single global
104f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)   mutex.
105f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param mutex The given mutex to be unlocked.  Pass NULL to specify
106f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *              the global ICU mutex.
107f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
108f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CAPI void U_EXPORT2 umtx_unlock ( UMTX* mutex );
109f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
110f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* Initialize a mutex. Use it this way:
111f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)   umtx_init( &aMutex );
112f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * ICU Mutexes do not need explicit initialization before use.  Use of this
113f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *   function is not necessary.
114f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Initialization of an already initialized mutex has no effect, and is safe to do.
115f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Initialization of mutexes is thread safe.  Two threads can concurrently
116f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *   initialize the same mutex without causing problems.
117f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param mutex The given mutex to be initialized
118f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
119f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CAPI void U_EXPORT2 umtx_init   ( UMTX* mutex );
120f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
121f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* Destroy a mutex. This will free the resources of a mutex.
122f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Use it this way:
123f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *   umtx_destroy( &aMutex );
124f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Destroying an already destroyed mutex has no effect, and causes no problems.
125f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * This function is not thread safe.  Two threads must not attempt to concurrently
126f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *   destroy the same mutex.
127f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param mutex The given mutex to be destroyed.
128f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
129f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CAPI void U_EXPORT2 umtx_destroy( UMTX *mutex );
130f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
131f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
132f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
133f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/*
134f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Atomic Increment and Decrement of an int32_t value.
135f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *
136f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Return Values:
137f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *   If the result of the operation is zero, the return zero.
138f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *   If the result of the operation is not zero, the sign of returned value
139f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *      is the same as the sign of the result, but the returned value itself may
140f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *      be different from the result of the operation.
141f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
142f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CAPI int32_t U_EXPORT2 umtx_atomic_inc(int32_t *);
143f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CAPI int32_t U_EXPORT2 umtx_atomic_dec(int32_t *);
144f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
145f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
146f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif /*_CMUTEX*/
147f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/*eof*/
148f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
149f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
150f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
151