1*e93f7393Sniklas /* 2*e93f7393Sniklas * (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC. 3*e93f7393Sniklas * (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY 4*e93f7393Sniklas * (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION 5*e93f7393Sniklas * (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems 6*e93f7393Sniklas * To anyone who acknowledges that this file is provided "AS IS" without 7*e93f7393Sniklas * any express or implied warranty: permission to use, copy, modify, and 8*e93f7393Sniklas * distribute this file for any purpose is hereby granted without fee, 9*e93f7393Sniklas * provided that the above copyright notices and this notice appears in 10*e93f7393Sniklas * all source code copies, and that none of the names listed above be used 11*e93f7393Sniklas * in advertising or publicity pertaining to distribution of the software 12*e93f7393Sniklas * without specific, written prior permission. None of these organizations 13*e93f7393Sniklas * makes any representations about the suitability of this software for 14*e93f7393Sniklas * any purpose. 15*e93f7393Sniklas */ 16*e93f7393Sniklas /* 17*e93f7393Sniklas * Header file for mutex operations 18*e93f7393Sniklas */ 19*e93f7393Sniklas 20*e93f7393Sniklas #ifndef CMA_MUTEX 21*e93f7393Sniklas #define CMA_MUTEX 22*e93f7393Sniklas 23*e93f7393Sniklas /* 24*e93f7393Sniklas * INCLUDE FILES 25*e93f7393Sniklas */ 26*e93f7393Sniklas 27*e93f7393Sniklas #include <cma.h> 28*e93f7393Sniklas #include <cma_attr.h> 29*e93f7393Sniklas #include <cma_defs.h> 30*e93f7393Sniklas #include <cma_semaphore_defs.h> 31*e93f7393Sniklas #include <cma_sequence.h> 32*e93f7393Sniklas #include <cma_tcb_defs.h> 33*e93f7393Sniklas #include <cma_stack.h> 34*e93f7393Sniklas 35*e93f7393Sniklas /* 36*e93f7393Sniklas * CONSTANTS AND MACROS 37*e93f7393Sniklas */ 38*e93f7393Sniklas 39*e93f7393Sniklas /* 40*e93f7393Sniklas * TYPEDEFS 41*e93f7393Sniklas */ 42*e93f7393Sniklas 43*e93f7393Sniklas typedef struct CMA__T_INT_MUTEX { 44*e93f7393Sniklas cma__t_object header; /* Common header (sequence, type) */ 45*e93f7393Sniklas cma__t_int_attr *attributes; /* Back link */ 46*e93f7393Sniklas cma__t_int_tcb *owner; /* Current owner (if any) */ 47*e93f7393Sniklas cma_t_integer nest_count; /* Nesting level for recursive mutex */ 48*e93f7393Sniklas cma__t_atomic_bit *unlock; /* Pointer used for unlock operation */ 49*e93f7393Sniklas cma__t_atomic_bit lock; /* Set if currently locked */ 50*e93f7393Sniklas struct CMA__T_INT_MUTEX *int_lock; /* Internal protection for mutex */ 51*e93f7393Sniklas cma__t_atomic_bit event; /* Clear when unlock requires action */ 52*e93f7393Sniklas cma__t_atomic_bit waiters; /* Clear when threads are waiting */ 53*e93f7393Sniklas cma__t_atomic_bit bitbucket; /* Fake bit to keep friendlies locked */ 54*e93f7393Sniklas cma_t_mutex_kind mutex_kind; /* Kind of mutex */ 55*e93f7393Sniklas cma__t_semaphore semaphore; /* Semaphore for low-level wait */ 56*e93f7393Sniklas } cma__t_int_mutex; 57*e93f7393Sniklas 58*e93f7393Sniklas 59*e93f7393Sniklas /* 60*e93f7393Sniklas * FUNCTIONAL DESCRIPTION: 61*e93f7393Sniklas * 62*e93f7393Sniklas * Lock a mutex (internal) 63*e93f7393Sniklas * 64*e93f7393Sniklas * FORMAL PARAMETERS: 65*e93f7393Sniklas * 66*e93f7393Sniklas * mutex Pointer to mutex object to lock 67*e93f7393Sniklas * 68*e93f7393Sniklas * IMPLICIT INPUTS: 69*e93f7393Sniklas * 70*e93f7393Sniklas * none 71*e93f7393Sniklas * 72*e93f7393Sniklas * IMPLICIT OUTPUTS: 73*e93f7393Sniklas * 74*e93f7393Sniklas * none 75*e93f7393Sniklas * 76*e93f7393Sniklas * FUNCTION VALUE: 77*e93f7393Sniklas * 78*e93f7393Sniklas * none 79*e93f7393Sniklas * 80*e93f7393Sniklas * SIDE EFFECTS: 81*e93f7393Sniklas * 82*e93f7393Sniklas * none 83*e93f7393Sniklas */ 84*e93f7393Sniklas #ifdef NDEBUG 85*e93f7393Sniklas # define cma__int_lock(mutex) { \ 86*e93f7393Sniklas if (cma__test_and_set (&((cma__t_int_mutex *)mutex)->lock)) { \ 87*e93f7393Sniklas cma_t_status res;\ 88*e93f7393Sniklas res = cma__int_mutex_block ((cma__t_int_mutex *)mutex); \ 89*e93f7393Sniklas if (res != cma_s_normal) cma__error (res); \ 90*e93f7393Sniklas } \ 91*e93f7393Sniklas } 92*e93f7393Sniklas #else 93*e93f7393Sniklas # define cma__int_lock(mutex) { \ 94*e93f7393Sniklas cma__t_int_tcb *__ltcb__; \ 95*e93f7393Sniklas __ltcb__ = cma__get_self_tcb (); \ 96*e93f7393Sniklas if (cma__test_and_set (&((cma__t_int_mutex *)mutex)->lock)) { \ 97*e93f7393Sniklas cma_t_status res;\ 98*e93f7393Sniklas res = cma__int_mutex_block ((cma__t_int_mutex *)mutex); \ 99*e93f7393Sniklas if (res != cma_s_normal) cma__error (res); \ 100*e93f7393Sniklas } \ 101*e93f7393Sniklas ((cma__t_int_mutex *)mutex)->owner = __ltcb__; \ 102*e93f7393Sniklas } 103*e93f7393Sniklas #endif 104*e93f7393Sniklas 105*e93f7393Sniklas /* 106*e93f7393Sniklas * FUNCTIONAL DESCRIPTION: 107*e93f7393Sniklas * 108*e93f7393Sniklas * Unlock a mutex (internal) 109*e93f7393Sniklas * 110*e93f7393Sniklas * FORMAL PARAMETERS: 111*e93f7393Sniklas * 112*e93f7393Sniklas * mutex Pointer to mutex object to unlock 113*e93f7393Sniklas * 114*e93f7393Sniklas * IMPLICIT INPUTS: 115*e93f7393Sniklas * 116*e93f7393Sniklas * none 117*e93f7393Sniklas * 118*e93f7393Sniklas * IMPLICIT OUTPUTS: 119*e93f7393Sniklas * 120*e93f7393Sniklas * none 121*e93f7393Sniklas * 122*e93f7393Sniklas * FUNCTION VALUE: 123*e93f7393Sniklas * 124*e93f7393Sniklas * none 125*e93f7393Sniklas * 126*e93f7393Sniklas * SIDE EFFECTS: 127*e93f7393Sniklas * 128*e93f7393Sniklas * none 129*e93f7393Sniklas */ 130*e93f7393Sniklas #ifdef NDEBUG 131*e93f7393Sniklas # define cma__int_unlock(mutex) { \ 132*e93f7393Sniklas cma__unset (((cma__t_int_mutex *)mutex)->unlock); \ 133*e93f7393Sniklas if (!cma__test_and_set (&((cma__t_int_mutex *)mutex)->event)) { \ 134*e93f7393Sniklas cma_t_status res;\ 135*e93f7393Sniklas res = cma__int_mutex_unblock ((cma__t_int_mutex *)mutex); \ 136*e93f7393Sniklas if (res != cma_s_normal) cma__error (res); \ 137*e93f7393Sniklas } \ 138*e93f7393Sniklas } 139*e93f7393Sniklas #else 140*e93f7393Sniklas # define cma__int_unlock(mutex) { \ 141*e93f7393Sniklas cma__t_int_tcb *__utcb__; \ 142*e93f7393Sniklas __utcb__ = cma__get_self_tcb (); \ 143*e93f7393Sniklas if (((cma__t_int_mutex *)mutex)->mutex_kind == cma_c_mutex_fast) { \ 144*e93f7393Sniklas cma__assert_warn ( \ 145*e93f7393Sniklas (__utcb__ == ((cma__t_int_mutex *)mutex)->owner), \ 146*e93f7393Sniklas "attempt to release mutx owned by another thread"); \ 147*e93f7393Sniklas ((cma__t_int_mutex *)mutex)->owner = (cma__t_int_tcb *)cma_c_null_ptr; \ 148*e93f7393Sniklas } \ 149*e93f7393Sniklas cma__unset (((cma__t_int_mutex *)mutex)->unlock); \ 150*e93f7393Sniklas if (!cma__test_and_set (&((cma__t_int_mutex *)mutex)->event)) { \ 151*e93f7393Sniklas cma_t_status res;\ 152*e93f7393Sniklas res = cma__int_mutex_unblock ((cma__t_int_mutex *)mutex); \ 153*e93f7393Sniklas if (res != cma_s_normal) cma__error (res); \ 154*e93f7393Sniklas } \ 155*e93f7393Sniklas } 156*e93f7393Sniklas #endif 157*e93f7393Sniklas 158*e93f7393Sniklas /* 159*e93f7393Sniklas * FUNCTIONAL DESCRIPTION: 160*e93f7393Sniklas * 161*e93f7393Sniklas * cma__int_mutex_delete - Performs work for cma_mutex_delete 162*e93f7393Sniklas * 163*e93f7393Sniklas * FORMAL PARAMETERS: 164*e93f7393Sniklas * 165*e93f7393Sniklas * cma__t_mutex _mutex_ - Mutex to be deleted 166*e93f7393Sniklas * 167*e93f7393Sniklas * IMPLICIT INPUTS: 168*e93f7393Sniklas * 169*e93f7393Sniklas * none 170*e93f7393Sniklas * 171*e93f7393Sniklas * IMPLICIT OUTPUTS: 172*e93f7393Sniklas * 173*e93f7393Sniklas * none 174*e93f7393Sniklas * 175*e93f7393Sniklas * FUNCTION VALUE: 176*e93f7393Sniklas * 177*e93f7393Sniklas * none 178*e93f7393Sniklas * 179*e93f7393Sniklas * SIDE EFFECTS: 180*e93f7393Sniklas * 181*e93f7393Sniklas * none 182*e93f7393Sniklas */ 183*e93f7393Sniklas #define cma__int_mutex_delete(_mutex_) { \ 184*e93f7393Sniklas cma__t_int_mutex *_int_mutex_; \ 185*e93f7393Sniklas _int_mutex_ = cma__validate_null_mutex (_mutex_); \ 186*e93f7393Sniklas if (_int_mutex_ == (cma__t_int_mutex *)cma_c_null_ptr) \ 187*e93f7393Sniklas return; \ 188*e93f7393Sniklas if (cma__int_mutex_locked (_int_mutex_)) \ 189*e93f7393Sniklas cma__error (cma_s_in_use); \ 190*e93f7393Sniklas cma__free_mutex (_int_mutex_); \ 191*e93f7393Sniklas cma__clear_handle (_mutex_); \ 192*e93f7393Sniklas } 193*e93f7393Sniklas 194*e93f7393Sniklas 195*e93f7393Sniklas /* 196*e93f7393Sniklas * GLOBAL DATA 197*e93f7393Sniklas */ 198*e93f7393Sniklas 199*e93f7393Sniklas extern cma__t_sequence cma__g_mutex_seq; 200*e93f7393Sniklas extern cma__t_int_mutex *cma__g_global_lock; 201*e93f7393Sniklas 202*e93f7393Sniklas /* 203*e93f7393Sniklas * INTERNAL INTERFACES 204*e93f7393Sniklas */ 205*e93f7393Sniklas 206*e93f7393Sniklas extern void cma__destroy_mutex (cma__t_int_mutex *); 207*e93f7393Sniklas 208*e93f7393Sniklas extern void cma__free_mutex (cma__t_int_mutex *); 209*e93f7393Sniklas 210*e93f7393Sniklas extern void cma__free_mutex_nolock (cma__t_int_mutex *); 211*e93f7393Sniklas 212*e93f7393Sniklas extern cma__t_int_mutex * cma__get_first_mutex (cma__t_int_attr *); 213*e93f7393Sniklas 214*e93f7393Sniklas extern cma__t_int_mutex * cma__get_mutex (cma__t_int_attr *); 215*e93f7393Sniklas 216*e93f7393Sniklas extern void cma__init_mutex (void); 217*e93f7393Sniklas 218*e93f7393Sniklas extern cma_t_status cma__int_mutex_block (cma__t_int_mutex *); 219*e93f7393Sniklas 220*e93f7393Sniklas extern cma_t_boolean cma__int_mutex_locked (cma__t_int_mutex *); 221*e93f7393Sniklas 222*e93f7393Sniklas extern cma_t_boolean cma__int_try_lock (cma__t_int_mutex *); 223*e93f7393Sniklas 224*e93f7393Sniklas extern cma_t_status cma__int_mutex_unblock (cma__t_int_mutex *); 225*e93f7393Sniklas 226*e93f7393Sniklas extern cma_t_boolean cma__mutex_locked (cma_t_mutex); 227*e93f7393Sniklas 228*e93f7393Sniklas extern void cma__reinit_mutex (cma_t_integer); 229*e93f7393Sniklas 230*e93f7393Sniklas #endif 231