]> git.saurik.com Git - apple/libc.git/blob - threads/cthreads.h
c4fa284da01e7d930d752d67777792c03d26bc8a
[apple/libc.git] / threads / cthreads.h
1 /*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23 /*
24 * Cthreads.
25 */
26
27 #ifndef _CTHREADS_
28 #define _CTHREADS_ 1
29
30 #if defined(__cplusplus)
31 #define __DECLBEGIN extern "C" {
32 #define __DECLEND }
33 #else
34 #define __DECLBEGIN
35 #define __DECLEND
36 #endif
37
38 typedef void *any_t;
39
40 /*
41 * Spin locks.
42 */
43 __DECLBEGIN
44 extern void spin_unlock(int *p);
45 extern void spin_lock(int *p);
46 __DECLEND
47
48 #include <mach/mach_types.h>
49 #include <mach/boolean.h>
50
51 #ifndef MACRO_BEGIN
52
53 #define NEVER FALSE
54
55 #define MACRO_BEGIN do {
56 #define MACRO_END } while (NEVER)
57
58 #endif /* MACRO_BEGIN */
59
60 /*
61 * C Threads package initialization.
62 */
63 __DECLBEGIN
64 extern void cthread_init();
65 __DECLEND
66
67 #include <stdlib.h>
68
69 /*
70 * Queues.
71 */
72 typedef struct cthread_queue {
73 struct cthread_queue_item *head;
74 struct cthread_queue_item *tail;
75 } *cthread_queue_t;
76
77 typedef struct cthread_queue_item {
78 struct cthread_queue_item *next;
79 } *cthread_queue_item_t;
80
81 #define NO_QUEUE_ITEM ((cthread_queue_item_t) 0)
82
83 #define QUEUE_INITIALIZER { NO_QUEUE_ITEM, NO_QUEUE_ITEM }
84
85 #define cthread_queue_alloc() ((cthread_queue_t) calloc(1, sizeof(struct cthread_queue)))
86 #define cthread_queue_init(q) ((q)->head = (q)->tail = 0)
87 #define cthread_queue_free(q) free((any_t) (q))
88
89 #define cthread_queue_enq(q, x) \
90 MACRO_BEGIN \
91 (x)->next = 0; \
92 if ((q)->tail == 0) \
93 (q)->head = (cthread_queue_item_t) (x); \
94 else \
95 (q)->tail->next = (cthread_queue_item_t) (x); \
96 (q)->tail = (cthread_queue_item_t) (x); \
97 MACRO_END
98
99 #define cthread_queue_preq(q, x) \
100 MACRO_BEGIN \
101 if ((q)->tail == 0) \
102 (q)->tail = (cthread_queue_item_t) (x); \
103 ((cthread_queue_item_t) (x))->next = (q)->head; \
104 (q)->head = (cthread_queue_item_t) (x); \
105 MACRO_END
106
107 #define cthread_queue_head(q, t) ((t) ((q)->head))
108
109 #define cthread_queue_deq(q, t, x) \
110 MACRO_BEGIN \
111 if (((x) = (t) ((q)->head)) != 0 && \
112 ((q)->head = (cthread_queue_item_t) ((x)->next)) == 0) \
113 (q)->tail = 0; \
114 MACRO_END
115
116 #define cthread_queue_map(q, t, f) \
117 MACRO_BEGIN \
118 register cthread_queue_item_t x, next; \
119 for (x = (cthread_queue_item_t) ((q)->head); x != 0; x = next) { \
120 next = x->next; \
121 (*(f))((t) x); \
122 } \
123 MACRO_END
124
125
126 /*
127 * Mutex objects.
128 */
129 typedef struct mutex {
130 int lock;
131 char *name;
132 } *mutex_t;
133
134 #define MUTEX_INITIALIZER { 0, 0 }
135
136 #define mutex_alloc() ((mutex_t) calloc(1, sizeof(struct mutex)))
137 #define mutex_init(m) ((m)->lock = 0)
138 #define mutex_set_name(m, x) ((m)->name = (x))
139 #define mutex_name(m) ((m)->name != 0 ? (m)->name : "?")
140 #define mutex_clear(m) /* nop */
141 #define mutex_free(m) free((any_t) (m))
142
143 #define mutex_lock(m) \
144 MACRO_BEGIN \
145 if (! mutex_try_lock(m)) mutex_wait_lock(m); \
146 MACRO_END
147
148 __DECLBEGIN
149 extern int mutex_try_lock(mutex_t m); /* nonblocking */
150 extern void mutex_wait_lock(mutex_t m); /* blocking */
151 extern void mutex_unlock(mutex_t m);
152 __DECLEND
153
154 /*
155 * Condition variables.
156 */
157 typedef struct condition {
158 int lock;
159 struct cthread_queue queue;
160 char *name;
161 } *condition_t;
162
163 #define CONDITION_INITIALIZER { 0, QUEUE_INITIALIZER, 0 }
164
165 #define condition_alloc() ((condition_t) calloc(1, sizeof(struct condition)))
166 #define condition_init(c) MACRO_BEGIN (c)->lock = 0; cthread_queue_init(&(c)->queue); MACRO_END
167 #define condition_set_name(c, x) ((c)->name = (x))
168 #define condition_name(c) ((c)->name != 0 ? (c)->name : "?")
169 #define condition_clear(c) MACRO_BEGIN condition_broadcast(c); spin_lock(&(c)->lock); MACRO_END
170 #define condition_free(c) MACRO_BEGIN condition_clear(c); free((any_t) (c)); MACRO_END
171
172 #define condition_signal(c) \
173 MACRO_BEGIN \
174 if ((c)->queue.head) cond_signal(c); \
175 MACRO_END
176
177 #define condition_broadcast(c) \
178 MACRO_BEGIN \
179 if ((c)->queue.head) cond_broadcast(c); \
180 MACRO_END
181
182 __DECLBEGIN
183 extern void cond_signal(condition_t c);
184 extern void cond_broadcast(condition_t c);
185 extern void condition_wait(condition_t c, mutex_t m);
186 __DECLEND
187
188 /*
189 * Threads.
190 */
191
192 typedef any_t (*cthread_fn_t)(any_t arg);
193
194 #import <setjmp.h>
195
196 typedef struct cthread {
197 struct cthread *next;
198 thread_port_t real_thread;
199 struct mutex lock;
200 struct condition done;
201 int state;
202 #if defined(__cplusplus)
203 jmp_buf catchBuf;
204 #else
205 jmp_buf catch;
206 #endif
207 cthread_fn_t func;
208 any_t arg;
209 any_t result;
210 const char *name;
211 any_t data;
212 } *cthread_t;
213
214 #define NO_CTHREAD ((cthread_t) 0)
215
216 __DECLBEGIN
217 extern cthread_t cthread_fork(cthread_fn_t func, any_t arg);
218 extern void cthread_detach(cthread_t t);
219 extern any_t cthread_join(cthread_t t);
220 extern void cthread_yield(void);
221 extern void cthread_exit(any_t result);
222 extern kern_return_t cthread_priority(
223 cthread_t t,
224 int priority,
225 boolean_t set_max);
226 extern kern_return_t cthread_max_priority(
227 cthread_t t,
228 mach_port_t pset,
229 int max_priority);
230 extern kern_return_t cthread_abort(cthread_t t);
231 __DECLEND
232
233 /*
234 * This structure must agree with struct cproc in cthread_internals.h
235 */
236 typedef struct ur_cthread {
237 struct ur_cthread *next;
238 cthread_t incarnation;
239 } *ur_cthread_t;
240
241 __DECLBEGIN
242 extern int cthread_sp(void);
243
244 extern int cthread_stack_mask;
245
246 extern ur_cthread_t ur_cthread_self(void);
247 #define cthread_thread(c) (c->real_thread)
248 extern void cthread_set_errno_self(int e, int nocancel);
249 extern int cthread_errno(void);
250 #define cthread_assoc(id, t) (((ur_cthread_t) (id))->incarnation = (t))
251 #define cthread_self() (ur_cthread_self()->incarnation)
252
253 extern void cthread_set_name(cthread_t t, const char *name);
254 extern const char *cthread_name(cthread_t t);
255 extern int cthread_count(void);
256 extern void cthread_set_limit(int n);
257 extern int cthread_limit(void);
258 __DECLEND
259
260 #define cthread_set_data(t, x) ((t)->data = (x))
261 #define cthread_data(t) ((t)->data)
262
263 /*
264 * Spin locks.
265 */
266 #define spin_unlock(p) (*(p) = 0)
267
268 /*
269 * Mutex locks.
270 */
271 #define mutex_unlock(m) ((m)->lock = 0)
272
273
274 /*
275 * Debugging support.
276 */
277 #ifdef CTHREADS_DEBUG
278
279 #ifndef ASSERT
280 /*
281 * Assertion macro, similar to <assert.h>
282 */
283 #import <stdio.h>
284 #define ASSERT(p) \
285 MACRO_BEGIN \
286 if (!(p)) { \
287 fprintf(stderr, \
288 "File %s, line %d: assertion p failed.\n", \
289 __FILE__, __LINE__); \
290 abort(); \
291 } \
292 MACRO_END
293
294 #endif /* ASSERT */
295
296 #define SHOULDNT_HAPPEN 0
297
298 extern int cthread_debug;
299
300 #else /* CTHREADS_DEBUG */
301
302 #ifndef ASSERT
303 #define ASSERT(p)
304 #endif /* ASSERT */
305
306 #endif /* CTHREADS_DEBUG */
307
308 #endif /* _CTHREADS_ */