rf_threadstuff.h revision 1.1 1 1.1 oster /* $NetBSD: rf_threadstuff.h,v 1.1 1998/11/13 04:20:35 oster Exp $ */
2 1.1 oster /*
3 1.1 oster * Copyright (c) 1995 Carnegie-Mellon University.
4 1.1 oster * All rights reserved.
5 1.1 oster *
6 1.1 oster * Author: Mark Holland, Daniel Stodolsky, Jim Zelenka
7 1.1 oster *
8 1.1 oster * Permission to use, copy, modify and distribute this software and
9 1.1 oster * its documentation is hereby granted, provided that both the copyright
10 1.1 oster * notice and this permission notice appear in all copies of the
11 1.1 oster * software, derivative works or modified versions, and any portions
12 1.1 oster * thereof, and that both notices appear in supporting documentation.
13 1.1 oster *
14 1.1 oster * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
15 1.1 oster * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
16 1.1 oster * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
17 1.1 oster *
18 1.1 oster * Carnegie Mellon requests users of this software to return to
19 1.1 oster *
20 1.1 oster * Software Distribution Coordinator or Software.Distribution (at) CS.CMU.EDU
21 1.1 oster * School of Computer Science
22 1.1 oster * Carnegie Mellon University
23 1.1 oster * Pittsburgh PA 15213-3890
24 1.1 oster *
25 1.1 oster * any improvements or extensions that they make and grant Carnegie the
26 1.1 oster * rights to redistribute these changes.
27 1.1 oster */
28 1.1 oster
29 1.1 oster /*
30 1.1 oster * threadstuff.h -- definitions for threads, locks, and synchronization
31 1.1 oster *
32 1.1 oster * The purpose of this file is provide some illusion of portability.
33 1.1 oster * If the functions below can be implemented with the same semantics on
34 1.1 oster * some new system, then at least the synchronization and thread control
35 1.1 oster * part of the code should not require modification to port to a new machine.
36 1.1 oster * the only other place where the pthread package is explicitly used is
37 1.1 oster * threadid.h
38 1.1 oster *
39 1.1 oster * this file should be included above stdio.h to get some necessary defines.
40 1.1 oster *
41 1.1 oster */
42 1.1 oster
43 1.1 oster /* :
44 1.1 oster * Log: rf_threadstuff.h,v
45 1.1 oster * Revision 1.38 1996/08/12 22:37:47 jimz
46 1.1 oster * add AIX stuff for user driver
47 1.1 oster *
48 1.1 oster * Revision 1.37 1996/08/11 00:47:09 jimz
49 1.1 oster * make AIX friendly
50 1.1 oster *
51 1.1 oster * Revision 1.36 1996/07/23 22:06:59 jimz
52 1.1 oster * add rf_destroy_threadgroup
53 1.1 oster *
54 1.1 oster * Revision 1.35 1996/07/23 21:31:16 jimz
55 1.1 oster * add init_threadgroup
56 1.1 oster *
57 1.1 oster * Revision 1.34 1996/07/18 22:57:14 jimz
58 1.1 oster * port simulator to AIX
59 1.1 oster *
60 1.1 oster * Revision 1.33 1996/07/15 17:22:18 jimz
61 1.1 oster * nit-pick code cleanup
62 1.1 oster * resolve stdlib problems on DEC OSF
63 1.1 oster *
64 1.1 oster * Revision 1.32 1996/06/17 03:01:11 jimz
65 1.1 oster * get rid of JOIN stuff
66 1.1 oster *
67 1.1 oster * Revision 1.31 1996/06/14 23:15:38 jimz
68 1.1 oster * attempt to deal with thread GC problem
69 1.1 oster *
70 1.1 oster * Revision 1.30 1996/06/11 18:12:36 jimz
71 1.1 oster * get rid of JOIN operations
72 1.1 oster * use ThreadGroup stuff instead
73 1.1 oster * fix some allocation/deallocation and sync bugs
74 1.1 oster *
75 1.1 oster * Revision 1.29 1996/06/11 13:48:10 jimz
76 1.1 oster * make kernel RF_THREAD_CREATE give back happier return vals
77 1.1 oster *
78 1.1 oster * Revision 1.28 1996/06/10 16:40:01 jimz
79 1.1 oster * break user-level stuff out into lib+apps
80 1.1 oster *
81 1.1 oster * Revision 1.27 1996/06/10 11:55:47 jimz
82 1.1 oster * Straightened out some per-array/not-per-array distinctions, fixed
83 1.1 oster * a couple bugs related to confusion. Added shutdown lists. Removed
84 1.1 oster * layout shutdown function (now subsumed by shutdown lists).
85 1.1 oster *
86 1.1 oster * Revision 1.26 1996/06/09 02:36:46 jimz
87 1.1 oster * lots of little crufty cleanup- fixup whitespace
88 1.1 oster * issues, comment #ifdefs, improve typing in some
89 1.1 oster * places (esp size-related)
90 1.1 oster *
91 1.1 oster * Revision 1.25 1996/06/05 18:06:02 jimz
92 1.1 oster * Major code cleanup. The Great Renaming is now done.
93 1.1 oster * Better modularity. Better typing. Fixed a bunch of
94 1.1 oster * synchronization bugs. Made a lot of global stuff
95 1.1 oster * per-desc or per-array. Removed dead code.
96 1.1 oster *
97 1.1 oster * Revision 1.24 1996/05/30 11:29:41 jimz
98 1.1 oster * Numerous bug fixes. Stripe lock release code disagreed with the taking code
99 1.1 oster * about when stripes should be locked (I made it consistent: no parity, no lock)
100 1.1 oster * There was a lot of extra serialization of I/Os which I've removed- a lot of
101 1.1 oster * it was to calculate values for the cache code, which is no longer with us.
102 1.1 oster * More types, function, macro cleanup. Added code to properly quiesce the array
103 1.1 oster * on shutdown. Made a lot of stuff array-specific which was (bogusly) general
104 1.1 oster * before. Fixed memory allocation, freeing bugs.
105 1.1 oster *
106 1.1 oster * Revision 1.23 1996/05/20 19:31:54 jimz
107 1.1 oster * add atomic debug (mutex and cond leak finder) stuff
108 1.1 oster *
109 1.1 oster * Revision 1.22 1996/05/20 16:24:49 jimz
110 1.1 oster * get happy in simulator
111 1.1 oster *
112 1.1 oster * Revision 1.21 1996/05/20 16:15:07 jimz
113 1.1 oster * switch to rf_{mutex,cond}_{init,destroy}
114 1.1 oster *
115 1.1 oster * Revision 1.20 1996/05/18 19:51:34 jimz
116 1.1 oster * major code cleanup- fix syntax, make some types consistent,
117 1.1 oster * add prototypes, clean out dead code, et cetera
118 1.1 oster *
119 1.1 oster * Revision 1.19 1996/05/09 17:16:53 jimz
120 1.1 oster * correct arg to JOIN_THREAD
121 1.1 oster *
122 1.1 oster * Revision 1.18 1995/12/12 18:10:06 jimz
123 1.1 oster * MIN -> RF_MIN, MAX -> RF_MAX, ASSERT -> RF_ASSERT
124 1.1 oster * fix 80-column brain damage in comments
125 1.1 oster *
126 1.1 oster * Revision 1.17 1995/12/06 15:15:21 root
127 1.1 oster * added copyright info
128 1.1 oster *
129 1.1 oster */
130 1.1 oster
131 1.1 oster #ifndef _RF__RF_THREADSTUFF_H_
132 1.1 oster #define _RF__RF_THREADSTUFF_H_
133 1.1 oster
134 1.1 oster #include "rf_types.h"
135 1.1 oster
136 1.1 oster #define rf_create_managed_mutex(a,b) _rf_create_managed_mutex(a,b,__FILE__,__LINE__)
137 1.1 oster #define rf_create_managed_cond(a,b) _rf_create_managed_cond(a,b,__FILE__,__LINE__)
138 1.1 oster #define rf_init_managed_threadgroup(a,b) _rf_init_managed_threadgroup(a,b,__FILE__,__LINE__)
139 1.1 oster #define rf_init_threadgroup(a) _rf_init_threadgroup(a,__FILE__,__LINE__)
140 1.1 oster #define rf_destroy_threadgroup(a) _rf_destroy_threadgroup(a,__FILE__,__LINE__)
141 1.1 oster
142 1.1 oster int _rf_init_threadgroup(RF_ThreadGroup_t *g, char *file, int line);
143 1.1 oster int _rf_destroy_threadgroup(RF_ThreadGroup_t *g, char *file, int line);
144 1.1 oster int _rf_init_managed_threadgroup(RF_ShutdownList_t **listp,
145 1.1 oster RF_ThreadGroup_t *g, char *file, int line);
146 1.1 oster
147 1.1 oster #ifndef SIMULATE /* will null all this calls */
148 1.1 oster #ifndef KERNEL
149 1.1 oster
150 1.1 oster #if defined(__osf__) || defined(AIX)
151 1.1 oster #include <pthread.h>
152 1.1 oster #endif /* __osf__ || AIX */
153 1.1 oster
154 1.1 oster #define RF_DEBUG_ATOMIC 0
155 1.1 oster
156 1.1 oster #if RF_DEBUG_ATOMIC > 0
157 1.1 oster #define RF_ATENT_M 1
158 1.1 oster #define RF_ATENT_C 2
159 1.1 oster typedef struct RF_ATEnt_s RF_ATEnt_t;
160 1.1 oster struct RF_ATEnt_s {
161 1.1 oster char *file;
162 1.1 oster int line;
163 1.1 oster pthread_mutex_t m;
164 1.1 oster pthread_cond_t c;
165 1.1 oster int type;
166 1.1 oster int otype;
167 1.1 oster RF_ATEnt_t *next;
168 1.1 oster RF_ATEnt_t *prev;
169 1.1 oster };
170 1.1 oster
171 1.1 oster #define RF_DECLARE_MUTEX(_m_) RF_ATEnt_t *_m_;
172 1.1 oster #define RF_DECLARE_STATIC_MUTEX(_m_) static RF_ATEnt_t *_m_;
173 1.1 oster #define RF_DECLARE_EXTERN_MUTEX(_m_) extern RF_ATEnt_t *_m_;
174 1.1 oster #define RF_DECLARE_COND(_c_) RF_ATEnt_t *_c_;
175 1.1 oster #define RF_DECLARE_STATIC_COND(_c_) static RF_ATEnt_t *_c_;
176 1.1 oster #define RF_DECLARE_EXTERN_COND(_c_) extern RF_ATEnt_t *_c_;
177 1.1 oster
178 1.1 oster int _rf_mutex_init(RF_ATEnt_t **m, char *file, int line);
179 1.1 oster int _rf_mutex_destroy(RF_ATEnt_t **m, char *file, int line);
180 1.1 oster int _rf_cond_init(RF_ATEnt_t **c, char *file, int line);
181 1.1 oster int _rf_cond_destroy(RF_ATEnt_t **c, char *file, int line);
182 1.1 oster void rf_atent_init(void);
183 1.1 oster void rf_atent_shutdown(void);
184 1.1 oster
185 1.1 oster #define rf_mutex_init(_m_) _rf_mutex_init(_m_,__FILE__,__LINE__)
186 1.1 oster #define rf_mutex_destroy(_m_) _rf_mutex_destroy(_m_,__FILE__,__LINE__)
187 1.1 oster #define rf_cond_init(_m_) _rf_cond_init(_m_,__FILE__,__LINE__)
188 1.1 oster #define rf_cond_destroy(_m_) _rf_cond_destroy(_m_,__FILE__,__LINE__)
189 1.1 oster
190 1.1 oster #define RF_LOCK_MUTEX(_a_) {RF_ASSERT((_a_)->type == RF_ATENT_M); pthread_mutex_lock(&((_a_)->m));}
191 1.1 oster #define RF_UNLOCK_MUTEX(_a_) {RF_ASSERT((_a_)->type == RF_ATENT_M); pthread_mutex_unlock(&((_a_)->m));}
192 1.1 oster
193 1.1 oster #define RF_WAIT_COND(_c_,_m_) { \
194 1.1 oster RF_ASSERT((_c_)->type == RF_ATENT_C); \
195 1.1 oster RF_ASSERT((_m_)->type == RF_ATENT_M); \
196 1.1 oster pthread_cond_wait( &((_c_)->c), &((_m_)->m) ); \
197 1.1 oster }
198 1.1 oster #define RF_SIGNAL_COND(_c_) {RF_ASSERT((_c_)->type == RF_ATENT_C); pthread_cond_signal( &((_c_)->c));}
199 1.1 oster #define RF_BROADCAST_COND(_c_) {RF_ASSERT((_c_)->type == RF_ATENT_C); pthread_cond_broadcast(&((_c_)->c));}
200 1.1 oster
201 1.1 oster #else /* RF_DEBUG_ATOMIC > 0 */
202 1.1 oster
203 1.1 oster /* defining these as macros allows us to NULL them out in the kernel */
204 1.1 oster #define RF_DECLARE_MUTEX(_m_) pthread_mutex_t _m_;
205 1.1 oster #define RF_DECLARE_STATIC_MUTEX(_m_) static pthread_mutex_t _m_;
206 1.1 oster #define RF_DECLARE_EXTERN_MUTEX(_m_) extern pthread_mutex_t _m_;
207 1.1 oster #define RF_DECLARE_COND(_c_) pthread_cond_t _c_;
208 1.1 oster #define RF_DECLARE_STATIC_COND(_c_) static pthread_cond_t _c_;
209 1.1 oster #define RF_DECLARE_EXTERN_COND(_c_) extern pthread_cond_t _c_;
210 1.1 oster
211 1.1 oster int rf_mutex_init(pthread_mutex_t *m);
212 1.1 oster int rf_mutex_destroy(pthread_mutex_t *m);
213 1.1 oster int rf_cond_init(pthread_cond_t *c);
214 1.1 oster int rf_cond_destroy(pthread_cond_t *c);
215 1.1 oster
216 1.1 oster #define RF_LOCK_MUTEX(_m_) {pthread_mutex_lock(&(_m_));}
217 1.1 oster #define RF_UNLOCK_MUTEX(_m_) pthread_mutex_unlock(&(_m_))
218 1.1 oster
219 1.1 oster #define RF_WAIT_COND(_c_,_m_) pthread_cond_wait( &(_c_), &(_m_) )
220 1.1 oster #define RF_SIGNAL_COND(_c_) pthread_cond_signal( &(_c_) )
221 1.1 oster #define RF_BROADCAST_COND(_c_) pthread_cond_broadcast(&(_c_))
222 1.1 oster
223 1.1 oster #endif /* RF_DEBUG_ATOMIC > 0 */
224 1.1 oster
225 1.1 oster int _rf_create_managed_mutex(RF_ShutdownList_t **listp, pthread_mutex_t *m, char *file, int line);
226 1.1 oster int _rf_create_managed_cond(RF_ShutdownList_t **listp, pthread_cond_t *c, char *file, int line);
227 1.1 oster
228 1.1 oster typedef pthread_t RF_Thread_t;
229 1.1 oster #ifdef __osf__
230 1.1 oster typedef pthread_addr_t RF_ThreadArg_t; /* the argument to a thread function */
231 1.1 oster #else /* __osf__ */
232 1.1 oster typedef void *RF_ThreadArg_t; /* the argument to a thread function */
233 1.1 oster #endif /* __osf__ */
234 1.1 oster typedef pthread_attr_t RF_ThreadAttr_t; /* a thread creation attribute structure */
235 1.1 oster
236 1.1 oster #ifdef __osf__
237 1.1 oster #define RF_EXIT_THREAD(_status_) pthread_exit( (pthread_addr_t) (_status_) )
238 1.1 oster #else /* __osf__ */
239 1.1 oster #define RF_EXIT_THREAD(_status_) pthread_exit( (void *) (_status_) )
240 1.1 oster #endif /* __osf__ */
241 1.1 oster #define RF_DELAY_THREAD(_secs_, _msecs_) {struct timespec interval; \
242 1.1 oster interval.tv_sec = (_secs_); \
243 1.1 oster interval.tv_nsec = (_msecs_)*1000000; \
244 1.1 oster pthread_delay_np(&interval); \
245 1.1 oster }
246 1.1 oster #define RF_DELAY_THREAD_TS(_ts_) pthread_delay_np(&(_ts_))
247 1.1 oster
248 1.1 oster #ifdef __osf__
249 1.1 oster #define RF_THREAD_ATTR_CREATE(_attr_) pthread_attr_create( &(_attr_) )
250 1.1 oster #define RF_THREAD_ATTR_DELETE(_attr_) pthread_attr_delete( &(_attr_) )
251 1.1 oster #endif /* __osf__ */
252 1.1 oster #ifdef AIX
253 1.1 oster #define RF_THREAD_ATTR_CREATE(_attr_) pthread_attr_init( &(_attr_) )
254 1.1 oster #define RF_THREAD_ATTR_DELETE(_attr_) pthread_attr_destroy( &(_attr_) )
255 1.1 oster #endif /* AIX */
256 1.1 oster #define RF_THREAD_ATTR_SETSTACKSIZE(_attr_,_sz_) pthread_attr_setstacksize(&(_attr_), (long) (_sz_))
257 1.1 oster #define RF_THREAD_ATTR_GETSTACKSIZE(_attr_) pthread_attr_getstacksize(_attr_)
258 1.1 oster #define RF_THREAD_ATTR_SETSCHED(_attr_,_sched_) pthread_attr_setsched(&(_attr_), (_sched_))
259 1.1 oster #define RF_CREATE_ATTR_THREAD(_handle_, _attr_, _func_, _arg_) \
260 1.1 oster pthread_create(&(_handle_), (_attr_), (pthread_startroutine_t) (_func_), (_arg_))
261 1.1 oster
262 1.1 oster
263 1.1 oster extern pthread_attr_t raidframe_attr_default;
264 1.1 oster int rf_thread_create(RF_Thread_t *thread, pthread_attr_t attr,
265 1.1 oster void (*func)(), RF_ThreadArg_t arg);
266 1.1 oster
267 1.1 oster #define RF_CREATE_THREAD(_handle_, _func_, _arg_) \
268 1.1 oster rf_thread_create(&(_handle_), raidframe_attr_default, (_func_), (_arg_))
269 1.1 oster
270 1.1 oster #else /* KERNEL */
271 1.1 oster #ifdef __NetBSD__
272 1.1 oster #include <sys/lock.h>
273 1.1 oster #define decl_simple_lock_data(a,b) a struct simplelock b;
274 1.1 oster #define simple_lock_addr(a) ((struct simplelock *)&(a))
275 1.1 oster #else
276 1.1 oster #include <kern/task.h>
277 1.1 oster #include <kern/thread.h>
278 1.1 oster #include <kern/lock.h>
279 1.1 oster #include <kern/sched_prim.h>
280 1.1 oster #define decl_simple_lock_data(a,b) a int (b);
281 1.1 oster #endif /* __NetBSD__ */
282 1.1 oster
283 1.1 oster #ifdef __NetBSD__
284 1.1 oster typedef struct proc *RF_Thread_t;
285 1.1 oster #else
286 1.1 oster typedef thread_t RF_Thread_t;
287 1.1 oster #endif
288 1.1 oster typedef void *RF_ThreadArg_t;
289 1.1 oster
290 1.1 oster #define RF_DECLARE_MUTEX(_m_) decl_simple_lock_data(,(_m_))
291 1.1 oster #define RF_DECLARE_STATIC_MUTEX(_m_) decl_simple_lock_data(static,(_m_))
292 1.1 oster #define RF_DECLARE_EXTERN_MUTEX(_m_) decl_simple_lock_data(extern,(_m_))
293 1.1 oster
294 1.1 oster #define RF_DECLARE_COND(_c_) int _c_;
295 1.1 oster #define RF_DECLARE_STATIC_COND(_c_) static int _c_;
296 1.1 oster #define RF_DECLARE_EXTERN_COND(_c_) extern int _c_;
297 1.1 oster
298 1.1 oster #define RF_LOCK_MUTEX(_m_) simple_lock(&(_m_))
299 1.1 oster #define RF_UNLOCK_MUTEX(_m_) simple_unlock(&(_m_))
300 1.1 oster
301 1.1 oster
302 1.1 oster #ifdef __NetBSD__
303 1.1 oster #include <sys/types.h>
304 1.1 oster #include <sys/kthread.h>
305 1.1 oster /*
306 1.1 oster * In NetBSD, kernel threads are simply processes which share several
307 1.1 oster * substructures and never run in userspace.
308 1.1 oster *
309 1.1 oster * XXX Note, NetBSD does not yet have a wakeup_one(), so we always
310 1.1 oster * XXX get Thundering Herd when a condition occurs.
311 1.1 oster */
312 1.1 oster #define RF_WAIT_COND(_c_,_m_) { \
313 1.1 oster RF_UNLOCK_MUTEX(_m_); \
314 1.1 oster tsleep(&_c_, PRIBIO | PCATCH, "rfwcond", 0); \
315 1.1 oster RF_LOCK_MUTEX(_m_); \
316 1.1 oster }
317 1.1 oster #define RF_SIGNAL_COND(_c_) wakeup(&(_c_))
318 1.1 oster #define RF_BROADCAST_COND(_c_) wakeup(&(_c_))
319 1.1 oster #define RF_CREATE_THREAD(_handle_, _func_, _arg_) \
320 1.1 oster kthread_create((void (*) __P((void *)))(_func_), (void *)(_arg_), \
321 1.1 oster (struct proc **)&(_handle_), "raid")
322 1.1 oster #else /* ! __NetBSD__ */
323 1.1 oster /*
324 1.1 oster * Digital UNIX/Mach threads.
325 1.1 oster */
326 1.1 oster #define RF_WAIT_COND(_c_,_m_) { \
327 1.1 oster assert_wait((vm_offset_t)&(_c_), TRUE); \
328 1.1 oster RF_UNLOCK_MUTEX(_m_); \
329 1.1 oster thread_block(); \
330 1.1 oster RF_LOCK_MUTEX(_m_); \
331 1.1 oster }
332 1.1 oster #define RF_SIGNAL_COND(_c_) thread_wakeup_one(((vm_offset_t)&(_c_)))
333 1.1 oster #define RF_BROADCAST_COND(_c_) thread_wakeup(((vm_offset_t)&(_c_)))
334 1.1 oster extern task_t first_task;
335 1.1 oster #define RF_CREATE_THREAD(_handle_, _func_, _arg_) \
336 1.1 oster (((_handle_ = kernel_thread_w_arg(first_task, (void (*)())_func_, (void *)(_arg_))) != THREAD_NULL) ? 0 : ENOMEM)
337 1.1 oster #endif /* __NetBSD__ */
338 1.1 oster #endif /* KERNEL */
339 1.1 oster #else /* SIMULATE */
340 1.1 oster
341 1.1 oster #define RF_DECLARE_MUTEX(_m_) int _m_;
342 1.1 oster #define RF_DECLARE_STATIC_MUTEX(_m_) static int _m_;
343 1.1 oster #define RF_DECLARE_EXTERN_MUTEX(_m_) extern int _m_;
344 1.1 oster #define RF_DECLARE_COND(_c_) int _c_;
345 1.1 oster #define RF_DECLARE_STATIC_COND(_c_) static int _c_;
346 1.1 oster #define RF_DECLARE_EXTERN_COND(_c_) extern int _c_;
347 1.1 oster
348 1.1 oster extern int rf_mutex_init(int *m);
349 1.1 oster extern int rf_mutex_destroy(int *m);
350 1.1 oster extern int rf_cond_init(int *c);
351 1.1 oster extern int rf_cond_destroy(int *c);
352 1.1 oster
353 1.1 oster int rf_mutex_init(int *m);
354 1.1 oster int rf_mutex_destroy(int *m);
355 1.1 oster int _rf_create_managed_mutex(RF_ShutdownList_t **listp, int *m, char *file, int line);
356 1.1 oster int _rf_create_managed_cond(RF_ShutdownList_t **listp, int *m, char *file, int line);
357 1.1 oster
358 1.1 oster typedef void *RF_ThreadArg_t; /* the argument to a thread function */
359 1.1 oster
360 1.1 oster #define RF_LOCK_MUTEX(_m_)
361 1.1 oster #define RF_UNLOCK_MUTEX(_m_)
362 1.1 oster
363 1.1 oster #define RF_WAIT_COND(_c_,_m_)
364 1.1 oster #define RF_SIGNAL_COND(_c_)
365 1.1 oster #define RF_BROADCAST_COND(_c_)
366 1.1 oster
367 1.1 oster #define RF_EXIT_THREAD(_status_)
368 1.1 oster #define RF_DELAY_THREAD(_secs_, _msecs_)
369 1.1 oster
370 1.1 oster #define RF_THREAD_ATTR_CREATE(_attr_) ;
371 1.1 oster #define RF_THREAD_ATTR_DELETE(_attr_) ;
372 1.1 oster #define RF_THREAD_ATTR_SETSTACKSIZE(_attr_,_sz_) ;
373 1.1 oster #define RF_THREAD_ATTR_SETSCHED(_attr_,_sched_) ;
374 1.1 oster #define RF_CREATE_ATTR_THREAD(_handle_, _attr_, _func_, _arg_) ;
375 1.1 oster
376 1.1 oster #define RF_CREATE_THREAD(_handle_, _func_, _arg_) 1
377 1.1 oster
378 1.1 oster #endif /* SIMULATE */
379 1.1 oster
380 1.1 oster struct RF_ThreadGroup_s {
381 1.1 oster int created;
382 1.1 oster int running;
383 1.1 oster int shutdown;
384 1.1 oster RF_DECLARE_MUTEX(mutex)
385 1.1 oster RF_DECLARE_COND(cond)
386 1.1 oster };
387 1.1 oster
388 1.1 oster /*
389 1.1 oster * Someone has started a thread in the group
390 1.1 oster */
391 1.1 oster #define RF_THREADGROUP_STARTED(_g_) { \
392 1.1 oster RF_LOCK_MUTEX((_g_)->mutex); \
393 1.1 oster (_g_)->created++; \
394 1.1 oster RF_UNLOCK_MUTEX((_g_)->mutex); \
395 1.1 oster }
396 1.1 oster
397 1.1 oster /*
398 1.1 oster * Thread announcing that it is now running
399 1.1 oster */
400 1.1 oster #define RF_THREADGROUP_RUNNING(_g_) { \
401 1.1 oster RF_LOCK_MUTEX((_g_)->mutex); \
402 1.1 oster (_g_)->running++; \
403 1.1 oster RF_UNLOCK_MUTEX((_g_)->mutex); \
404 1.1 oster RF_SIGNAL_COND((_g_)->cond); \
405 1.1 oster }
406 1.1 oster
407 1.1 oster /*
408 1.1 oster * Thread announcing that it is now done
409 1.1 oster */
410 1.1 oster #define RF_THREADGROUP_DONE(_g_) { \
411 1.1 oster RF_LOCK_MUTEX((_g_)->mutex); \
412 1.1 oster (_g_)->shutdown++; \
413 1.1 oster RF_UNLOCK_MUTEX((_g_)->mutex); \
414 1.1 oster RF_SIGNAL_COND((_g_)->cond); \
415 1.1 oster }
416 1.1 oster
417 1.1 oster /*
418 1.1 oster * Wait for all threads to start running
419 1.1 oster */
420 1.1 oster #define RF_THREADGROUP_WAIT_START(_g_) { \
421 1.1 oster RF_LOCK_MUTEX((_g_)->mutex); \
422 1.1 oster while((_g_)->running < (_g_)->created) { \
423 1.1 oster RF_WAIT_COND((_g_)->cond, (_g_)->mutex); \
424 1.1 oster } \
425 1.1 oster RF_UNLOCK_MUTEX((_g_)->mutex); \
426 1.1 oster }
427 1.1 oster
428 1.1 oster /*
429 1.1 oster * Wait for all threads to stop running
430 1.1 oster */
431 1.1 oster #ifndef __NetBSD__
432 1.1 oster #define RF_THREADGROUP_WAIT_STOP(_g_) { \
433 1.1 oster RF_LOCK_MUTEX((_g_)->mutex); \
434 1.1 oster RF_ASSERT((_g_)->running == (_g_)->created); \
435 1.1 oster while((_g_)->shutdown < (_g_)->running) { \
436 1.1 oster RF_WAIT_COND((_g_)->cond, (_g_)->mutex); \
437 1.1 oster } \
438 1.1 oster RF_UNLOCK_MUTEX((_g_)->mutex); \
439 1.1 oster }
440 1.1 oster #else
441 1.1 oster /* XXX Note that we've removed the assert. That should get put back
442 1.1 oster in once we actually get something like a kernel thread running */
443 1.1 oster #define RF_THREADGROUP_WAIT_STOP(_g_) { \
444 1.1 oster RF_LOCK_MUTEX((_g_)->mutex); \
445 1.1 oster while((_g_)->shutdown < (_g_)->running) { \
446 1.1 oster RF_WAIT_COND((_g_)->cond, (_g_)->mutex); \
447 1.1 oster } \
448 1.1 oster RF_UNLOCK_MUTEX((_g_)->mutex); \
449 1.1 oster }
450 1.1 oster #endif
451 1.1 oster
452 1.1 oster #if defined(__NetBSD__) && defined(_KERNEL)
453 1.1 oster
454 1.1 oster int rf_mutex_init(struct simplelock *);
455 1.1 oster int rf_mutex_destroy(struct simplelock *);
456 1.1 oster int _rf_create_managed_mutex(RF_ShutdownList_t **, struct simplelock *,
457 1.1 oster char *, int);
458 1.1 oster int _rf_create_managed_cond(RF_ShutdownList_t **listp, int *,
459 1.1 oster char *file, int line);
460 1.1 oster
461 1.1 oster int rf_cond_init(int *c); /* XXX need to write?? */
462 1.1 oster int rf_cond_destroy(int *c); /* XXX need to write?? */
463 1.1 oster #endif
464 1.1 oster #endif /* !_RF__RF_THREADSTUFF_H_ */
465