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