2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
30 #if defined(__cplusplus)
31 #define __DECLBEGIN extern "C" {
44 extern void spin_unlock(int *p
);
45 extern void spin_lock(int *p
);
48 #include <mach/mach_types.h>
49 #include <mach/boolean.h>
55 #define MACRO_BEGIN do {
56 #define MACRO_END } while (NEVER)
58 #endif /* MACRO_BEGIN */
61 * C Threads package initialization.
64 extern void cthread_init();
72 typedef struct cthread_queue
{
73 struct cthread_queue_item
*head
;
74 struct cthread_queue_item
*tail
;
77 typedef struct cthread_queue_item
{
78 struct cthread_queue_item
*next
;
79 } *cthread_queue_item_t
;
81 #define NO_QUEUE_ITEM ((cthread_queue_item_t) 0)
83 #define QUEUE_INITIALIZER { NO_QUEUE_ITEM, NO_QUEUE_ITEM }
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))
89 #define cthread_queue_enq(q, x) \
93 (q)->head = (cthread_queue_item_t) (x); \
95 (q)->tail->next = (cthread_queue_item_t) (x); \
96 (q)->tail = (cthread_queue_item_t) (x); \
99 #define cthread_queue_preq(q, x) \
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); \
107 #define cthread_queue_head(q, t) ((t) ((q)->head))
109 #define cthread_queue_deq(q, t, x) \
111 if (((x) = (t) ((q)->head)) != 0 && \
112 ((q)->head = (cthread_queue_item_t) ((x)->next)) == 0) \
116 #define cthread_queue_map(q, t, f) \
118 register cthread_queue_item_t x, next; \
119 for (x = (cthread_queue_item_t) ((q)->head); x != 0; x = next) { \
129 typedef struct mutex
{
134 #define MUTEX_INITIALIZER { 0, 0 }
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))
143 #define mutex_lock(m) \
145 if (! mutex_try_lock(m)) mutex_wait_lock(m); \
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
);
155 * Condition variables.
157 typedef struct condition
{
159 struct cthread_queue queue
;
163 #define CONDITION_INITIALIZER { 0, QUEUE_INITIALIZER, 0 }
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
172 #define condition_signal(c) \
174 if ((c)->queue.head) cond_signal(c); \
177 #define condition_broadcast(c) \
179 if ((c)->queue.head) cond_broadcast(c); \
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
);
192 typedef any_t (*cthread_fn_t
)(any_t arg
);
196 typedef struct cthread
{
197 struct cthread
*next
;
198 thread_port_t real_thread
;
200 struct condition done
;
202 #if defined(__cplusplus)
214 #define NO_CTHREAD ((cthread_t) 0)
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(
226 extern kern_return_t
cthread_max_priority(
230 extern kern_return_t
cthread_abort(cthread_t t
);
234 * This structure must agree with struct cproc in cthread_internals.h
236 typedef struct ur_cthread
{
237 struct ur_cthread
*next
;
238 cthread_t incarnation
;
242 extern int cthread_sp(void);
244 extern int cthread_stack_mask
;
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)
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);
260 #define cthread_set_data(t, x) ((t)->data = (x))
261 #define cthread_data(t) ((t)->data)
266 #define spin_unlock(p) (*(p) = 0)
271 #define mutex_unlock(m) ((m)->lock = 0)
277 #ifdef CTHREADS_DEBUG
281 * Assertion macro, similar to <assert.h>
288 "File %s, line %d: assertion p failed.\n", \
289 __FILE__, __LINE__); \
296 #define SHOULDNT_HAPPEN 0
298 extern int cthread_debug
;
300 #else /* CTHREADS_DEBUG */
306 #endif /* CTHREADS_DEBUG */
308 #endif /* _CTHREADS_ */