Commit | Line | Data |
---|---|---|
c906108c SS |
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 | \f | |
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 | \f | |
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 | \f | |
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 |