2 * Copyright (c) 2000-2007 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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 License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 * @OSF_FREE_COPYRIGHT@
32 * Mach Operating System
33 * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
34 * All Rights Reserved.
36 * Permission to use, copy, modify and distribute this software and its
37 * documentation is hereby granted, provided that both the copyright
38 * notice and this permission notice appear in all copies of the
39 * software, derivative works or modified versions, and any portions
40 * thereof, and that both notices appear in supporting documentation.
42 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
43 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
44 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
46 * Carnegie Mellon requests users of this software to return to
48 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
49 * School of Computer Science
50 * Carnegie Mellon University
51 * Pittsburgh PA 15213-3890
53 * any improvements or extensions that they make and grant Carnegie Mellon
54 * the rights to redistribute these changes.
60 * Author: Avadis Tevanian, Jr.
62 * This file contains the structure definitions for threads.
66 * Copyright (c) 1993 The University of Utah and
67 * the Computer Systems Laboratory (CSL). All rights reserved.
69 * Permission to use, copy, modify and distribute this software and its
70 * documentation is hereby granted, provided that both the copyright
71 * notice and this permission notice appear in all copies of the
72 * software, derivative works or modified versions, and any portions
73 * thereof, and that both notices appear in supporting documentation.
75 * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS
76 * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF
77 * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
79 * CSL requests users of this software to return to csl-dist@cs.utah.edu any
80 * improvements that they make and grant CSL redistribution rights.
84 #ifndef _KERN_THREAD_H_
85 #define _KERN_THREAD_H_
87 #include <mach/kern_return.h>
88 #include <mach/mach_types.h>
89 #include <mach/message.h>
90 #include <mach/boolean.h>
91 #include <mach/vm_param.h>
92 #include <mach/thread_info.h>
93 #include <mach/thread_status.h>
94 #include <mach/exception_types.h>
96 #include <kern/kern_types.h>
98 #include <sys/cdefs.h>
100 #ifdef MACH_KERNEL_PRIVATE
102 #include <cputypes.h>
104 #include <mach_assert.h>
105 #include <mach_ldebug.h>
107 #include <ipc/ipc_types.h>
109 #include <mach/port.h>
110 #include <kern/cpu_number.h>
111 #include <kern/queue.h>
112 #include <kern/timer.h>
113 #include <kern/lock.h>
114 #include <kern/locks.h>
115 #include <kern/sched.h>
116 #include <kern/sched_prim.h>
117 #include <kern/thread_call.h>
118 #include <kern/timer_call.h>
119 #include <kern/task.h>
120 #include <kern/exception.h>
121 #include <kern/affinity.h>
123 #include <ipc/ipc_kmsg.h>
125 #include <machine/cpu_data.h>
126 #include <machine/thread.h>
130 * NOTE: The runq field in the thread structure has an unusual
131 * locking protocol. If its value is PROCESSOR_NULL, then it is
132 * locked by the thread_lock, but if its value is something else
133 * then it is locked by the associated run queue lock.
135 * When the thread is on a wait queue, these first three fields
136 * are treated as an unofficial union with a wait_queue_element.
137 * If you change these, you must change that definition as well
138 * (kern/wait_queue.h).
140 /* Items examined often, modified infrequently */
141 queue_chain_t links
; /* run/wait queue links */
142 processor_t runq
; /* run queue assignment */
143 wait_queue_t wait_queue
; /* wait queue we are currently on */
144 event64_t wait_event
; /* wait queue event */
145 integer_t options
; /* options set by thread itself */
146 #define TH_OPT_INTMASK 0x03 /* interrupt / abort level */
147 #define TH_OPT_VMPRIV 0x04 /* may allocate reserved memory */
148 #define TH_OPT_DTRACE 0x08 /* executing under dtrace_probe */
150 /* Data updated during assert_wait/thread_wakeup */
151 decl_simple_lock_data(,sched_lock
) /* scheduling lock (thread_lock()) */
152 decl_simple_lock_data(,wake_lock
) /* for thread stop / wait (wake_lock()) */
153 boolean_t wake_active
; /* wake event on stop */
154 int at_safe_point
; /* thread_abort_safely allowed */
155 ast_t reason
; /* why we blocked */
156 wait_result_t wait_result
; /* outcome of wait -
157 * may be examined by this thread
159 thread_continue_t continuation
; /* continue here next dispatch */
160 void *parameter
; /* continuation parameter */
162 /* Data updated/used in thread_invoke */
163 struct funnel_lock
*funnel_lock
; /* Non-reentrancy funnel */
165 #define TH_FN_OWNED 0x1 /* we own the funnel */
166 #define TH_FN_REFUNNEL 0x2 /* re-acquire funnel on dispatch */
168 vm_offset_t kernel_stack
; /* current kernel stack */
169 vm_offset_t reserved_stack
; /* reserved kernel stack */
174 * Thread states [bits or'ed]
176 #define TH_WAIT 0x01 /* queued for waiting */
177 #define TH_SUSP 0x02 /* stopped or requested to stop */
178 #define TH_RUN 0x04 /* running or on runq */
179 #define TH_UNINT 0x08 /* waiting uninteruptibly */
180 #define TH_TERMINATE 0x10 /* halted at termination */
182 #define TH_IDLE 0x80 /* idling processor */
184 /* Scheduling information */
185 integer_t sched_mode
; /* scheduling mode bits */
186 #define TH_MODE_REALTIME 0x0001 /* time constraints supplied */
187 #define TH_MODE_TIMESHARE 0x0002 /* use timesharing algorithm */
188 #define TH_MODE_PREEMPT 0x0004 /* can preempt kernel contexts */
189 #define TH_MODE_FAILSAFE 0x0008 /* fail-safe has tripped */
190 #define TH_MODE_PROMOTED 0x0010 /* sched pri has been promoted */
191 #define TH_MODE_ABORT 0x0020 /* abort interruptible waits */
192 #define TH_MODE_ABORTSAFELY 0x0040 /* ... but only those at safe point */
193 #define TH_MODE_ISABORTED (TH_MODE_ABORT | TH_MODE_ABORTSAFELY)
194 #define TH_MODE_DEPRESS 0x0080 /* normal depress yield */
195 #define TH_MODE_POLLDEPRESS 0x0100 /* polled depress yield */
196 #define TH_MODE_ISDEPRESSED (TH_MODE_DEPRESS | TH_MODE_POLLDEPRESS)
198 integer_t sched_pri
; /* scheduled (current) priority */
199 integer_t priority
; /* base priority */
200 integer_t max_priority
; /* max base priority */
201 integer_t task_priority
; /* copy of task base priority */
203 integer_t promotions
; /* level of promotion */
204 integer_t pending_promoter_index
;
205 void *pending_promoter
[2];
207 integer_t importance
; /* task-relative importance */
209 /* real-time parameters */
210 struct { /* see mach/thread_policy.h */
212 uint32_t computation
;
214 boolean_t preemptible
;
219 uint32_t current_quantum
; /* duration of current quantum */
221 /* Data used during setrun/dispatch */
222 timer_data_t system_timer
; /* system mode timer */
223 processor_t bound_processor
; /* bound to a processor? */
224 processor_t last_processor
; /* processor last dispatched on */
225 uint64_t last_switch
; /* time of last context switch */
227 /* Fail-safe computation since last unblock or qualifying yield */
228 uint64_t computation_metered
;
229 uint64_t computation_epoch
;
230 integer_t safe_mode
; /* saved mode during fail-safe */
231 natural_t safe_release
; /* when to release fail-safe */
233 /* Call out from scheduler */
238 /* Statistics and timesharing calculations */
239 natural_t sched_stamp
; /* last scheduler tick */
240 natural_t sched_usage
; /* timesharing cpu usage [sched] */
241 natural_t pri_shift
; /* usage -> priority from pset */
242 natural_t cpu_usage
; /* instrumented cpu usage [%cpu] */
243 natural_t cpu_delta
; /* accumulated cpu_usage delta */
244 uint32_t c_switch
; /* total context switches */
245 uint32_t p_switch
; /* total processor switches */
246 uint32_t ps_switch
; /* total pset switches */
248 /* Timing data structures */
249 timer_data_t user_timer
; /* user mode timer */
250 uint64_t user_timer_save
; /* saved user timer value */
251 uint64_t system_timer_save
; /* saved system timer value */
252 uint64_t vtimer_user_save
; /* saved values for vtimers */
253 uint64_t vtimer_prof_save
;
254 uint64_t vtimer_rlim_save
;
256 /* Timed wait expiration */
257 timer_call_data_t wait_timer
;
258 integer_t wait_timer_active
;
259 boolean_t wait_timer_is_set
;
261 /* Priority depression expiration */
262 timer_call_data_t depress_timer
;
263 integer_t depress_timer_active
;
266 * Processor/cache affinity
267 * - affinity_threads links task threads with the same affinity set
269 affinity_set_t affinity_set
;
270 queue_chain_t affinity_threads
;
272 /* Various bits of stashed state */
275 mach_msg_return_t state
; /* receive state */
276 ipc_object_t object
; /* object received on */
277 mach_vm_address_t msg_addr
; /* receive buffer pointer */
278 mach_msg_size_t msize
; /* max size for recvd msg */
279 mach_msg_option_t option
; /* options for receive */
280 mach_msg_size_t slist_size
; /* scatter list size */
281 struct ipc_kmsg
*kmsg
; /* received message */
282 mach_port_seqno_t seqno
; /* seqno of recvd message */
283 mach_msg_continue_t continuation
;
286 struct semaphore
*waitsemaphore
; /* semaphore ref */
287 struct semaphore
*signalsemaphore
; /* semaphore ref */
288 int options
; /* semaphore options */
289 kern_return_t result
; /* primary result */
290 mach_msg_continue_t continuation
;
293 int option
; /* switch option */
295 int misc
; /* catch-all for other state */
298 /* IPC data structures */
299 struct ipc_kmsg_queue ith_messages
;
300 mach_port_t ith_rpc_reply
; /* reply port for kernel RPCs */
302 /* Ast/Halt data structures */
303 vm_offset_t recover
; /* page fault recover(copyin/out) */
304 uint32_t ref_count
; /* number of references to me */
306 queue_chain_t threads
; /* global list of all threads */
309 queue_chain_t task_threads
;
311 /*** Machine-dependent state ***/
312 struct machine_thread machine
;
314 /* Task membership */
318 decl_mutex_data(,mutex
)
320 /* Kernel holds on this thread */
323 /* User level suspensions */
326 /* Pending thread ast(s) */
329 /* Miscellaneous bits guarded by mutex */
331 active
:1, /* Thread is active and has not been terminated */
332 started
:1, /* Thread has been started after creation */
333 static_param
:1, /* Disallow policy parameter changes */
337 struct ReturnHandler
{
338 struct ReturnHandler
*next
;
340 struct ReturnHandler
*rh
,
341 struct thread
*thread
);
342 } *handlers
, special_handler
;
344 /* Ports associated with this thread */
345 struct ipc_port
*ith_self
; /* not a right, doesn't hold ref */
346 struct ipc_port
*ith_sself
; /* a send right */
347 struct exception_action exc_actions
[EXC_TYPES_COUNT
];
349 /* Owned ulocks (a lock set element) */
350 queue_head_t held_ulocks
;
357 uint32_t t_dtrace_predcache
;/* DTrace per thread predicate value hint */
358 int64_t t_dtrace_tracing
; /* Thread time under dtrace_probe() */
359 int64_t t_dtrace_vtime
;
361 uint32_t t_chud
; /* CHUD flags, used for Shark */
364 #define ith_state saved.receive.state
365 #define ith_object saved.receive.object
366 #define ith_msg_addr saved.receive.msg_addr
367 #define ith_msize saved.receive.msize
368 #define ith_option saved.receive.option
369 #define ith_scatter_list_size saved.receive.slist_size
370 #define ith_continuation saved.receive.continuation
371 #define ith_kmsg saved.receive.kmsg
372 #define ith_seqno saved.receive.seqno
374 #define sth_waitsemaphore saved.sema.waitsemaphore
375 #define sth_signalsemaphore saved.sema.signalsemaphore
376 #define sth_options saved.sema.options
377 #define sth_result saved.sema.result
378 #define sth_continuation saved.sema.continuation
380 extern void thread_bootstrap(void) __attribute__((section("__TEXT, initcode")));
382 extern void thread_init(void) __attribute__((section("__TEXT, initcode")));
384 extern void thread_daemon_init(void);
386 #define thread_reference_internal(thread) \
387 (void)hw_atomic_add(&(thread)->ref_count, 1)
389 #define thread_deallocate_internal(thread) \
390 hw_atomic_sub(&(thread)->ref_count, 1)
392 #define thread_reference(thread) \
394 if ((thread) != THREAD_NULL) \
395 thread_reference_internal(thread); \
398 extern void thread_deallocate(
401 extern void thread_terminate_self(void);
403 extern kern_return_t
thread_terminate_internal(
406 extern void thread_start_internal(
407 thread_t thread
) __attribute__ ((noinline
));
409 extern void thread_terminate_enqueue(
412 extern void thread_stack_enqueue(
415 extern void thread_hold(
418 extern void thread_release(
421 #define thread_lock_init(th) simple_lock_init(&(th)->sched_lock, 0)
422 #define thread_lock(th) simple_lock(&(th)->sched_lock)
423 #define thread_unlock(th) simple_unlock(&(th)->sched_lock)
425 #define wake_lock_init(th) simple_lock_init(&(th)->wake_lock, 0)
426 #define wake_lock(th) simple_lock(&(th)->wake_lock)
427 #define wake_unlock(th) simple_unlock(&(th)->wake_lock)
429 #define thread_should_halt_fast(thread) (!(thread)->active)
431 extern void stack_alloc(
434 extern void stack_free(
437 extern void stack_free_stack(
440 extern boolean_t
stack_alloc_try(
443 extern void stack_collect(void);
445 extern void stack_init(void) __attribute__((section("__TEXT, initcode")));
447 extern kern_return_t
thread_state_initialize(
450 extern kern_return_t
thread_setstatus(
453 thread_state_t tstate
,
454 mach_msg_type_number_t count
);
456 extern kern_return_t
thread_getstatus(
459 thread_state_t tstate
,
460 mach_msg_type_number_t
*count
);
462 extern kern_return_t
thread_info_internal(
464 thread_flavor_t flavor
,
465 thread_info_t thread_info_out
,
466 mach_msg_type_number_t
*thread_info_count
);
468 extern void thread_task_priority(
471 integer_t max_priority
);
473 extern void thread_policy_reset(
476 extern kern_return_t
kernel_thread_create(
477 thread_continue_t continuation
,
480 thread_t
*new_thread
);
482 extern kern_return_t
kernel_thread_start_priority(
483 thread_continue_t continuation
,
486 thread_t
*new_thread
);
488 extern void machine_stack_attach(
492 extern vm_offset_t
machine_stack_detach(
495 extern void machine_stack_handoff(
499 extern thread_t
machine_switch_context(
501 thread_continue_t continuation
,
502 thread_t new_thread
);
504 extern void machine_load_context(
507 extern kern_return_t
machine_thread_state_initialize(
510 extern kern_return_t
machine_thread_set_state(
512 thread_flavor_t flavor
,
513 thread_state_t state
,
514 mach_msg_type_number_t count
);
516 extern kern_return_t
machine_thread_get_state(
518 thread_flavor_t flavor
,
519 thread_state_t state
,
520 mach_msg_type_number_t
*count
);
522 extern kern_return_t
machine_thread_dup(
526 extern void machine_thread_init(void);
528 extern kern_return_t
machine_thread_create(
531 extern void machine_thread_switch_addrmode(
534 extern void machine_thread_destroy(
537 extern void machine_set_current_thread(
540 extern void machine_thread_terminate_self(void);
542 extern kern_return_t
machine_thread_get_kern_state(
544 thread_flavor_t flavor
,
545 thread_state_t tstate
,
546 mach_msg_type_number_t
*count
);
550 * XXX Funnel locks XXX
554 int fnl_type
; /* funnel type */
555 lck_mtx_t
*fnl_mutex
; /* underlying mutex for the funnel */
556 void * fnl_mtxholder
; /* thread (last)holdng mutex */
557 void * fnl_mtxrelease
; /* thread (last)releasing mutex */
558 lck_mtx_t
*fnl_oldmutex
; /* Mutex before collapsing split funnel */
561 typedef struct ReturnHandler ReturnHandler
;
563 #define thread_mtx_lock(thread) mutex_lock(&(thread)->mutex)
564 #define thread_mtx_try(thread) mutex_try(&(thread)->mutex)
565 #define thread_mtx_unlock(thread) mutex_unlock(&(thread)->mutex)
567 extern void act_execute_returnhandlers(void);
569 extern void install_special_handler(
572 extern void special_handler(
576 void act_machine_sv_free(thread_t
, int);
578 #else /* MACH_KERNEL_PRIVATE */
582 extern thread_t
current_thread(void);
584 extern void thread_reference(
587 extern void thread_deallocate(
592 #endif /* MACH_KERNEL_PRIVATE */
594 #ifdef KERNEL_PRIVATE
596 typedef struct funnel_lock funnel_t
;
598 #ifdef MACH_KERNEL_PRIVATE
600 extern void funnel_lock(
603 extern void funnel_unlock(
606 vm_offset_t
min_valid_stack_address(void);
607 vm_offset_t
max_valid_stack_address(void);
609 #endif /* MACH_KERNEL_PRIVATE */
613 extern funnel_t
*thread_funnel_get(void);
615 extern boolean_t
thread_funnel_set(
619 extern thread_t
kernel_thread(
621 void (*start
)(void));
625 #endif /* KERNEL_PRIVATE */
629 #ifdef XNU_KERNEL_PRIVATE
631 extern void thread_yield_internal(
632 mach_msg_timeout_t interval
);
635 * XXX Funnel locks XXX
638 #define THR_FUNNEL_NULL (funnel_t *)0
640 extern funnel_t
*funnel_alloc(
643 extern void funnel_free(
646 extern void thread_read_times(
648 time_value_t
*user_time
,
649 time_value_t
*system_time
);
651 extern void thread_setuserstack(
653 mach_vm_offset_t user_stack
);
655 extern uint64_t thread_adjuserstack(
659 extern void thread_setentrypoint(
661 mach_vm_offset_t entry
);
663 extern kern_return_t
thread_setsinglestep(
667 extern kern_return_t
thread_wire_internal(
668 host_priv_t host_priv
,
671 boolean_t
*prev_state
);
673 extern kern_return_t
thread_dup(thread_t
);
675 typedef void (*sched_call_t
)(
679 #define SCHED_CALL_BLOCK 0x1
680 #define SCHED_CALL_UNBLOCK 0x2
682 extern void thread_sched_call(
686 extern void thread_static_param(
690 extern task_t
get_threadtask(thread_t
);
691 #define thread_is_64bit(thd) \
692 task_has_64BitAddr(get_threadtask(thd))
695 extern void *get_bsdthread_info(thread_t
);
696 extern void set_bsdthread_info(thread_t
, void *);
697 extern void *uthread_alloc(task_t
, thread_t
);
698 extern void uthread_cleanup(task_t
, void *, void *);
699 extern void uthread_zone_free(void *);
700 extern void uthread_cred_free(void *);
702 extern boolean_t
thread_should_halt(
705 extern int is_64signalregset(void);
707 void act_set_apc(thread_t
);
709 extern uint32_t dtrace_get_thread_predcache(thread_t
);
710 extern int64_t dtrace_get_thread_vtime(thread_t
);
711 extern int64_t dtrace_get_thread_tracing(thread_t
);
712 extern boolean_t
dtrace_get_thread_reentering(thread_t
);
713 extern vm_offset_t
dtrace_get_kernel_stack(thread_t
);
714 extern void dtrace_set_thread_predcache(thread_t
, uint32_t);
715 extern void dtrace_set_thread_vtime(thread_t
, int64_t);
716 extern void dtrace_set_thread_tracing(thread_t
, int64_t);
717 extern void dtrace_set_thread_reentering(thread_t
, boolean_t
);
718 extern vm_offset_t
dtrace_set_thread_recover(thread_t
, vm_offset_t
);
720 extern int64_t dtrace_calc_thread_recent_vtime(thread_t
);
723 extern void thread_set_wq_state32(
725 thread_state_t tstate
);
727 extern void thread_set_wq_state64(
729 thread_state_t tstate
);
731 #endif /* XNU_KERNEL_PRIVATE */
733 extern kern_return_t
kernel_thread_start(
734 thread_continue_t continuation
,
736 thread_t
*new_thread
);
740 #endif /* _KERN_THREAD_H_ */