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