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