1 #ifndef SYS_MACH_THREAD_H_
2 #define SYS_MACH_THREAD_H_
3
4 #undef vm_map_remove
5 #include <sys/proc.h>
6 #include <vm/vm.h>
7 #include <vm/pmap.h>
8 #include <vm/vm_map.h>
9
10 #include <sys/mach/task.h>
11
12
13
14 /*
15 * thread_t->at_safe_point values
16 */
17 #define NOT_AT_SAFE_POINT 0
18 #define SAFE_EXCEPTION_RETURN -1
19 #define SAFE_BOOTSTRAP_RETURN -2
20 #define SAFE_EXTERNAL_RECEIVE -3
21 #define SAFE_THR_DEPRESS -4
22 #define SAFE_SUSPENDED -5
23 #define SAFE_MISCELLANEOUS -6
24 #define SAFE_INTERNAL_RECEIVE -7
25
26
27
28 #define disable_preemption() critical_enter()
29 #define enable_preemption() critical_exit()
30
31
32 /* XXX move me */
33 struct thread_shuttle {
34
35 /* IPC data structures */
36 struct thread_shuttle *ith_next, *ith_prev, *ith_pool_next;
37
38 struct ipc_kmsg_queue ith_messages;
39
40 struct mtx ith_lock_data;
41 struct mtx *ith_block_lock_data;
42 mach_port_t ith_mig_reply; /* reply port for mig */
43 struct ipc_port *ith_rpc_reply; /* reply port for kernel RPCs */
44 uint32_t timeout;
45 uint32_t sleep_stamp;
46
47 /* Various bits of stashed state */
48 union {
49 struct {
50 mach_msg_return_t state; /* receive state */
51 mach_port_seqno_t seqno; /* seqno of recvd message */
52 ipc_object_t object; /* object received on */
53 mach_vm_address_t msg_addr; /* receive buffer pointer */
54 mach_msg_size_t msize; /* max size for recvd msg */
55 mach_msg_option_t option; /* options for receive */
56 mach_msg_size_t slist_size; /* scatter list size */
57 mach_port_name_t receiver_name; /* the receive port name */
58 struct ipc_kmsg *kmsg; /* received message */
59 mach_msg_body_t *scatter_list;
60 mach_msg_size_t scatter_list_size;
61 } receive;
62 char *other; /* catch-all for other state */
63 } saved;
64 kern_return_t wait_result; /* outcome of wait -
65 may be examined by this thread
66 WITHOUT locking */
67 struct callout *timer; /* timer for thread */
68 struct thread *ith_td;
69
70 /* Special ports attached to this activation */
71 struct ipc_port *ith_self; /* not a right, doesn't hold ref */
72 struct ipc_port *ith_sself; /* a send right */
73 struct exception_action exc_actions[EXC_TYPES_COUNT];
74 int ref_count; /* number of references to me */
75 int ith_active;
76
77
78 #define ith_wait_result wait_result
79
80 #define ith_option saved.receive.option
81 #define ith_scatter_list saved.receive.scatter_list
82 #define ith_scatter_list_size saved.receive.scatter_list_size
83 #define ith_state saved.receive.state
84 #define ith_object saved.receive.object
85 #define ith_msg_addr saved.receive.msg_addr
86 #define ith_msize saved.receive.msize
87 #define ith_receiver_name saved.receive.receiver_name
88 #define ith_kmsg saved.receive.kmsg
89 #define ith_seqno saved.receive.seqno
90
91 #define ith_other saved.other
92
93 #if 0
94
95
96 /*
97 * Beginning of thread_shuttle proper
98 */
99 queue_chain_t links; /* current run queue links */
100 run_queue_t runq; /* run queue p is on SEE BELOW */
101 int whichq; /* which queue level p is on */
102 /*
103 * NOTE: The runq field in the thread structure has an unusual
104 * locking protocol. If its value is RUN_QUEUE_NULL, then it is
105 * locked by the thread_lock, but if its value is something else
106 * (i.e. a run_queue) then it is locked by that run_queue's lock.
107 */
108
109 /* Thread bookkeeping */
110 queue_chain_t pset_threads; /* list of all shuttles in proc set */
111
112 /* Self-preservation */
113 decl_simple_lock_data(,lock) /* scheduling lock (thread_lock()) */
114 decl_simple_lock_data(,w_lock) /* covers wake_active (wake_lock())*/
115 decl_mutex_data(,rpc_lock) /* RPC lock (rpc_lock()) */
116 int ref_count; /* number of references to me */
117
118 vm_offset_t kernel_stack; /* accurate only if the thread is
119 not swapped and not executing */
120
121 vm_offset_t stack_privilege;/* reserved kernel stack */
122
123 /* Blocking information */
124 int reason; /* why we blocked */
125 event_t wait_event; /* event we are waiting on */
126 kern_return_t wait_result; /* outcome of wait -
127 may be examined by this thread
128 WITHOUT locking */
129 queue_chain_t wait_link; /* event's wait queue link */
130 boolean_t wake_active; /* Someone is waiting for this
131 thread to become suspended */
132 int state; /* Thread state: */
133
134 /*
135 * Thread states [bits or'ed]
136 */
137 #define TH_WAIT 0x01 /* thread is queued for waiting */
138 #define TH_SUSP 0x02 /* thread has been asked to stop */
139 #define TH_RUN 0x04 /* thread is running or on runq */
140 #define TH_UNINT 0x08 /* thread is waiting uninteruptibly */
141 #define TH_HALTED 0x10 /* thread is halted at clean point ? */
142
143 #define TH_ABORT 0x20 /* abort interruptible waits */
144 #define TH_SWAPPED_OUT 0x40 /* thread is swapped out */
145
146 #define TH_IDLE 0x80 /* thread is an idle thread */
147
148 #define TH_SCHED_STATE (TH_WAIT|TH_SUSP|TH_RUN|TH_UNINT)
149
150 /* These two flags will never be seen and might well be removed */
151 #define TH_STACK_HANDOFF 0x0100 /* thread has no kernel stack */
152 #define TH_STACK_COMING_IN 0x0200 /* thread is waiting for kernel stack */
153 #define TH_STACK_STATE (TH_STACK_HANDOFF | TH_STACK_COMING_IN)
154
155 int preempt; /* Thread preemption status */
156 #define TH_PREEMPTABLE 0 /* Thread is preemptable */
157 #define TH_NOT_PREEMPTABLE 1 /* Thread is not preemptable */
158 #define TH_PREEMPTED 2 /* Thread has been preempted */
159
160 #if ETAP_EVENT_MONITOR
161 int etap_reason; /* real reason why we blocked */
162 boolean_t etap_trace; /* ETAP trace status */
163 #endif /* ETAP_EVENT_MONITOR */
164
165
166 /* Stack handoff information */
167 void (*continuation)(/* start here next time runnable */
168 void);
169
170 /* Scheduling information */
171 int priority; /* thread's priority */
172 int max_priority; /* maximum priority */
173 int sched_pri; /* scheduled (computed) priority */
174 int sched_data; /* for use by policy */
175 int policy; /* scheduling policy */
176 int depress_priority; /* depressed from this priority */
177 unsigned int cpu_usage; /* exp. decaying cpu usage [%cpu] */
178 unsigned int sched_usage; /* load-weighted cpu usage [sched] */
179 unsigned int sched_stamp; /* last time priority was updated */
180 unsigned int sleep_stamp; /* last time in TH_WAIT state */
181 unsigned int sched_change_stamp;
182 /* last time priority or policy was
183 explicitly changed (not the same
184 units as sched_stamp!) */
185 int unconsumed_quantum; /* leftover quantum (RR/FIFO) */
186
187 /* VM global variables */
188 boolean_t vm_privilege; /* can use reserved memory? */
189 vm_offset_t recover; /* page fault recovery (copyin/out) */
190
191 /* IPC data structures */
192 struct thread_shuttle *ith_next, *ith_prev;
193
194 struct ipc_kmsg_queue ith_messages;
195
196 decl_mutex_data(,ith_lock_data)
197 mach_port_t ith_mig_reply; /* reply port for mig */
198 struct ipc_port *ith_rpc_reply; /* reply port for kernel RPCs */
199
200 /* Various bits of stashed state */
201 union {
202 struct {
203 mach_msg_option_t option;
204 mach_msg_body_t *scatter_list;
205 mach_msg_size_t scatter_list_size;
206 } receive;
207 char *other; /* catch-all for other state */
208 } saved;
209
210 /* Timing data structures */
211 timer_data_t user_timer; /* user mode timer */
212 timer_data_t system_timer; /* system mode timer */
213 timer_data_t depressed_timer;/* depressed priority timer */
214 timer_save_data_t user_timer_save; /* saved user timer value */
215 timer_save_data_t system_timer_save; /* saved sys timer val. */
216 unsigned int cpu_delta; /* cpu usage since last update */
217 unsigned int sched_delta; /* weighted cpu usage since update */
218
219 /* Time-outs */
220 timer_elt_data_t timer; /* timer for thread */
221 timer_elt_data_t depress_timer; /* timer for priority depression */
222
223 /* Ast/Halt data structures */
224 boolean_t active; /* how alive is the thread */
225
226 /* Processor data structures */
227 processor_set_t processor_set; /* assigned processor set */
228 #if NCPUS > 1
229 processor_t bound_processor; /* bound to processor ?*/
230 #endif /* NCPUS > 1 */
231 #if MACH_HOST
232 boolean_t may_assign; /* may assignment change? */
233 boolean_t assign_active; /* someone waiting for may_assign */
234 #endif /* MACH_HOST */
235
236 #if XKMACHKERNEL
237 int xk_type;
238 #endif /* XKMACHKERNEL */
239
240 #if NCPUS > 1
241 processor_t last_processor; /* processor this last ran on */
242 #if MACH_LOCK_MON
243 unsigned lock_stack; /* number of locks held */
244 #endif /* MACH_LOCK_MON */o
245 #endif /* NCPUS > 1 */
246
247 int at_safe_point; /* thread_abort_safely allowed */
248
249 #if MACH_LDEBUG
250 /*
251 * Debugging: track acquired mutexes and locks.
252 * Because a thread can block while holding such
253 * synchronizers, we think of the thread as
254 * "owning" them.
255 */
256 #define MUTEX_STACK_DEPTH 20
257 #define LOCK_STACK_DEPTH 20
258 mutex_t *mutex_stack[MUTEX_STACK_DEPTH];
259 lock_t *lock_stack[LOCK_STACK_DEPTH];
260 unsigned int mutex_stack_index;
261 unsigned int lock_stack_index;
262 unsigned mutex_count; /* XXX to be deleted XXX */
263 boolean_t kthread; /* thread is a kernel thread */
264 #endif /* MACH_LDEBUG */
265
266 #if LINUX_DEV
267 /*
268 * State for Linux device drivers
269 */
270 void *linux_data; /* used by linuxdev/mach/glue/block.c */
271 #endif /* LINUX_DEV */
272
273 /*
274 * End of thread_shuttle proper
275 */
276
277 /*
278 * Migration and thread_activation linkage information
279 */
280 struct thread_activation *top_act; /* "current" thr_act */
281
282 } Thread_Shuttle;
283
284
285 /* typedef of thread_t is in kern/kern_types.h */
286 typedef struct thread_shuttle *thread_shuttle_t;
287 #define THREAD_NULL ((thread_t) 0)
288 #define THREAD_SHUTTLE_NULL ((thread_shuttle_t)0)
289
290
291 /*
292 * thread_t->at_safe_point values
293 */
294 #define NOT_AT_SAFE_POINT 0
295 #define SAFE_EXCEPTION_RETURN -1
296 #define SAFE_BOOTSTRAP_RETURN -2
297 #define SAFE_EXTERNAL_RECEIVE -3
298 #define SAFE_THR_DEPRESS -4
299 #define SAFE_SUSPENDED -5
300 #define SAFE_MISCELLANEOUS -6
301 #define SAFE_INTERNAL_RECEIVE -7
302
303 extern thread_act_t active_kloaded[NCPUS]; /* "" kernel-loaded acts */
304 extern vm_offset_t active_stacks[NCPUS]; /* active kernel stacks */
305 extern vm_offset_t kernel_stack[NCPUS];
306
307 #ifndef MACHINE_STACK_STASH
308 /*
309 * MD Macro to fill up global stack state,
310 * keeping the MD structure sizes + games private
311 */
312 #define MACHINE_STACK_STASH(stack) \
313 MACRO_BEGIN \
314 mp_disable_preemption(); \
315 active_stacks[cpu_number()] = (stack), \
316 kernel_stack[cpu_number()] = (stack) + KERNEL_STACK_SIZE; \
317 mp_enable_preemption(); \
318 MACRO_END
319 #endif /* MACHINE_STACK_STASH */
320
321 /*
322 * Kernel-only routines
323 */
324
325 /* Initialize thread module */
326 extern void thread_init(void);
327
328 /* Take reference on thread (make sure it doesn't go away) */
329 extern void thread_reference(
330 thread_t th);
331
332 /* Release reference on thread */
333 extern void thread_deallocate(
334 thread_t th);
335
336 /* Set priority of calling thread */
337 extern void thread_set_own_priority(
338 int priority);
339 /* Reset thread's priority */
340 extern kern_return_t thread_priority(
341 thread_act_t thr_act,
342 int priority,
343 boolean_t set_max);
344
345 /* Reset thread's max priority */
346 extern kern_return_t thread_max_priority(
347 thread_act_t thr_act,
348 processor_set_t pset,
349 int max_priority);
350
351 /* Reset thread's max priority while holding RPC locks */
352 extern kern_return_t thread_max_priority_locked(
353 thread_t thread,
354 processor_set_t pset,
355 int max_priority);
356
357 /* Set a thread's priority while holding RPC locks */
358 extern kern_return_t thread_priority_locked(
359 thread_t thread,
360 int priority,
361 boolean_t set_max);
362
363 /* Start a thread at specified routine */
364 #define thread_start(thread, start) (thread)->continuation = (start)
365
366 /* Create Kernel mode thread */
367 extern thread_t kernel_thread(
368 task_t task,
369 void (*start)(void),
370 void *arg);
371
372 /* Reaps threads waiting to be destroyed */
373 extern void reaper_thread(void);
374
375 #if MACH_HOST
376 /* Preclude thread processor set assignement */
377 extern void thread_freeze(
378 thread_t th);
379
380 /* Assign thread to a processor set */
381 extern void thread_doassign(
382 thread_t thread,
383 processor_set_t new_pset,
384 boolean_t release_freeze);
385
386 /* Allow thread processor set assignement */
387 extern void thread_unfreeze(
388 thread_t th);
389
390 #endif /* MACH_HOST */
391
392 /* Insure thread always has a kernel stack */
393 extern void stack_privilege(
394 thread_t th);
395
396 extern void consider_thread_collect(void);
397
398 /*
399 * Arguments to specify aggressiveness to thread halt.
400 * Can't have MUST_HALT and SAFELY at the same time.
401 */
402 #define THREAD_HALT_NORMAL 0
403 #define THREAD_HALT_MUST_HALT 1 /* no deadlock checks */
404 #define THREAD_HALT_SAFELY 2 /* result must be restartable */
405
406 /*
407 * Macro-defined routines
408 */
409
410 #define thread_lock_init(th) simple_lock_init(&(th)->lock, ETAP_THREAD_LOCK)
411 #define thread_lock(th) simple_lock(&(th)->lock)
412 #define thread_unlock(th) simple_unlock(&(th)->lock)
413
414 #define thread_should_halt(thread) \
415 (!(thread)->top_act || \
416 !(thread)->top_act->active || \
417 (thread)->top_act->ast & (AST_HALT|AST_TERMINATE))
418
419 /*
420 * We consider a thread not preempt
421 */
422 /*
423 * Beginning of thread_shuttle proper
424 */
425 queue_chain_t links; /* current run queue links */
426 run_queue_t runq; /* run queue p is on SEE BELOW */
427 int whichq; /* which queue level p is on */
428 /*
429 * NOTE: The runq field in the thread structure has an unusual
430 * locking protocol. If its value is RUN_QUEUE_NULL, then it is
431 * locked by the thread_lock, but if its value is something else
432 * (i.e. a run_queue) then it is locked by that run_queue's lock.
433 */
434
435 /* Thread bookkeeping */
436 queue_chain_t pset_threads; /* list of all shuttles in proc set */
437
438 /* Self-preservation */
439 decl_simple_lock_data(,lock) /* scheduling lock (thread_lock()) */
440 decl_simple_lock_data(,w_lock) /* covers wake_active (wake_lock())*/
441 decl_mutex_data(,rpc_lock) /* RPC lock (rpc_lock()) */
442
443 vm_offset_t kernel_stack; /* accurate only if the thread is
444 not swapped and not executing */
445
446 vm_offset_t stack_privilege;/* reserved kernel stack */
447
448 /* Blocking information */
449 int reason; /* why we blocked */
450 event_t wait_event; /* event we are waiting on */
451 kern_return_t wait_result; /* outcome of wait -
452 may be examined by this thread
453 WITHOUT locking */
454 queue_chain_t wait_link; /* event's wait queue link */
455 boolean_t wake_active; /* Someone is waiting for this
456 thread to become suspended */
457 int state; /* Thread state: */
458
459 /*
460 * Thread states [bits or'ed]
461 */
462 #define TH_WAIT 0x01 /* thread is queued for waiting */
463 #define TH_SUSP 0x02 /* thread has been asked to stop */
464 #define TH_RUN 0x04 /* thread is running or on runq */
465 #define TH_UNINT 0x08 /* thread is waiting uninteruptibly */
466 #define TH_HALTED 0x10 /* thread is halted at clean point ? */
467
468 #define TH_ABORT 0x20 /* abort interruptible waits */
469 #define TH_SWAPPED_OUT 0x40 /* thread is swapped out */
470
471 #define TH_IDLE 0x80 /* thread is an idle thread */
472
473 #define TH_SCHED_STATE (TH_WAIT|TH_SUSP|TH_RUN|TH_UNINT)
474
475 /* These two flags will never be seen and might well be removed */
476 #define TH_STACK_HANDOFF 0x0100 /* thread has no kernel stack */
477 #define TH_STACK_COMING_IN 0x0200 /* thread is waiting for kernel stack */
478 #define TH_STACK_STATE (TH_STACK_HANDOFF | TH_STACK_COMING_IN)
479
480 int preempt; /* Thread preemption status */
481 #define TH_PREEMPTABLE 0 /* Thread is preemptable */
482 #define TH_NOT_PREEMPTABLE 1 /* Thread is not preemptable */
483 #define TH_PREEMPTED 2 /* Thread has been preempted */
484
485 #if ETAP_EVENT_MONITOR
486 int etap_reason; /* real reason why we blocked */
487 boolean_t etap_trace; /* ETAP trace status */
488 #endif /* ETAP_EVENT_MONITOR */
489
490
491 /* Stack handoff information */
492 void (*continuation)(/* start here next time runnable */
493 void);
494
495 /* Scheduling information */
496 int priority; /* thread's priority */
497 int max_priority; /* maximum priority */
498 int sched_pri; /* scheduled (computed) priority */
499 int sched_data; /* for use by policy */
500 int policy; /* scheduling policy */
501 int depress_priority; /* depressed from this priority */
502 unsigned int cpu_usage; /* exp. decaying cpu usage [%cpu] */
503 unsigned int sched_usage; /* load-weighted cpu usage [sched] */
504 unsigned int sched_stamp; /* last time priority was updated */
505 unsigned int sleep_stamp; /* last time in TH_WAIT state */
506 unsigned int sched_change_stamp;
507 /* last time priority or policy was
508 explicitly changed (not the same
509 units as sched_stamp!) */
510 int unconsumed_quantum; /* leftover quantum (RR/FIFO) */
511
512 /* VM global variables */
513 boolean_t vm_privilege; /* can use reserved memory? */
514 vm_offset_t recover; /* page fault recovery (copyin/out) */
515
516 /* IPC data structures */
517 struct thread_shuttle *ith_next, *ith_prev;
518
519 struct ipc_kmsg_queue ith_messages;
520
521 decl_mutex_data(,ith_lock_data)
522 mach_port_t ith_mig_reply; /* reply port for mig */
523 struct ipc_port *ith_rpc_reply; /* reply port for kernel RPCs */
524
525 /* Various bits of stashed state */
526 union {
527 struct {
528 mach_msg_option_t option;
529 mach_msg_body_t *scatter_list;
530 mach_msg_size_t scatter_list_size;
531 } receive;
532 char *other; /* catch-all for other state */
533 } saved;
534
535 /* Timing data structures */
536 timer_data_t user_timer; /* user mode timer */
537 timer_data_t system_timer; /* system mode timer */
538 timer_data_t depressed_timer;/* depressed priority timer */
539 timer_save_data_t user_timer_save; /* saved user timer value */
540 timer_save_data_t system_timer_save; /* saved sys timer val. */
541 unsigned int cpu_delta; /* cpu usage since last update */
542 unsigned int sched_delta; /* weighted cpu usage since update */
543
544 /* Time-outs */
545 timer_elt_data_t timer; /* timer for thread */
546 timer_elt_data_t depress_timer; /* timer for priority depression */
547
548 /* Ast/Halt data structures */
549 boolean_t active; /* how alive is the thread */
550
551 /* Processor data structures */
552 processor_set_t processor_set; /* assigned processor set */
553 #if NCPUS > 1
554 processor_t bound_processor; /* bound to processor ?*/
555 #endif /* NCPUS > 1 */
556 #if MACH_HOST
557 boolean_t may_assign; /* may assignment change? */
558 boolean_t assign_active; /* someone waiting for may_assign */
559 #endif /* MACH_HOST */
560
561 #if XKMACHKERNEL
562 int xk_type;
563 #endif /* XKMACHKERNEL */
564
565 #if NCPUS > 1
566 processor_t last_processor; /* processor this last ran on */
567 #if MACH_LOCK_MON
568 unsigned lock_stack; /* number of locks held */
569 #endif /* MACH_LOCK_MON */
570 #endif /* NCPUS > 1 */
571
572 int at_safe_point; /* thread_abort_safely allowed */
573
574 #if MACH_LDEBUG
575 /*
576 * Debugging: track acquired mutexes and locks.
577 * Because a thread can block while holding such
578 * synchronizers, we think of the thread as
579 * "owning" them.
580 */
581 #define MUTEX_STACK_DEPTH 20
582 #define LOCK_STACK_DEPTH 20
583 mutex_t *mutex_stack[MUTEX_STACK_DEPTH];
584 lock_t *lock_stack[LOCK_STACK_DEPTH];
585 unsigned int mutex_stack_index;
586 unsigned int lock_stack_index;
587 unsigned mutex_count; /* XXX to be deleted XXX */
588 boolean_t kthread; /* thread is a kernel thread */
589 #endif /* MACH_LDEBUG */
590
591 #if LINUX_DEV
592 /*
593 * State for Linux device drivers
594 */
595 void *linux_data; /* used by linuxdev/mach/glue/block.c */
596 #endif /* LINUX_DEV */
597
598 /*
599 * End of thread_shuttle proper
600 */
601
602 /*
603 * Migration and thread_activation linkage information
604 */
605 struct thread_activation *top_act; /* "current" thr_act */
606
607
608 #endif
609
610
611 };
612
613 #define ith_wait_result wait_result
614
615 #define ith_option saved.receive.option
616 #define ith_scatter_list saved.receive.scatter_list
617 #define ith_scatter_list_size saved.receive.scatter_list_size
618 #define ith_task ith_td->td_proc->p_machdata
619 #define ith_map ith_td->td_proc->p_vmspace->vm_map
620 #define ith_other saved.other
621
622 #define thread_map(thread) (&(thread)->ith_td->td_proc->p_vmspace->vm_map)
623
624 static __inline thread_t
current_thread(void)625 current_thread(void)
626 {
627
628 return (curthread->td_machdata);
629 }
630
631
632 static __inline task_t
current_task(void)633 current_task(void)
634 {
635
636 return (curthread->td_proc->p_machdata);
637 }
638
639 #define current_space() current_task()->itk_space
640
641 #define current_act() current_thread()
642
643 static __inline vm_map_t
current_map(void)644 current_map(void)
645 {
646
647 return (&curthread->td_proc->p_vmspace->vm_map);
648 }
649
650 #define act_deallocate(act) thread_deallocate(act)
651 #define act_lock(act) mtx_lock(&(act)->ith_lock_data)
652 #define act_lock_try(act) mtx_trylock(&(act)->ith_lock_data)
653 #define act_unlock(act) mtx_unlock(&act->ith_lock_data)
654 #define act_locked_act_reference(act) ((act)->ref_count++)
655
656
657 /* wakeup a thread */
658 extern void thread_go(thread_t);
659 extern void thread_will_wait_with_timeout(thread_t, int);
660 extern void thread_will_wait(thread_t);
661 extern void thread_block(void);
662 #if 0
663 extern void assert_wait(event_t, boolean_t);
664 #else
665 #define assert_wait(a, b)
666 #endif
667 /*
668 * Possible results of assert_wait - returned in
669 * current_thread()->wait_result.
670 */
671 #define THREAD_WAITING -1
672 #define THREAD_AWAKENED 0 /* normal wakeup */
673 #define THREAD_TIMED_OUT 1 /* timeout expired */
674 #define THREAD_INTERRUPTED 2 /* interrupted by clear_wait */
675 #define THREAD_RESTART 3 /* restart operation entirely */
676 #define THREAD_NOT_WAITING 10
677
678
679 #endif
680