]> git.saurik.com Git - apple/xnu.git/blob - osfmk/kern/thread.h
xnu-792.6.61.tar.gz
[apple/xnu.git] / osfmk / kern / thread.h
1 /*
2 * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22 /*
23 * @OSF_FREE_COPYRIGHT@
24 */
25 /*
26 * Mach Operating System
27 * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
28 * All Rights Reserved.
29 *
30 * Permission to use, copy, modify and distribute this software and its
31 * documentation is hereby granted, provided that both the copyright
32 * notice and this permission notice appear in all copies of the
33 * software, derivative works or modified versions, and any portions
34 * thereof, and that both notices appear in supporting documentation.
35 *
36 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
37 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
38 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
39 *
40 * Carnegie Mellon requests users of this software to return to
41 *
42 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
43 * School of Computer Science
44 * Carnegie Mellon University
45 * Pittsburgh PA 15213-3890
46 *
47 * any improvements or extensions that they make and grant Carnegie Mellon
48 * the rights to redistribute these changes.
49 */
50 /*
51 */
52 /*
53 * File: thread.h
54 * Author: Avadis Tevanian, Jr.
55 *
56 * This file contains the structure definitions for threads.
57 *
58 */
59 /*
60 * Copyright (c) 1993 The University of Utah and
61 * the Computer Systems Laboratory (CSL). All rights reserved.
62 *
63 * Permission to use, copy, modify and distribute this software and its
64 * documentation is hereby granted, provided that both the copyright
65 * notice and this permission notice appear in all copies of the
66 * software, derivative works or modified versions, and any portions
67 * thereof, and that both notices appear in supporting documentation.
68 *
69 * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS
70 * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF
71 * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
72 *
73 * CSL requests users of this software to return to csl-dist@cs.utah.edu any
74 * improvements that they make and grant CSL redistribution rights.
75 *
76 */
77
78 #ifndef _KERN_THREAD_H_
79 #define _KERN_THREAD_H_
80
81 #include <mach/kern_return.h>
82 #include <mach/mach_types.h>
83 #include <mach/message.h>
84 #include <mach/boolean.h>
85 #include <mach/vm_param.h>
86 #include <mach/thread_info.h>
87 #include <mach/thread_status.h>
88 #include <mach/exception_types.h>
89
90 #include <kern/kern_types.h>
91
92 #include <sys/cdefs.h>
93
94 #ifdef MACH_KERNEL_PRIVATE
95
96 #include <cputypes.h>
97
98 #include <mach_assert.h>
99 #include <mach_host.h>
100 #include <mach_prof.h>
101 #include <mach_ldebug.h>
102
103 #include <ipc/ipc_types.h>
104
105 #include <mach/port.h>
106 #include <kern/cpu_number.h>
107 #include <kern/queue.h>
108 #include <kern/timer.h>
109 #include <kern/lock.h>
110 #include <kern/locks.h>
111 #include <kern/sched.h>
112 #include <kern/sched_prim.h>
113 #include <kern/thread_call.h>
114 #include <kern/timer_call.h>
115 #include <kern/task.h>
116 #include <kern/exception.h>
117
118 #include <ipc/ipc_kmsg.h>
119
120 #include <machine/cpu_data.h>
121 #include <machine/thread.h>
122
123 struct thread {
124 /*
125 * NOTE: The runq field in the thread structure has an unusual
126 * locking protocol. If its value is RUN_QUEUE_NULL, then it is
127 * locked by the thread_lock, but if its value is something else
128 * (i.e. a run_queue) then it is locked by that run_queue's lock.
129 *
130 * When the thread is on a wait queue, these first three fields
131 * are treated as an unofficial union with a wait_queue_element.
132 * If you change these, you must change that definition as well
133 * (kern/wait_queue.h).
134 */
135 /* Items examined often, modified infrequently */
136 queue_chain_t links; /* run/wait queue links */
137 run_queue_t runq; /* run queue thread is on SEE BELOW */
138 wait_queue_t wait_queue; /* wait queue we are currently on */
139 event64_t wait_event; /* wait queue event */
140 integer_t options; /* options set by thread itself */
141 #define TH_OPT_INTMASK 0x03 /* interrupt / abort level */
142 #define TH_OPT_VMPRIV 0x04 /* may allocate reserved memory */
143 #define TH_OPT_DELAYIDLE 0x08 /* performing delayed idle */
144 #define TH_OPT_CALLOUT 0x10 /* executing as callout */
145
146 /* Data updated during assert_wait/thread_wakeup */
147 decl_simple_lock_data(,sched_lock) /* scheduling lock (thread_lock()) */
148 decl_simple_lock_data(,wake_lock) /* covers wake_active (wake_lock())*/
149 boolean_t wake_active; /* Someone is waiting for this */
150 int at_safe_point; /* thread_abort_safely allowed */
151 ast_t reason; /* why we blocked */
152 wait_result_t wait_result; /* outcome of wait -
153 * may be examined by this thread
154 * WITHOUT locking */
155 thread_continue_t continuation; /* continue here next dispatch */
156 void *parameter; /* continuation parameter */
157
158 /* Data updated/used in thread_invoke */
159 struct funnel_lock *funnel_lock; /* Non-reentrancy funnel */
160 int funnel_state;
161 #define TH_FN_OWNED 0x1 /* we own the funnel */
162 #define TH_FN_REFUNNEL 0x2 /* re-acquire funnel on dispatch */
163
164 vm_offset_t kernel_stack; /* current kernel stack */
165 vm_offset_t reserved_stack; /* reserved kernel stack */
166
167 /* Thread state: */
168 int state;
169 /*
170 * Thread states [bits or'ed]
171 */
172 #define TH_WAIT 0x01 /* queued for waiting */
173 #define TH_SUSP 0x02 /* stopped or requested to stop */
174 #define TH_RUN 0x04 /* running or on runq */
175 #define TH_UNINT 0x08 /* waiting uninteruptibly */
176 #define TH_TERMINATE 0x10 /* halted at termination */
177
178 #define TH_ABORT 0x20 /* abort interruptible waits */
179 #define TH_ABORT_SAFELY 0x40 /* ... but only those at safe point */
180
181 #define TH_IDLE 0x80 /* processor idle thread */
182
183 #define TH_SCHED_STATE (TH_WAIT|TH_SUSP|TH_RUN|TH_UNINT)
184
185 /* Scheduling information */
186 integer_t sched_mode; /* scheduling mode bits */
187 #define TH_MODE_REALTIME 0x0001 /* time constraints supplied */
188 #define TH_MODE_TIMESHARE 0x0002 /* use timesharing algorithm */
189 #define TH_MODE_PREEMPT 0x0004 /* can preempt kernel contexts */
190 #define TH_MODE_FAILSAFE 0x0008 /* fail-safe has tripped */
191 #define TH_MODE_PROMOTED 0x0010 /* sched pri has been promoted */
192 #define TH_MODE_DEPRESS 0x0020 /* normal depress yield */
193 #define TH_MODE_POLLDEPRESS 0x0040 /* polled depress yield */
194 #define TH_MODE_ISDEPRESSED (TH_MODE_DEPRESS | TH_MODE_POLLDEPRESS)
195
196 integer_t sched_pri; /* scheduled (current) priority */
197 integer_t priority; /* base priority */
198 integer_t max_priority; /* max base priority */
199 integer_t task_priority; /* copy of task base priority */
200
201 integer_t promotions; /* level of promotion */
202 integer_t pending_promoter_index;
203 void *pending_promoter[2];
204
205 integer_t importance; /* task-relative importance */
206
207 /* real-time parameters */
208 struct { /* see mach/thread_policy.h */
209 uint32_t period;
210 uint32_t computation;
211 uint32_t constraint;
212 boolean_t preemptible;
213
214 uint64_t deadline;
215 } realtime;
216
217 uint32_t current_quantum; /* duration of current quantum */
218
219 /* Data used during setrun/dispatch */
220 timer_data_t system_timer; /* system mode timer */
221 processor_set_t processor_set; /* assigned processor set */
222 processor_t bound_processor; /* bound to a processor? */
223 processor_t last_processor; /* processor last dispatched on */
224 uint64_t last_switch; /* time of last context switch */
225
226 /* Fail-safe computation since last unblock or qualifying yield */
227 uint64_t computation_metered;
228 uint64_t computation_epoch;
229 integer_t safe_mode; /* saved mode during fail-safe */
230 natural_t safe_release; /* when to release fail-safe */
231
232 /* Statistics and timesharing calculations */
233 natural_t sched_stamp; /* last scheduler tick */
234 natural_t sched_usage; /* timesharing cpu usage [sched] */
235 natural_t pri_shift; /* usage -> priority from pset */
236 natural_t cpu_usage; /* instrumented cpu usage [%cpu] */
237 natural_t cpu_delta; /* accumulated cpu_usage delta */
238
239 /* Timing data structures */
240 timer_data_t user_timer; /* user mode timer */
241 uint64_t system_timer_save; /* saved system timer value */
242 uint64_t user_timer_save; /* saved user timer value */
243
244 /* Timed wait expiration */
245 timer_call_data_t wait_timer;
246 integer_t wait_timer_active;
247 boolean_t wait_timer_is_set;
248
249 /* Priority depression expiration */
250 timer_call_data_t depress_timer;
251 integer_t depress_timer_active;
252
253 /* Various bits of stashed state */
254 union {
255 struct {
256 mach_msg_return_t state; /* receive state */
257 ipc_object_t object; /* object received on */
258 mach_vm_address_t msg_addr; /* receive buffer pointer */
259 mach_msg_size_t msize; /* max size for recvd msg */
260 mach_msg_option_t option; /* options for receive */
261 mach_msg_size_t slist_size; /* scatter list size */
262 struct ipc_kmsg *kmsg; /* received message */
263 mach_port_seqno_t seqno; /* seqno of recvd message */
264 mach_msg_continue_t continuation;
265 } receive;
266 struct {
267 struct semaphore *waitsemaphore; /* semaphore ref */
268 struct semaphore *signalsemaphore; /* semaphore ref */
269 int options; /* semaphore options */
270 kern_return_t result; /* primary result */
271 mach_msg_continue_t continuation;
272 } sema;
273 struct {
274 int option; /* switch option */
275 } swtch;
276 int misc; /* catch-all for other state */
277 } saved;
278
279 /* IPC data structures */
280 struct ipc_kmsg_queue ith_messages;
281 mach_port_t ith_rpc_reply; /* reply port for kernel RPCs */
282
283 /* Ast/Halt data structures */
284 vm_offset_t recover; /* page fault recover(copyin/out) */
285 int ref_count; /* number of references to me */
286
287 /* Processor set info */
288 queue_chain_t pset_threads; /* list of all threads in pset */
289 #if MACH_HOST
290 boolean_t may_assign; /* may assignment change? */
291 boolean_t assign_active; /* waiting for may_assign */
292 #endif /* MACH_HOST */
293
294 /* Activation */
295 queue_chain_t task_threads;
296
297 /*** Machine-dependent state ***/
298 struct machine_thread machine;
299
300 /* Task membership */
301 struct task *task;
302 vm_map_t map;
303
304 decl_mutex_data(,mutex)
305
306 /* Kernel holds on this thread */
307 int suspend_count;
308
309 /* User level suspensions */
310 int user_stop_count;
311
312 /* Pending thread ast(s) */
313 ast_t ast;
314
315 /* Miscellaneous bits guarded by mutex */
316 uint32_t
317 /* Indicates that the thread has not been terminated */
318 active:1,
319
320 /* Indicates that the thread has been started after creation */
321 started:1,
322 :0;
323
324 /* Return Handers */
325 struct ReturnHandler {
326 struct ReturnHandler *next;
327 void (*handler)(
328 struct ReturnHandler *rh,
329 struct thread *thread);
330 } *handlers, special_handler;
331
332 /* Ports associated with this thread */
333 struct ipc_port *ith_self; /* not a right, doesn't hold ref */
334 struct ipc_port *ith_sself; /* a send right */
335 struct exception_action exc_actions[EXC_TYPES_COUNT];
336
337 /* Owned ulocks (a lock set element) */
338 queue_head_t held_ulocks;
339
340 #if MACH_PROF
341 /* Profiling */
342 boolean_t profiled;
343 boolean_t profiled_own;
344 struct prof_data *profil_buffer;
345 #endif /* MACH_PROF */
346
347 #ifdef MACH_BSD
348 void *uthread;
349 #endif
350 };
351
352 #define ith_state saved.receive.state
353 #define ith_object saved.receive.object
354 #define ith_msg_addr saved.receive.msg_addr
355 #define ith_msize saved.receive.msize
356 #define ith_option saved.receive.option
357 #define ith_scatter_list_size saved.receive.slist_size
358 #define ith_continuation saved.receive.continuation
359 #define ith_kmsg saved.receive.kmsg
360 #define ith_seqno saved.receive.seqno
361
362 #define sth_waitsemaphore saved.sema.waitsemaphore
363 #define sth_signalsemaphore saved.sema.signalsemaphore
364 #define sth_options saved.sema.options
365 #define sth_result saved.sema.result
366 #define sth_continuation saved.sema.continuation
367
368 extern void thread_bootstrap(void);
369
370 extern void thread_init(void);
371
372 extern void thread_daemon_init(void);
373
374 #define thread_reference_internal(thread) \
375 hw_atomic_add(&(thread)->ref_count, 1)
376
377 #define thread_deallocate_internal(thread) \
378 hw_atomic_sub(&(thread)->ref_count, 1)
379
380 #define thread_reference(thread) \
381 MACRO_BEGIN \
382 if ((thread) != THREAD_NULL) \
383 thread_reference_internal(thread); \
384 MACRO_END
385
386 extern void thread_deallocate(
387 thread_t thread);
388
389 extern void thread_terminate_self(void);
390
391 extern kern_return_t thread_terminate_internal(
392 thread_t thread);
393
394 extern void thread_terminate_enqueue(
395 thread_t thread);
396
397 extern void thread_stack_enqueue(
398 thread_t thread);
399
400 extern void thread_hold(
401 thread_t thread);
402
403 extern void thread_release(
404 thread_t thread);
405
406 #define thread_lock_init(th) simple_lock_init(&(th)->sched_lock, 0)
407 #define thread_lock(th) simple_lock(&(th)->sched_lock)
408 #define thread_unlock(th) simple_unlock(&(th)->sched_lock)
409 #define thread_lock_try(th) simple_lock_try(&(th)->sched_lock)
410
411 #define thread_should_halt_fast(thread) (!(thread)->active)
412
413 #define wake_lock_init(th) simple_lock_init(&(th)->wake_lock, 0)
414 #define wake_lock(th) simple_lock(&(th)->wake_lock)
415 #define wake_unlock(th) simple_unlock(&(th)->wake_lock)
416 #define wake_lock_try(th) simple_lock_try(&(th)->wake_lock)
417
418 extern void stack_alloc(
419 thread_t thread);
420
421 extern void stack_free(
422 thread_t thread);
423
424 extern void stack_free_stack(
425 vm_offset_t stack);
426
427 extern boolean_t stack_alloc_try(
428 thread_t thread);
429
430 extern void stack_collect(void);
431
432 extern void stack_init(void);
433
434 extern kern_return_t thread_state_initialize(
435 thread_t thread);
436
437 extern kern_return_t thread_setstatus(
438 thread_t thread,
439 int flavor,
440 thread_state_t tstate,
441 mach_msg_type_number_t count);
442
443 extern kern_return_t thread_getstatus(
444 thread_t thread,
445 int flavor,
446 thread_state_t tstate,
447 mach_msg_type_number_t *count);
448
449 extern kern_return_t thread_info_internal(
450 thread_t thread,
451 thread_flavor_t flavor,
452 thread_info_t thread_info_out,
453 mach_msg_type_number_t *thread_info_count);
454
455 extern void thread_task_priority(
456 thread_t thread,
457 integer_t priority,
458 integer_t max_priority);
459
460 extern void thread_policy_reset(
461 thread_t thread);
462
463 extern kern_return_t kernel_thread_create(
464 thread_continue_t continuation,
465 void *parameter,
466 integer_t priority,
467 thread_t *new_thread);
468
469 extern kern_return_t kernel_thread_start_priority(
470 thread_continue_t continuation,
471 void *parameter,
472 integer_t priority,
473 thread_t *new_thread);
474
475 extern void machine_stack_attach(
476 thread_t thread,
477 vm_offset_t stack);
478
479 extern vm_offset_t machine_stack_detach(
480 thread_t thread);
481
482 extern void machine_stack_handoff(
483 thread_t old,
484 thread_t new);
485
486 extern thread_t machine_switch_context(
487 thread_t old_thread,
488 thread_continue_t continuation,
489 thread_t new_thread);
490
491 extern void machine_load_context(
492 thread_t thread);
493
494 extern kern_return_t machine_thread_state_initialize(
495 thread_t thread);
496
497 extern kern_return_t machine_thread_set_state(
498 thread_t thread,
499 thread_flavor_t flavor,
500 thread_state_t state,
501 mach_msg_type_number_t count);
502
503 extern kern_return_t machine_thread_get_state(
504 thread_t thread,
505 thread_flavor_t flavor,
506 thread_state_t state,
507 mach_msg_type_number_t *count);
508
509 extern kern_return_t machine_thread_dup(
510 thread_t self,
511 thread_t target);
512
513 extern void machine_thread_init(void);
514
515 extern kern_return_t machine_thread_create(
516 thread_t thread,
517 task_t task);
518
519 extern void machine_thread_destroy(
520 thread_t thread);
521
522 extern void machine_set_current_thread(
523 thread_t thread);
524
525 extern void machine_thread_terminate_self(void);
526
527 extern kern_return_t machine_thread_get_kern_state(
528 thread_t thread,
529 thread_flavor_t flavor,
530 thread_state_t tstate,
531 mach_msg_type_number_t *count);
532
533
534 /*
535 * XXX Funnel locks XXX
536 */
537
538 struct funnel_lock {
539 int fnl_type; /* funnel type */
540 lck_mtx_t *fnl_mutex; /* underlying mutex for the funnel */
541 void * fnl_mtxholder; /* thread (last)holdng mutex */
542 void * fnl_mtxrelease; /* thread (last)releasing mutex */
543 lck_mtx_t *fnl_oldmutex; /* Mutex before collapsing split funnel */
544 };
545
546 typedef struct ReturnHandler ReturnHandler;
547
548 #define thread_mtx_lock(thread) mutex_lock(&(thread)->mutex)
549 #define thread_mtx_try(thread) mutex_try(&(thread)->mutex)
550 #define thread_mtx_unlock(thread) mutex_unlock(&(thread)->mutex)
551
552 extern void act_execute_returnhandlers(void);
553
554 extern void install_special_handler(
555 thread_t thread);
556
557 extern void special_handler(
558 ReturnHandler *rh,
559 thread_t thread);
560
561 #else /* MACH_KERNEL_PRIVATE */
562
563 __BEGIN_DECLS
564
565 extern thread_t current_thread(void);
566
567 extern void thread_reference(
568 thread_t thread);
569
570 extern void thread_deallocate(
571 thread_t thread);
572
573 __END_DECLS
574
575 #endif /* MACH_KERNEL_PRIVATE */
576
577 #ifdef KERNEL_PRIVATE
578
579 typedef struct funnel_lock funnel_t;
580
581 #ifdef MACH_KERNEL_PRIVATE
582
583 extern void funnel_lock(
584 funnel_t *lock);
585
586 extern void funnel_unlock(
587 funnel_t *lock);
588
589 vm_offset_t min_valid_stack_address(void);
590 vm_offset_t max_valid_stack_address(void);
591
592 #endif /* MACH_KERNEL_PRIVATE */
593
594 __BEGIN_DECLS
595
596 extern funnel_t *thread_funnel_get(void);
597
598 extern boolean_t thread_funnel_set(
599 funnel_t *lock,
600 boolean_t funneled);
601
602 extern thread_t kernel_thread(
603 task_t task,
604 void (*start)(void));
605
606 __END_DECLS
607
608 #endif /* KERNEL_PRIVATE */
609
610 __BEGIN_DECLS
611
612 #ifdef XNU_KERNEL_PRIVATE
613
614 /*
615 * XXX Funnel locks XXX
616 */
617
618 #define THR_FUNNEL_NULL (funnel_t *)0
619
620 extern funnel_t *funnel_alloc(
621 int type);
622
623 extern void funnel_free(
624 funnel_t *lock);
625
626 extern void thread_read_times(
627 thread_t thread,
628 time_value_t *user_time,
629 time_value_t *system_time);
630
631 extern void thread_setuserstack(
632 thread_t thread,
633 mach_vm_offset_t user_stack);
634
635 extern uint64_t thread_adjuserstack(
636 thread_t thread,
637 int adjust);
638
639 extern void thread_setentrypoint(
640 thread_t thread,
641 mach_vm_offset_t entry);
642
643 extern kern_return_t thread_wire_internal(
644 host_priv_t host_priv,
645 thread_t thread,
646 boolean_t wired,
647 boolean_t *prev_state);
648
649 /* JMM - These are only temporary */
650 extern boolean_t is_thread_running(thread_t); /* True is TH_RUN */
651 extern boolean_t is_thread_idle(thread_t); /* True is TH_IDLE */
652
653 extern kern_return_t thread_dup(thread_t);
654
655 extern task_t get_threadtask(thread_t);
656
657 extern void *get_bsdthread_info(thread_t);
658 extern void set_bsdthread_info(thread_t, void *);
659 extern void *uthread_alloc(task_t, thread_t);
660 extern void uthread_free(task_t, void *, void *);
661
662 extern boolean_t thread_should_halt(
663 thread_t thread);
664
665 #endif /* XNU_KERNEL_PRIVATE */
666
667 extern kern_return_t kernel_thread_start(
668 thread_continue_t continuation,
669 void *parameter,
670 thread_t *new_thread);
671
672 __END_DECLS
673
674 #endif /* _KERN_THREAD_H_ */