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
55 cma_t_mutex_kind mutex_kind
; /* Kind of mutex */
56 cma__t_semaphore semaphore
; /* Semaphore for low-level wait */
61 * FUNCTIONAL DESCRIPTION:
63 * Lock a mutex (internal)
67 * mutex Pointer to mutex object to lock
86 # define cma__int_lock(mutex) { \
87 if (cma__test_and_set (&((cma__t_int_mutex *)mutex)->lock)) { \
89 res = cma__int_mutex_block ((cma__t_int_mutex *)mutex); \
90 if (res != cma_s_normal) cma__error (res); \
94 # define cma__int_lock(mutex) { \
95 cma__t_int_tcb *__ltcb__; \
96 __ltcb__ = cma__get_self_tcb (); \
97 if (cma__test_and_set (&((cma__t_int_mutex *)mutex)->lock)) { \
99 res = cma__int_mutex_block ((cma__t_int_mutex *)mutex); \
100 if (res != cma_s_normal) cma__error (res); \
102 ((cma__t_int_mutex *)mutex)->owner = __ltcb__; \
107 * FUNCTIONAL DESCRIPTION:
109 * Unlock a mutex (internal)
113 * mutex Pointer to mutex object to unlock
132 # define cma__int_unlock(mutex) { \
133 cma__unset (((cma__t_int_mutex *)mutex)->unlock); \
134 if (!cma__test_and_set (&((cma__t_int_mutex *)mutex)->event)) { \
136 res = cma__int_mutex_unblock ((cma__t_int_mutex *)mutex); \
137 if (res != cma_s_normal) cma__error (res); \
141 # define cma__int_unlock(mutex) { \
142 cma__t_int_tcb *__utcb__; \
143 __utcb__ = cma__get_self_tcb (); \
144 if (((cma__t_int_mutex *)mutex)->mutex_kind == cma_c_mutex_fast) { \
146 (__utcb__ == ((cma__t_int_mutex *)mutex)->owner), \
147 "attempt to release mutx owned by another thread"); \
148 ((cma__t_int_mutex *) mutex)->owner \
149 = (cma__t_int_tcb *)cma_c_null_ptr; \
151 cma__unset (((cma__t_int_mutex *)mutex)->unlock); \
152 if (!cma__test_and_set (&((cma__t_int_mutex *)mutex)->event)) { \
154 res = cma__int_mutex_unblock ((cma__t_int_mutex *)mutex); \
155 if (res != cma_s_normal) cma__error (res); \
161 * FUNCTIONAL DESCRIPTION:
163 * cma__int_mutex_delete - Performs work for cma_mutex_delete
167 * cma__t_mutex _mutex_ - Mutex to be deleted
185 #define cma__int_mutex_delete(_mutex_) { \
186 cma__t_int_mutex *_int_mutex_; \
187 _int_mutex_ = cma__validate_null_mutex (_mutex_); \
188 if (_int_mutex_ == (cma__t_int_mutex *)cma_c_null_ptr) \
190 if (cma__int_mutex_locked (_int_mutex_)) \
191 cma__error (cma_s_in_use); \
192 cma__free_mutex (_int_mutex_); \
193 cma__clear_handle (_mutex_); \
201 extern cma__t_sequence cma__g_mutex_seq
;
202 extern cma__t_int_mutex
*cma__g_global_lock
;
205 * INTERNAL INTERFACES
208 extern void cma__destroy_mutex (cma__t_int_mutex
*);
210 extern void cma__free_mutex (cma__t_int_mutex
*);
212 extern void cma__free_mutex_nolock (cma__t_int_mutex
*);
214 extern cma__t_int_mutex
* cma__get_first_mutex (cma__t_int_attr
*);
216 extern cma__t_int_mutex
* cma__get_mutex (cma__t_int_attr
*);
218 extern void cma__init_mutex (void);
220 extern cma_t_status
cma__int_mutex_block (cma__t_int_mutex
*);
222 extern cma_t_boolean
cma__int_mutex_locked (cma__t_int_mutex
*);
224 extern cma_t_boolean
cma__int_try_lock (cma__t_int_mutex
*);
226 extern cma_t_status
cma__int_mutex_unblock (cma__t_int_mutex
*);
228 extern cma_t_boolean
cma__mutex_locked (cma_t_mutex
);
230 extern void cma__reinit_mutex (cma_t_integer
);