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
17 * Header file for mutex operations
30 #include <cma_semaphore_defs.h>
31 #include <cma_sequence.h>
32 #include <cma_tcb_defs.h>
33 #include <cma_stack.h>
36 * CONSTANTS AND MACROS
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 */
60 * FUNCTIONAL DESCRIPTION:
62 * Lock a mutex (internal)
66 * mutex Pointer to mutex object to lock
85 # define cma__int_lock(mutex) { \
86 if (cma__test_and_set (&((cma__t_int_mutex *)mutex)->lock)) { \
88 res = cma__int_mutex_block ((cma__t_int_mutex *)mutex); \
89 if (res != cma_s_normal) cma__error (res); \
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)) { \
98 res = cma__int_mutex_block ((cma__t_int_mutex *)mutex); \
99 if (res != cma_s_normal) cma__error (res); \
101 ((cma__t_int_mutex *)mutex)->owner = __ltcb__; \
106 * FUNCTIONAL DESCRIPTION:
108 * Unlock a mutex (internal)
112 * mutex Pointer to mutex object to unlock
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)) { \
135 res = cma__int_mutex_unblock ((cma__t_int_mutex *)mutex); \
136 if (res != cma_s_normal) cma__error (res); \
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) { \
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; \
149 cma__unset (((cma__t_int_mutex *)mutex)->unlock); \
150 if (!cma__test_and_set (&((cma__t_int_mutex *)mutex)->event)) { \
152 res = cma__int_mutex_unblock ((cma__t_int_mutex *)mutex); \
153 if (res != cma_s_normal) cma__error (res); \
159 * FUNCTIONAL DESCRIPTION:
161 * cma__int_mutex_delete - Performs work for cma_mutex_delete
165 * cma__t_mutex _mutex_ - Mutex to be deleted
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) \
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_); \
199 extern cma__t_sequence cma__g_mutex_seq
;
200 extern cma__t_int_mutex
*cma__g_global_lock
;
203 * INTERNAL INTERFACES
206 extern void cma__destroy_mutex (cma__t_int_mutex
*);
208 extern void cma__free_mutex (cma__t_int_mutex
*);
210 extern void cma__free_mutex_nolock (cma__t_int_mutex
*);
212 extern cma__t_int_mutex
* cma__get_first_mutex (cma__t_int_attr
*);
214 extern cma__t_int_mutex
* cma__get_mutex (cma__t_int_attr
*);
216 extern void cma__init_mutex (void);
218 extern cma_t_status
cma__int_mutex_block (cma__t_int_mutex
*);
220 extern cma_t_boolean
cma__int_mutex_locked (cma__t_int_mutex
*);
222 extern cma_t_boolean
cma__int_try_lock (cma__t_int_mutex
*);
224 extern cma_t_status
cma__int_mutex_unblock (cma__t_int_mutex
*);
226 extern cma_t_boolean
cma__mutex_locked (cma_t_mutex
);
228 extern void cma__reinit_mutex (cma_t_integer
);