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 preemptab /*
421 * Beginning of thread_shuttle proper
422 */
423 queue_chain_t links; /* current run queue links */
424 run_queue_t runq; /* run queue p is on SEE BELOW */
425 int whichq; /* which queue level p is on */
426 /*
427 * NOTE: The runq field in the thread structure has an unusual
428 * locking protocol. If its value is RUN_QUEUE_NULL, then it is
429 * locked by the thread_lock, but if its value is something else
430 * (i.e. a run_queue) then it is locked by that run_queue's lock.
431 */
432
433 /* Thread bookkeeping */
434 queue_chain_t pset_threads; /* list of all shuttles in proc set */
435
436 /* Self-preservation */
437 decl_simple_lock_data(,lock) /* scheduling lock (thread_lock()) */
438 decl_simple_lock_data(,w_lock) /* covers wake_active (wake_lock())*/
439 decl_mutex_data(,rpc_lock) /* RPC lock (rpc_lock()) */
440
441 vm_offset_t kernel_stack; /* accurate only if the thread is
442 not swapped and not executing */
443
444 vm_offset_t stack_privilege;/* reserved kernel stack */
445
446 /* Blocking information */
447 int reason; /* why we blocked */
448 event_t wait_event; /* event we are waiting on */
449 kern_return_t wait_result; /* outcome of wait -
450 may be examined by this thread
451 WITHOUT locking */
452 queue_chain_t wait_link; /* event's wait queue link */
453 boolean_t wake_active; /* Someone is waiting for this
454 thread to become suspended */
455 int state; /* Thread state: */
456
457 /*
458 * Thread states [bits or'ed]
459 */
460 #define TH_WAIT 0x01 /* thread is queued for waiting */
461 #define TH_SUSP 0x02 /* thread has been asked to stop */
462 #define TH_RUN 0x04 /* thread is running or on runq */
463 #define TH_UNINT 0x08 /* thread is waiting uninteruptibly */
464 #define TH_HALTED 0x10 /* thread is halted at clean point ? */
465
466 #define TH_ABORT 0x20 /* abort interruptible waits */
467 #define TH_SWAPPED_OUT 0x40 /* thread is swapped out */
468
469 #define TH_IDLE 0x80 /* thread is an idle thread */
470
471 #define TH_SCHED_STATE (TH_WAIT|TH_SUSP|TH_RUN|TH_UNINT)
472
473 /* These two flags will never be seen and might well be removed */
474 #define TH_STACK_HANDOFF 0x0100 /* thread has no kernel stack */
475 #define TH_STACK_COMING_IN 0x0200 /* thread is waiting for kernel stack */
476 #define TH_STACK_STATE (TH_STACK_HANDOFF | TH_STACK_COMING_IN)
477
478 int preempt; /* Thread preemption status */
479 #define TH_PREEMPTABLE 0 /* Thread is preemptable */
480 #define TH_NOT_PREEMPTABLE 1 /* Thread is not preemptable */
481 #define TH_PREEMPTED 2 /* Thread has been preempted */
482
483 #if ETAP_EVENT_MONITOR
484 int etap_reason; /* real reason why we blocked */
485 boolean_t etap_trace; /* ETAP trace status */
486 #endif /* ETAP_EVENT_MONITOR */
487
488
489 /* Stack handoff information */
490 void (*continuation)(/* start here next time runnable */
491 void);
492
493 /* Scheduling information */
494 int priority; /* thread's priority */
495 int max_priority; /* maximum priority */
496 int sched_pri; /* scheduled (computed) priority */
497 int sched_data; /* for use by policy */
498 int policy; /* scheduling policy */
499 int depress_priority; /* depressed from this priority */
500 unsigned int cpu_usage; /* exp. decaying cpu usage [%cpu] */
501 unsigned int sched_usage; /* load-weighted cpu usage [sched] */
502 unsigned int sched_stamp; /* last time priority was updated */
503 unsigned int sleep_stamp; /* last time in TH_WAIT state */
504 unsigned int sched_change_stamp;
505 /* last time priority or policy was
506 explicitly changed (not the same
507 units as sched_stamp!) */
508 int unconsumed_quantum; /* leftover quantum (RR/FIFO) */
509
510 /* VM global variables */
511 boolean_t vm_privilege; /* can use reserved memory? */
512 vm_offset_t recover; /* page fault recovery (copyin/out) */
513
514 /* IPC data structures */
515 struct thread_shuttle *ith_next, *ith_prev;
516
517 struct ipc_kmsg_queue ith_messages;
518
519 decl_mutex_data(,ith_lock_data)
520 mach_port_t ith_mig_reply; /* reply port for mig */
521 struct ipc_port *ith_rpc_reply; /* reply port for kernel RPCs */
522
523 /* Various bits of stashed state */
524 union {
525 struct {
526 mach_msg_option_t option;
527 mach_msg_body_t *scatter_list;
528 mach_msg_size_t scatter_list_size;
529 } receive;
530 char *other; /* catch-all for other state */
531 } saved;
532
533 /* Timing data structures */
534 timer_data_t user_timer; /* user mode timer */
535 timer_data_t system_timer; /* system mode timer */
536 timer_data_t depressed_timer;/* depressed priority timer */
537 timer_save_data_t user_timer_save; /* saved user timer value */
538 timer_save_data_t system_timer_save; /* saved sys timer val. */
539 unsigned int cpu_delta; /* cpu usage since last update */
540 unsigned int sched_delta; /* weighted cpu usage since update */
541
542 /* Time-outs */
543 timer_elt_data_t timer; /* timer for thread */
544 timer_elt_data_t depress_timer; /* timer for priority depression */
545
546 /* Ast/Halt data structures */
547 boolean_t active; /* how alive is the thread */
548
549 /* Processor data structures */
550 processor_set_t processor_set; /* assigned processor set */
551 #if NCPUS > 1
552 processor_t bound_processor; /* bound to processor ?*/
553 #endif /* NCPUS > 1 */
554 #if MACH_HOST
555 boolean_t may_assign; /* may assignment change? */
556 boolean_t assign_active; /* someone waiting for may_assign */
557 #endif /* MACH_HOST */
558
559 #if XKMACHKERNEL
560 int xk_type;
561 #endif /* XKMACHKERNEL */
562
563 #if NCPUS > 1
564 processor_t last_processor; /* processor this last ran on */
565 #if MACH_LOCK_MON
566 unsigned lock_stack; /* number of locks held */
567 #endif /* MACH_LOCK_MON */
568 #endif /* NCPUS > 1 */
569
570 int at_safe_point; /* thread_abort_safely allowed */
571
572 #if MACH_LDEBUG
573 /*
574 * Debugging: track acquired mutexes and locks.
575 * Because a thread can block while holding such
576 * synchronizers, we think of the thread as
577 * "owning" them.
578 */
579 #define MUTEX_STACK_DEPTH 20
580 #define LOCK_STACK_DEPTH 20
581 mutex_t *mutex_stack[MUTEX_STACK_DEPTH];
582 lock_t *lock_stack[LOCK_STACK_DEPTH];
583 unsigned int mutex_stack_index;
584 unsigned int lock_stack_index;
585 unsigned mutex_count; /* XXX to be deleted XXX */
586 boolean_t kthread; /* thread is a kernel thread */
587 #endif /* MACH_LDEBUG */
588
589 #if LINUX_DEV
590 /*
591 * State for Linux device drivers
592 */
593 void *linux_data; /* used by linuxdev/mach/glue/block.c */
594 #endif /* LINUX_DEV */
595
596 /*
597 * End of thread_shuttle proper
598 */
599
600 /*
601 * Migration and thread_activation linkage information
602 */
603 struct thread_activation *top_act; /* "current" thr_act */
604
605
606 #endif
607
608
609 };
610
611 #define ith_wait_result wait_result
612
613 #define ith_option saved.receive.option
614 #define ith_scatter_list saved.receive.scatter_list
615 #define ith_scatter_list_size saved.receive.scatter_list_size
616 #define ith_task ith_td->td_proc->p_machdata
617 #define ith_map ith_td->td_proc->p_vmspace->vm_map
618 #define ith_other saved.other
619
620 #define thread_map(thread) (&(thread)->ith_td->td_proc->p_vmspace->vm_map)
621
622 static __inline thread_t
current_thread(void)623 current_thread(void)
624 {
625
626 return (curthread->td_machdata);
627 }
628
629
630 static __inline task_t
current_task(void)631 current_task(void)
632 {
633
634 return (curthread->td_proc->p_machdata);
635 }
636
637 #define current_space() current_task()->itk_space
638
639 #define current_act() current_thread()
640
641 static __inline vm_map_t
current_map(void)642 current_map(void)
643 {
644
645 return (&curthread->td_proc->p_vmspace->vm_map);
646 }
647
648 #define act_deallocate(act) thread_deallocate(act)
649 #define act_lock(act) mtx_lock(&(act)->ith_lock_data)
650 #define act_lock_try(act) mtx_trylock(&(act)->ith_lock_data)
651 #define act_unlock(act) mtx_unlock(&act->ith_lock_data)
652 #define act_locked_act_reference(act) ((act)->ref_count++)
653
654
655 /* wakeup a thread */
656 extern void thread_go(thread_t);
657 extern void thread_will_wait_with_timeout(thread_t, int);
658 extern void thread_will_wait(thread_t);
659 extern void thread_block(void);
660 #if 0
661 extern void assert_wait(event_t, boolean_t);
662 #else
663 #define assert_wait(a, b)
664 #endif
665 /*
666 * Possible results of assert_wait - returned in
667 * current_thread()->wait_result.
668 */
669 #define THREAD_WAITING -1
670 #define THREAD_AWAKENED 0 /* normal wakeup */
671 #define THREAD_TIMED_OUT 1 /* timeout expired */
672 #define THREAD_INTERRUPTED 2 /* interrupted by clear_wait */
673 #define THREAD_RESTART 3 /* restart operation entirely */
674 #define THREAD_NOT_WAITING 10
675
676
677 #endif
678