2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
32 #if defined(__cplusplus)
33 #define __DECLBEGIN extern "C" {
46 extern void spin_unlock(int *p
);
47 extern void spin_lock(int *p
);
50 #include <mach/mach_types.h>
51 #include <mach/boolean.h>
57 #define MACRO_BEGIN do {
58 #define MACRO_END } while (NEVER)
60 #endif /* MACRO_BEGIN */
63 * C Threads package initialization.
66 extern void cthread_init();
74 typedef struct cthread_queue
{
75 struct cthread_queue_item
*head
;
76 struct cthread_queue_item
*tail
;
79 typedef struct cthread_queue_item
{
80 struct cthread_queue_item
*next
;
81 } *cthread_queue_item_t
;
83 #define NO_QUEUE_ITEM ((cthread_queue_item_t) 0)
85 #define QUEUE_INITIALIZER { NO_QUEUE_ITEM, NO_QUEUE_ITEM }
87 #define cthread_queue_alloc() ((cthread_queue_t) calloc(1, sizeof(struct cthread_queue)))
88 #define cthread_queue_init(q) ((q)->head = (q)->tail = 0)
89 #define cthread_queue_free(q) free((any_t) (q))
91 #define cthread_queue_enq(q, x) \
95 (q)->head = (cthread_queue_item_t) (x); \
97 (q)->tail->next = (cthread_queue_item_t) (x); \
98 (q)->tail = (cthread_queue_item_t) (x); \
101 #define cthread_queue_preq(q, x) \
103 if ((q)->tail == 0) \
104 (q)->tail = (cthread_queue_item_t) (x); \
105 ((cthread_queue_item_t) (x))->next = (q)->head; \
106 (q)->head = (cthread_queue_item_t) (x); \
109 #define cthread_queue_head(q, t) ((t) ((q)->head))
111 #define cthread_queue_deq(q, t, x) \
113 if (((x) = (t) ((q)->head)) != 0 && \
114 ((q)->head = (cthread_queue_item_t) ((x)->next)) == 0) \
118 #define cthread_queue_map(q, t, f) \
120 register cthread_queue_item_t x, next; \
121 for (x = (cthread_queue_item_t) ((q)->head); x != 0; x = next) { \
131 typedef struct mutex
{
136 #define MUTEX_INITIALIZER { 0, 0 }
138 #define mutex_alloc() ((mutex_t) calloc(1, sizeof(struct mutex)))
139 #define mutex_init(m) ((m)->lock = 0)
140 #define mutex_set_name(m, x) ((m)->name = (x))
141 #define mutex_name(m) ((m)->name != 0 ? (m)->name : "?")
142 #define mutex_clear(m) /* nop */
143 #define mutex_free(m) free((any_t) (m))
145 #define mutex_lock(m) \
147 if (! mutex_try_lock(m)) mutex_wait_lock(m); \
151 extern int mutex_try_lock(mutex_t m
); /* nonblocking */
152 extern void mutex_wait_lock(mutex_t m
); /* blocking */
153 extern void mutex_unlock(mutex_t m
);
157 * Condition variables.
159 typedef struct condition
{
161 struct cthread_queue queue
;
165 #define CONDITION_INITIALIZER { 0, QUEUE_INITIALIZER, 0 }
167 #define condition_alloc() ((condition_t) calloc(1, sizeof(struct condition)))
168 #define condition_init(c) MACRO_BEGIN (c)->lock = 0; cthread_queue_init(&(c)->queue); MACRO_END
169 #define condition_set_name(c, x) ((c)->name = (x))
170 #define condition_name(c) ((c)->name != 0 ? (c)->name : "?")
171 #define condition_clear(c) MACRO_BEGIN condition_broadcast(c); spin_lock(&(c)->lock); MACRO_END
172 #define condition_free(c) MACRO_BEGIN condition_clear(c); free((any_t) (c)); MACRO_END
174 #define condition_signal(c) \
176 if ((c)->queue.head) cond_signal(c); \
179 #define condition_broadcast(c) \
181 if ((c)->queue.head) cond_broadcast(c); \
185 extern void cond_signal(condition_t c
);
186 extern void cond_broadcast(condition_t c
);
187 extern void condition_wait(condition_t c
, mutex_t m
);
194 typedef any_t (*cthread_fn_t
)(any_t arg
);
198 typedef struct cthread
{
199 struct cthread
*next
;
200 thread_port_t real_thread
;
202 struct condition done
;
204 #if defined(__cplusplus)
216 #define NO_CTHREAD ((cthread_t) 0)
219 extern cthread_t
cthread_fork(cthread_fn_t func
, any_t arg
);
220 extern void cthread_detach(cthread_t t
);
221 extern any_t
cthread_join(cthread_t t
);
222 extern void cthread_yield(void);
223 extern void cthread_exit(any_t result
);
224 extern kern_return_t
cthread_priority(
228 extern kern_return_t
cthread_max_priority(
232 extern kern_return_t
cthread_abort(cthread_t t
);
236 * This structure must agree with struct cproc in cthread_internals.h
238 typedef struct ur_cthread
{
239 struct ur_cthread
*next
;
240 cthread_t incarnation
;
244 extern int cthread_sp(void);
246 extern int cthread_stack_mask
;
248 extern ur_cthread_t
ur_cthread_self(void);
249 #define cthread_thread(c) (c->real_thread)
250 extern void cthread_set_errno_self(int e
);
251 extern int cthread_errno(void);
252 #define cthread_assoc(id, t) (((ur_cthread_t) (id))->incarnation = (t))
253 #define cthread_self() (ur_cthread_self()->incarnation)
255 extern void cthread_set_name(cthread_t t
, const char *name
);
256 extern const char *cthread_name(cthread_t t
);
257 extern int cthread_count(void);
258 extern void cthread_set_limit(int n
);
259 extern int cthread_limit(void);
262 #define cthread_set_data(t, x) ((t)->data = (x))
263 #define cthread_data(t) ((t)->data)
268 #define spin_unlock(p) (*(p) = 0)
273 #define mutex_unlock(m) ((m)->lock = 0)
279 #ifdef CTHREADS_DEBUG
283 * Assertion macro, similar to <assert.h>
290 "File %s, line %d: assertion p failed.\n", \
291 __FILE__, __LINE__); \
298 #define SHOULDNT_HAPPEN 0
300 extern int cthread_debug
;
302 #else /* CTHREADS_DEBUG */
308 #endif /* CTHREADS_DEBUG */
310 #endif /* _CTHREADS_ */