]> git.saurik.com Git - apple/xnu.git/blame - osfmk/kern/thread.h
xnu-4903.231.4.tar.gz
[apple/xnu.git] / osfmk / kern / thread.h
CommitLineData
1c79356b 1/*
39037602 2 * Copyright (c) 2000-2016 Apple Inc. All rights reserved.
1c79356b 3 *
2d21ac55 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
1c79356b 5 *
2d21ac55
A
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.
8f6c56a5 14 *
2d21ac55
A
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
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
8f6c56a5
A
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
2d21ac55
A
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.
8f6c56a5 25 *
2d21ac55 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
1c79356b
A
27 */
28/*
29 * @OSF_FREE_COPYRIGHT@
30 */
31/*
32 * Mach Operating System
33 * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
34 * All Rights Reserved.
35 *
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.
41 *
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.
45 *
46 * Carnegie Mellon requests users of this software to return to
47 *
48 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
49 * School of Computer Science
50 * Carnegie Mellon University
51 * Pittsburgh PA 15213-3890
52 *
53 * any improvements or extensions that they make and grant Carnegie Mellon
54 * the rights to redistribute these changes.
55 */
56/*
57 */
58/*
59 * File: thread.h
60 * Author: Avadis Tevanian, Jr.
61 *
62 * This file contains the structure definitions for threads.
63 *
64 */
65/*
66 * Copyright (c) 1993 The University of Utah and
67 * the Computer Systems Laboratory (CSL). All rights reserved.
68 *
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.
74 *
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.
78 *
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.
81 *
82 */
83
84#ifndef _KERN_THREAD_H_
85#define _KERN_THREAD_H_
86
87#include <mach/kern_return.h>
88#include <mach/mach_types.h>
89#include <mach/message.h>
90#include <mach/boolean.h>
55e303ae 91#include <mach/vm_param.h>
1c79356b
A
92#include <mach/thread_info.h>
93#include <mach/thread_status.h>
55e303ae 94#include <mach/exception_types.h>
9bccf70c 95
1c79356b 96#include <kern/kern_types.h>
5ba3f43e 97#include <vm/vm_kern.h>
1c79356b 98
91447636 99#include <sys/cdefs.h>
1c79356b 100
9bccf70c 101#ifdef MACH_KERNEL_PRIVATE
1c79356b 102
55e303ae 103#include <mach_assert.h>
1c79356b
A
104#include <mach_ldebug.h>
105
91447636
A
106#include <ipc/ipc_types.h>
107
1c79356b 108#include <mach/port.h>
1c79356b 109#include <kern/cpu_number.h>
3e170ce0 110#include <kern/smp.h>
1c79356b 111#include <kern/queue.h>
d9a64523 112
1c79356b 113#include <kern/timer.h>
fe8ab488 114#include <kern/simple_lock.h>
91447636 115#include <kern/locks.h>
1c79356b
A
116#include <kern/sched.h>
117#include <kern/sched_prim.h>
fe8ab488 118#include <mach/sfi_class.h>
1c79356b 119#include <kern/thread_call.h>
5ba3f43e 120#include <kern/thread_group.h>
1c79356b
A
121#include <kern/timer_call.h>
122#include <kern/task.h>
55e303ae 123#include <kern/exception.h>
2d21ac55 124#include <kern/affinity.h>
813fb2f6
A
125#include <kern/debug.h>
126#include <kern/block_hint.h>
d9a64523 127#include <kern/turnstile.h>
91447636 128
3e170ce0 129#include <kern/waitq.h>
5ba3f43e 130#include <san/kasan.h>
e8c3f781 131#include <os/refcnt.h>
3e170ce0 132
1c79356b 133#include <ipc/ipc_kmsg.h>
55e303ae 134
91447636 135#include <machine/cpu_data.h>
1c79356b
A
136#include <machine/thread.h>
137
d9a64523
A
138#ifdef XNU_KERNEL_PRIVATE
139/* priority queue static asserts fail for __ARM64_ARCH_8_32__ kext builds */
140#include <kern/priority_queue.h>
141#endif /* XNU_KERNEL_PRIVATE */
142
5ba3f43e
A
143#if MONOTONIC
144#include <stdatomic.h>
145#include <machine/monotonic.h>
146#endif /* MONOTONIC */
147
148#if CONFIG_EMBEDDED
149/* Taskwatch related. TODO: find this a better home */
150typedef struct task_watcher task_watch_t;
151#endif /* CONFIG_EMBEDDED */
39037602 152
55e303ae 153struct thread {
39037602
A
154
155#if MACH_ASSERT
156#define THREAD_MAGIC 0x1234ABCDDCBA4321ULL
157 /* Ensure nothing uses &thread as a queue entry */
158 uint64_t thread_magic;
159#endif /* MACH_ASSERT */
160
1c79356b 161 /*
9bccf70c 162 * NOTE: The runq field in the thread structure has an unusual
2d21ac55 163 * locking protocol. If its value is PROCESSOR_NULL, then it is
9bccf70c 164 * locked by the thread_lock, but if its value is something else
fe8ab488
A
165 * then it is locked by the associated run queue lock. It is
166 * set to PROCESSOR_NULL without holding the thread lock, but the
167 * transition from PROCESSOR_NULL to non-null must be done
168 * under the thread lock and the run queue lock.
9bccf70c 169 *
3e170ce0
A
170 * New waitq APIs allow the 'links' and 'runq' fields to be
171 * anywhere in the thread structure.
1c79356b 172 */
39037602 173 union {
d9a64523
A
174 queue_chain_t runq_links; /* run queue links */
175 queue_chain_t wait_links; /* wait queue links */
176 struct priority_queue_entry wait_prioq_links; /* priority ordered waitq links */
39037602
A
177 };
178
179 processor_t runq; /* run queue assignment */
180
181 event64_t wait_event; /* wait queue event */
182 struct waitq *waitq; /* wait queue this thread is enqueued on */
d9a64523
A
183 struct turnstile *turnstile; /* thread's turnstile, protected by primitives interlock */
184 void *inheritor; /* inheritor of the primitive the thread will block on */
185 struct priority_queue inheritor_queue; /* Inheritor queue */
39037602 186
9bccf70c 187 /* Data updated during assert_wait/thread_wakeup */
3e170ce0 188#if __SMP__
55e303ae 189 decl_simple_lock_data(,sched_lock) /* scheduling lock (thread_lock()) */
2d21ac55 190 decl_simple_lock_data(,wake_lock) /* for thread stop / wait (wake_lock()) */
3e170ce0 191#endif
39236c6e
A
192 integer_t options; /* options set by thread itself */
193#define TH_OPT_INTMASK 0x0003 /* interrupt / abort level */
194#define TH_OPT_VMPRIV 0x0004 /* may allocate reserved memory */
195#define TH_OPT_DTRACE 0x0008 /* executing under dtrace_probe */
196#define TH_OPT_SYSTEM_CRITICAL 0x0010 /* Thread must always be allowed to run - even under heavy load */
197#define TH_OPT_PROC_CPULIMIT 0x0020 /* Thread has a task-wide CPU limit applied to it */
198#define TH_OPT_PRVT_CPULIMIT 0x0040 /* Thread has a thread-private CPU limit applied to it */
3e170ce0
A
199#define TH_OPT_IDLE_THREAD 0x0080 /* Thread is a per-processor idle thread */
200#define TH_OPT_GLOBAL_FORCED_IDLE 0x0100 /* Thread performs forced idle for thermal control */
201#define TH_OPT_SCHED_VM_GROUP 0x0200 /* Thread belongs to special scheduler VM group */
202#define TH_OPT_HONOR_QLIMIT 0x0400 /* Thread will honor qlimit while sending mach_msg, regardless of MACH_SEND_ALWAYS */
490019cf 203#define TH_OPT_SEND_IMPORTANCE 0x0800 /* Thread will allow importance donation from kernel rpc */
5ba3f43e 204#define TH_OPT_ZONE_GC 0x1000 /* zone_gc() called on this thread */
39236c6e 205
2d21ac55 206 boolean_t wake_active; /* wake event on stop */
9bccf70c
A
207 int at_safe_point; /* thread_abort_safely allowed */
208 ast_t reason; /* why we blocked */
3e170ce0
A
209 uint32_t quantum_remaining;
210 wait_result_t wait_result; /* outcome of wait -
211 * may be examined by this thread
212 * WITHOUT locking */
39236c6e
A
213 thread_continue_t continuation; /* continue here next dispatch */
214 void *parameter; /* continuation parameter */
0b4e3aa0 215
9bccf70c 216 /* Data updated/used in thread_invoke */
9bccf70c 217 vm_offset_t kernel_stack; /* current kernel stack */
55e303ae 218 vm_offset_t reserved_stack; /* reserved kernel stack */
0b4e3aa0 219
5ba3f43e
A
220#if KASAN
221 struct kasan_thread_data kasan_data;
222#endif
223
0b4e3aa0 224 /* Thread state: */
9bccf70c 225 int state;
1c79356b
A
226/*
227 * Thread states [bits or'ed]
228 */
55e303ae
A
229#define TH_WAIT 0x01 /* queued for waiting */
230#define TH_SUSP 0x02 /* stopped or requested to stop */
231#define TH_RUN 0x04 /* running or on runq */
232#define TH_UNINT 0x08 /* waiting uninteruptibly */
d9a64523
A
233#define TH_TERMINATE 0x10 /* halted at termination */
234#define TH_TERMINATE2 0x20 /* added to termination queue */
235#define TH_WAIT_REPORT 0x40 /* the wait is using the sched_call,
236 only set if TH_WAIT is also set */
2d21ac55 237#define TH_IDLE 0x80 /* idling processor */
1c79356b 238
9bccf70c 239 /* Scheduling information */
6d2010ae
A
240 sched_mode_t sched_mode; /* scheduling mode */
241 sched_mode_t saved_mode; /* saved mode during forced mode demotion */
fe8ab488 242
39037602
A
243 /* This thread's contribution to global sched counters */
244 sched_bucket_t th_sched_bucket;
245
fe8ab488
A
246 sfi_class_id_t sfi_class; /* SFI class (XXX Updated on CSW/QE/AST) */
247 sfi_class_id_t sfi_wait_class; /* Currently in SFI wait for this class, protected by sfi_lock */
39037602
A
248
249
fe8ab488 250 uint32_t sched_flags; /* current flag bits */
3e170ce0 251/* TH_SFLAG_FAIRSHARE_TRIPPED (unused) 0x0001 */
6d2010ae 252#define TH_SFLAG_FAILSAFE 0x0002 /* fail-safe has tripped */
39037602
A
253#define TH_SFLAG_THROTTLED 0x0004 /* throttled thread forced to timeshare mode (may be applied in addition to failsafe) */
254#define TH_SFLAG_DEMOTED_MASK (TH_SFLAG_THROTTLED | TH_SFLAG_FAILSAFE) /* saved_mode contains previous sched_mode */
6d2010ae 255
d9a64523 256#define TH_SFLAG_PROMOTED 0x0008 /* sched pri has been promoted by kernel mutex priority promotion */
6d2010ae
A
257#define TH_SFLAG_ABORT 0x0010 /* abort interruptible waits */
258#define TH_SFLAG_ABORTSAFELY 0x0020 /* ... but only those at safe point */
259#define TH_SFLAG_ABORTED_MASK (TH_SFLAG_ABORT | TH_SFLAG_ABORTSAFELY)
260#define TH_SFLAG_DEPRESS 0x0040 /* normal depress yield */
261#define TH_SFLAG_POLLDEPRESS 0x0080 /* polled depress yield */
262#define TH_SFLAG_DEPRESSED_MASK (TH_SFLAG_DEPRESS | TH_SFLAG_POLLDEPRESS)
39037602 263/* unused TH_SFLAG_PRI_UPDATE 0x0100 */
6d2010ae 264#define TH_SFLAG_EAGERPREEMPT 0x0200 /* Any preemption of this thread should be treated as if AST_URGENT applied */
d9a64523 265#define TH_SFLAG_RW_PROMOTED 0x0400 /* promote reason: blocking with RW lock held */
39037602 266/* unused TH_SFLAG_THROTTLE_DEMOTED 0x0800 */
d9a64523 267#define TH_SFLAG_WAITQ_PROMOTED 0x1000 /* promote reason: waitq wakeup (generally for IPC receive) */
5ba3f43e
A
268
269
d9a64523
A
270#define TH_SFLAG_EXEC_PROMOTED 0x8000 /* promote reason: thread is in an exec */
271
272/* 'promote reasons' that request a priority floor only, not a custom priority */
273#define TH_SFLAG_PROMOTE_REASON_MASK (TH_SFLAG_RW_PROMOTED | TH_SFLAG_WAITQ_PROMOTED | TH_SFLAG_EXEC_PROMOTED)
39236c6e
A
274
275#define TH_SFLAG_RW_PROMOTED_BIT (10) /* 0x400 */
6d2010ae 276
3e170ce0
A
277 int16_t sched_pri; /* scheduled (current) priority */
278 int16_t base_pri; /* base priority */
279 int16_t max_priority; /* copy of max base priority */
280 int16_t task_priority; /* copy of task base priority */
d9a64523 281 int16_t promotion_priority; /* priority thread is currently promoted to */
3e170ce0 282
6d2010ae
A
283#if defined(CONFIG_SCHED_GRRR)
284#if 0
285 uint16_t grrr_deficit; /* fixed point (1/1000th quantum) fractional deficit */
286#endif
287#endif
d9a64523 288
39236c6e 289 int16_t promotions; /* level of promotion */
d9a64523 290 int iotier_override; /* atomic operations to set, cleared on ret to user */
e8c3f781 291 struct os_refcnt ref_count; /* number of references to me */
d9a64523
A
292
293 lck_mtx_t* waiting_for_mutex; /* points to mutex we're waiting for until we acquire it */
1c79356b 294
39236c6e 295 uint32_t rwlock_count; /* Number of lck_rw_t locks held by thread */
1c79356b 296
39236c6e 297 integer_t importance; /* task-relative importance */
d9a64523 298 uint32_t was_promoted_on_wakeup; /* thread promoted on wakeup to acquire mutex */
fe8ab488 299
39236c6e
A
300 /* Priority depression expiration */
301 integer_t depress_timer_active;
302 timer_call_data_t depress_timer;
303 /* real-time parameters */
9bccf70c 304 struct { /* see mach/thread_policy.h */
0b4e3aa0
A
305 uint32_t period;
306 uint32_t computation;
307 uint32_t constraint;
1c79356b 308 boolean_t preemptible;
55e303ae 309 uint64_t deadline;
1c79356b
A
310 } realtime;
311
6d2010ae 312 uint64_t last_run_time; /* time when thread was switched away from */
3e170ce0 313 uint64_t last_made_runnable_time; /* time when thread was unblocked or preempted */
5ba3f43e
A
314 uint64_t last_basepri_change_time; /* time when thread was last changed in basepri while runnable */
315 uint64_t same_pri_latency;
316#define THREAD_NOT_RUNNABLE (~0ULL)
317
fe8ab488
A
318
319#if defined(CONFIG_SCHED_MULTIQ)
320 sched_group_t sched_group;
321#endif /* defined(CONFIG_SCHED_MULTIQ) */
0b4e3aa0 322
9bccf70c
A
323 /* Data used during setrun/dispatch */
324 timer_data_t system_timer; /* system mode timer */
9bccf70c
A
325 processor_t bound_processor; /* bound to a processor? */
326 processor_t last_processor; /* processor last dispatched on */
6d2010ae 327 processor_t chosen_processor; /* Where we want to run this thread */
9bccf70c 328
0b4e3aa0 329 /* Fail-safe computation since last unblock or qualifying yield */
9bccf70c 330 uint64_t computation_metered;
0b4e3aa0 331 uint64_t computation_epoch;
6d2010ae 332 uint64_t safe_release; /* when to release fail-safe */
1c79356b 333
2d21ac55
A
334 /* Call out from scheduler */
335 void (*sched_call)(
336 int type,
337 thread_t thread);
6d2010ae
A
338#if defined(CONFIG_SCHED_PROTO)
339 uint32_t runqueue_generation; /* last time runqueue was drained */
340#endif
d9a64523 341
55e303ae 342 /* Statistics and timesharing calculations */
fe8ab488 343#if defined(CONFIG_SCHED_TIMESHARE_CORE)
91447636
A
344 natural_t sched_stamp; /* last scheduler tick */
345 natural_t sched_usage; /* timesharing cpu usage [sched] */
346 natural_t pri_shift; /* usage -> priority from pset */
347 natural_t cpu_usage; /* instrumented cpu usage [%cpu] */
348 natural_t cpu_delta; /* accumulated cpu_usage delta */
fe8ab488
A
349#endif /* CONFIG_SCHED_TIMESHARE_CORE */
350
2d21ac55
A
351 uint32_t c_switch; /* total context switches */
352 uint32_t p_switch; /* total processor switches */
353 uint32_t ps_switch; /* total pset switches */
1c79356b 354
3e170ce0 355 integer_t mutex_count; /* total count of locks held */
9bccf70c 356 /* Timing data structures */
316670eb 357 int precise_user_kernel_time; /* precise user/kernel enabled for this thread */
91447636 358 timer_data_t user_timer; /* user mode timer */
91447636 359 uint64_t user_timer_save; /* saved user timer value */
2d21ac55
A
360 uint64_t system_timer_save; /* saved system timer value */
361 uint64_t vtimer_user_save; /* saved values for vtimers */
362 uint64_t vtimer_prof_save;
363 uint64_t vtimer_rlim_save;
39037602 364 uint64_t vtimer_qos_save;
1c79356b 365
5ba3f43e 366 timer_data_t ptime; /* time executing in P mode */
d9a64523 367 timer_data_t runnable_timer; /* time the thread is runnable (including running) */
5ba3f43e 368
3e170ce0 369#if CONFIG_SCHED_SFI
fe8ab488
A
370 /* Timing for wait state */
371 uint64_t wait_sfi_begin_time; /* start time for thread waiting in SFI */
3e170ce0 372#endif
fe8ab488 373
9bccf70c 374 /* Timed wait expiration */
91447636
A
375 timer_call_data_t wait_timer;
376 integer_t wait_timer_active;
377 boolean_t wait_timer_is_set;
1c79356b 378
1c79356b 379
2d21ac55
A
380 /*
381 * Processor/cache affinity
382 * - affinity_threads links task threads with the same affinity set
383 */
384 affinity_set_t affinity_set;
385 queue_chain_t affinity_threads;
386
5ba3f43e 387 /* Various bits of state to stash across a continuation, exclusive to the current thread block point */
1c79356b
A
388 union {
389 struct {
d9a64523 390 mach_msg_return_t state; /* receive state */
39236c6e 391 mach_port_seqno_t seqno; /* seqno of recvd message */
d9a64523
A
392 ipc_object_t object; /* object received on */
393 mach_vm_address_t msg_addr; /* receive buffer pointer */
39037602
A
394 mach_msg_size_t rsize; /* max size for recvd msg */
395 mach_msg_size_t msize; /* actual size for recvd msg */
d9a64523 396 mach_msg_option_t option; /* options for receive */
b0d623f7 397 mach_port_name_t receiver_name; /* the receive port name */
5ba3f43e 398 struct knote *knote; /* knote fired for rcv */
39037602
A
399 union {
400 struct ipc_kmsg *kmsg; /* received message */
401 struct ipc_mqueue *peekq; /* mqueue to peek at */
402 struct {
403 mach_msg_priority_t qos; /* received message qos */
404 mach_msg_priority_t oqos; /* override qos for message */
405 } received_qos;
406 };
9bccf70c
A
407 mach_msg_continue_t continuation;
408 } receive;
1c79356b 409 struct {
d9a64523 410 struct semaphore *waitsemaphore; /* semaphore ref */
0b4e3aa0
A
411 struct semaphore *signalsemaphore; /* semaphore ref */
412 int options; /* semaphore options */
413 kern_return_t result; /* primary result */
9bccf70c
A
414 mach_msg_continue_t continuation;
415 } sema;
9bccf70c 416 } saved;
1c79356b 417
5ba3f43e
A
418 /* Only user threads can cause guard exceptions, only kernel threads can be thread call threads */
419 union {
420 /* Group and call this thread is working on behalf of */
421 struct {
422 struct thread_call_group * thc_group;
423 struct thread_call * thc_call; /* debug only, may be deallocated */
424 } thc_state;
425
426 /* Structure to save information about guard exception */
427 struct {
428 mach_exception_code_t code;
429 mach_exception_subcode_t subcode;
430 } guard_exc_info;
431 };
39236c6e 432
3e170ce0
A
433 /* Kernel holds on this thread */
434 int16_t suspend_count;
435 /* User level suspensions */
436 int16_t user_stop_count;
39236c6e 437
9bccf70c 438 /* IPC data structures */
39236c6e
A
439#if IMPORTANCE_INHERITANCE
440 natural_t ith_assertions; /* assertions pending drop */
441#endif
442 struct ipc_kmsg_queue ith_messages; /* messages to reap */
9bccf70c 443 mach_port_t ith_rpc_reply; /* reply port for kernel RPCs */
1c79356b
A
444
445 /* Ast/Halt data structures */
b0d623f7 446 vm_offset_t recover; /* page fault recover(copyin/out) */
1c79356b 447
b0d623f7 448 queue_chain_t threads; /* global list of all threads */
1c79356b 449
55e303ae
A
450 /* Activation */
451 queue_chain_t task_threads;
452
55e303ae
A
453 /* Task membership */
454 struct task *task;
455 vm_map_t map;
d9a64523
A
456#if DEVELOPMENT || DEBUG
457 boolean_t pmap_footprint_suspended;
458#endif /* DEVELOPMENT || DEBUG */
55e303ae 459
b0d623f7 460 decl_lck_mtx_data(,mutex)
55e303ae 461
55e303ae
A
462
463 /* Pending thread ast(s) */
464 ast_t ast;
465
91447636 466 /* Miscellaneous bits guarded by mutex */
55e303ae 467 uint32_t
39037602
A
468 active:1, /* Thread is active and has not been terminated */
469 started:1, /* Thread has been started after creation */
470 static_param:1, /* Disallow policy parameter changes */
471 inspection:1, /* TRUE when task is being inspected by crash reporter */
472 policy_reset:1, /* Disallow policy parameter changes on terminating threads */
473 suspend_parked:1, /* thread parked in thread_suspended */
474 corpse_dup:1, /* TRUE when thread is an inactive duplicate in a corpse */
2d21ac55 475 :0;
39037602 476
55e303ae
A
477 /* Ports associated with this thread */
478 struct ipc_port *ith_self; /* not a right, doesn't hold ref */
479 struct ipc_port *ith_sself; /* a send right */
5ba3f43e 480 struct ipc_port *ith_special_reply_port; /* ref to special reply port */
39236c6e 481 struct exception_action *exc_actions;
55e303ae 482
55e303ae
A
483#ifdef MACH_BSD
484 void *uthread;
485#endif
2d21ac55
A
486
487#if CONFIG_DTRACE
39236c6e
A
488 uint32_t t_dtrace_flags; /* DTrace thread states */
489#define TH_DTRACE_EXECSUCCESS 0x01
2d21ac55
A
490 uint32_t t_dtrace_predcache;/* DTrace per thread predicate value hint */
491 int64_t t_dtrace_tracing; /* Thread time under dtrace_probe() */
492 int64_t t_dtrace_vtime;
493#endif
b0d623f7 494
b0d623f7 495 clock_sec_t t_page_creation_time;
39236c6e 496 uint32_t t_page_creation_count;
3e170ce0 497 uint32_t t_page_creation_throttled;
04b8595b 498#if (DEVELOPMENT || DEBUG)
3e170ce0
A
499 uint64_t t_page_creation_throttled_hard;
500 uint64_t t_page_creation_throttled_soft;
04b8595b
A
501#endif /* DEVELOPMENT || DEBUG */
502
39037602
A
503#ifdef KPERF
504/* The high 7 bits are the number of frames to sample of a user callstack. */
505#define T_KPERF_CALLSTACK_DEPTH_OFFSET (25)
506#define T_KPERF_SET_CALLSTACK_DEPTH(DEPTH) (((uint32_t)(DEPTH)) << T_KPERF_CALLSTACK_DEPTH_OFFSET)
507#define T_KPERF_GET_CALLSTACK_DEPTH(FLAGS) ((FLAGS) >> T_KPERF_CALLSTACK_DEPTH_OFFSET)
508#endif
509
510#define T_KPERF_AST_CALLSTACK (1U << 0) /* dump a callstack on thread's next AST */
511#define T_KPERF_AST_DISPATCH (1U << 1) /* dump a name on thread's next AST */
512#define T_KPC_ALLOC (1U << 2) /* thread needs a kpc_buf allocated */
513/* only go up to T_KPERF_CALLSTACK_DEPTH_OFFSET - 1 */
514
515#ifdef KPERF
516 uint32_t kperf_flags;
517 uint32_t kperf_pet_gen; /* last generation of PET that sampled this thread*/
518 uint32_t kperf_c_switch; /* last dispatch detection */
519 uint32_t kperf_pet_cnt; /* how many times a thread has been sampled by PET */
520#endif
6d2010ae 521
39236c6e
A
522#ifdef KPC
523 /* accumulated performance counters for this thread */
524 uint64_t *kpc_buf;
525#endif
526
fe8ab488
A
527#if HYPERVISOR
528 /* hypervisor virtual CPU object associated with this thread */
529 void *hv_thread_target;
530#endif /* HYPERVISOR */
531
b0d623f7 532 uint64_t thread_id; /*system wide unique thread-id*/
6d2010ae
A
533
534 /* Statistics accumulated per-thread and aggregated per-task */
535 uint32_t syscalls_unix;
536 uint32_t syscalls_mach;
316670eb
A
537 ledger_t t_ledger;
538 ledger_t t_threadledger; /* per thread ledger */
5ba3f43e
A
539 ledger_t t_bankledger; /* ledger to charge someone */
540 uint64_t t_deduct_bank_ledger_time; /* cpu time to be deducted from bank ledger */
541 uint64_t t_deduct_bank_ledger_energy; /* energy to be deducted from bank ledger */
542
543#if MONOTONIC
544 struct mt_thread t_monotonic;
545#endif /* MONOTONIC */
546
547 /*** Machine-dependent state ***/
548 struct machine_thread machine;
39236c6e 549
39037602
A
550 /* policy is protected by the thread mutex */
551 struct thread_requested_policy requested_policy;
552 struct thread_effective_policy effective_policy;
39236c6e 553
fe8ab488 554 /* usynch override is protected by the task lock, eventually will be thread mutex */
a1c7dba1
A
555 struct thread_qos_override {
556 struct thread_qos_override *override_next;
557 uint32_t override_contended_resource_count;
558 int16_t override_qos;
559 int16_t override_resource_type;
560 user_addr_t override_resource;
561 } *overrides;
fe8ab488 562
39037602 563 uint32_t ipc_overrides;
d9a64523 564 _Atomic uint32_t kqwl_owning_count;
5ba3f43e 565 uint32_t sync_ipc_overrides;
39037602 566 uint16_t user_promotion_basepri;
5ba3f43e 567 _Atomic uint16_t kevent_ast_bits;
39037602 568
fe8ab488 569 io_stat_info_t thread_io_stats; /* per-thread I/O statistics */
39236c6e 570
5ba3f43e
A
571#if CONFIG_EMBEDDED
572 task_watch_t * taskwatch; /* task watch */
573#endif /* CONFIG_EMBEDDED */
39236c6e 574
4b17d6b6
A
575 uint32_t thread_callout_interrupt_wakeups;
576 uint32_t thread_callout_platform_idle_wakeups;
577 uint32_t thread_timer_wakeups_bin_1;
578 uint32_t thread_timer_wakeups_bin_2;
579 uint16_t thread_tag;
580 uint16_t callout_woken_from_icontext:1,
581 callout_woken_from_platform_idle:1,
39236c6e
A
582 callout_woke_thread:1,
583 thread_bitfield_unused:13;
fe8ab488
A
584
585 mach_port_name_t ith_voucher_name;
586 ipc_voucher_t ith_voucher;
587#if CONFIG_IOSCHED
588 void *decmp_upl;
589#endif /* CONFIG_IOSCHED */
3e170ce0 590
5ba3f43e
A
591 /* work interval (if any) associated with the thread. Uses thread mutex */
592 struct work_interval *th_work_interval;
39037602
A
593
594#if SCHED_TRACE_THREAD_WAKEUPS
595 uintptr_t thread_wakeup_bt[64];
596#endif
d9a64523
A
597 turnstile_update_flags_t inheritor_flags; /* inheritor flags for inheritor field */
598 block_hint_t pending_block_hint;
599 block_hint_t block_hint; /* What type of primitive last caused us to block. */
0b4e3aa0 600};
1c79356b 601
39037602
A
602#define ith_state saved.receive.state
603#define ith_object saved.receive.object
604#define ith_msg_addr saved.receive.msg_addr
605#define ith_rsize saved.receive.rsize
606#define ith_msize saved.receive.msize
607#define ith_option saved.receive.option
608#define ith_receiver_name saved.receive.receiver_name
609#define ith_continuation saved.receive.continuation
610#define ith_kmsg saved.receive.kmsg
611#define ith_peekq saved.receive.peekq
5ba3f43e 612#define ith_knote saved.receive.knote
39037602
A
613#define ith_qos saved.receive.received_qos.qos
614#define ith_qos_override saved.receive.received_qos.oqos
615#define ith_seqno saved.receive.seqno
616
617#define sth_waitsemaphore saved.sema.waitsemaphore
618#define sth_signalsemaphore saved.sema.signalsemaphore
619#define sth_options saved.sema.options
620#define sth_result saved.sema.result
621#define sth_continuation saved.sema.continuation
622
5ba3f43e
A
623#define ITH_KNOTE_NULL ((void *)NULL)
624#define ITH_KNOTE_PSEUDO ((void *)0xdeadbeef)
d9a64523
A
625/*
626 * The ith_knote is used during message delivery, and can safely be interpreted
627 * only when used for one of these codepaths, which the test for the msgt_name
628 * being RECEIVE or SEND_ONCE is about.
629 */
630#define ITH_KNOTE_VALID(kn, msgt_name) \
631 (((kn) != ITH_KNOTE_NULL && (kn) != ITH_KNOTE_PSEUDO) && \
632 ((msgt_name) == MACH_MSG_TYPE_PORT_RECEIVE || \
633 (msgt_name) == MACH_MSG_TYPE_PORT_SEND_ONCE))
5ba3f43e 634
39037602
A
635#if MACH_ASSERT
636#define assert_thread_magic(thread) assertf((thread)->thread_magic == THREAD_MAGIC, \
637 "bad thread magic 0x%llx for thread %p, expected 0x%llx", \
638 (thread)->thread_magic, (thread), THREAD_MAGIC)
639#else
640#define assert_thread_magic(thread) do { (void)(thread); } while (0)
641#endif
1c79356b 642
39236c6e 643extern void thread_bootstrap(void);
1c79356b 644
39236c6e 645extern void thread_init(void);
9bccf70c 646
91447636 647extern void thread_daemon_init(void);
1c79356b 648
91447636 649#define thread_reference_internal(thread) \
e8c3f781 650 os_ref_retain(&(thread)->ref_count);
91447636 651
91447636
A
652#define thread_reference(thread) \
653MACRO_BEGIN \
654 if ((thread) != THREAD_NULL) \
2d21ac55 655 thread_reference_internal(thread); \
91447636 656MACRO_END
1c79356b 657
55e303ae
A
658extern void thread_deallocate(
659 thread_t thread);
1c79356b 660
3e170ce0
A
661extern void thread_deallocate_safe(
662 thread_t thread);
663
813fb2f6
A
664extern void thread_inspect_deallocate(
665 thread_inspect_t thread);
666
55e303ae 667extern void thread_terminate_self(void);
1c79356b 668
91447636
A
669extern kern_return_t thread_terminate_internal(
670 thread_t thread);
671
39037602 672extern void thread_start(
2d21ac55
A
673 thread_t thread) __attribute__ ((noinline));
674
39037602
A
675extern void thread_start_in_assert_wait(
676 thread_t thread,
677 event_t event,
678 wait_interrupt_t interruptible) __attribute__ ((noinline));
679
91447636
A
680extern void thread_terminate_enqueue(
681 thread_t thread);
682
39037602
A
683extern void thread_exception_enqueue(
684 task_t task,
5ba3f43e
A
685 thread_t thread,
686 exception_type_t etype);
39037602
A
687
688extern void thread_copy_resource_info(
689 thread_t dst_thread,
690 thread_t src_thread);
691
3e170ce0
A
692extern void thread_terminate_crashed_threads(void);
693
d9a64523
A
694extern void turnstile_deallocate_enqueue(
695 struct turnstile *turnstile);
696
91447636
A
697extern void thread_stack_enqueue(
698 thread_t thread);
699
55e303ae 700extern void thread_hold(
91447636 701 thread_t thread);
1c79356b 702
55e303ae 703extern void thread_release(
91447636 704 thread_t thread);
1c79356b 705
39037602
A
706extern void thread_corpse_continue(void);
707
743345f9
A
708extern boolean_t thread_is_active(thread_t thread);
709
3e170ce0
A
710/* Locking for scheduler state, always acquired with interrupts disabled (splsched()) */
711#if __SMP__
91447636 712#define thread_lock_init(th) simple_lock_init(&(th)->sched_lock, 0)
55e303ae
A
713#define thread_lock(th) simple_lock(&(th)->sched_lock)
714#define thread_unlock(th) simple_unlock(&(th)->sched_lock)
1c79356b 715
91447636
A
716#define wake_lock_init(th) simple_lock_init(&(th)->wake_lock, 0)
717#define wake_lock(th) simple_lock(&(th)->wake_lock)
718#define wake_unlock(th) simple_unlock(&(th)->wake_lock)
3e170ce0
A
719#else
720#define thread_lock_init(th) do { (void)th; } while(0)
721#define thread_lock(th) do { (void)th; } while(0)
722#define thread_unlock(th) do { (void)th; } while(0)
723
724#define wake_lock_init(th) do { (void)th; } while(0)
725#define wake_lock(th) do { (void)th; } while(0)
726#define wake_unlock(th) do { (void)th; } while(0)
727#endif
2d21ac55
A
728
729#define thread_should_halt_fast(thread) (!(thread)->active)
1c79356b 730
91447636
A
731extern void stack_alloc(
732 thread_t thread);
1c79356b 733
6d2010ae
A
734extern void stack_handoff(
735 thread_t from,
736 thread_t to);
737
55e303ae
A
738extern void stack_free(
739 thread_t thread);
1c79356b 740
6d2010ae
A
741extern void stack_free_reserved(
742 thread_t thread);
1c79356b 743
91447636
A
744extern boolean_t stack_alloc_try(
745 thread_t thread);
746
55e303ae 747extern void stack_collect(void);
1c79356b 748
39236c6e 749extern void stack_init(void);
91447636 750
6d2010ae 751
91447636
A
752extern kern_return_t thread_info_internal(
753 thread_t thread,
1c79356b
A
754 thread_flavor_t flavor,
755 thread_info_t thread_info_out,
756 mach_msg_type_number_t *thread_info_count);
757
1c79356b 758
1c79356b 759
91447636
A
760extern kern_return_t kernel_thread_create(
761 thread_continue_t continuation,
762 void *parameter,
763 integer_t priority,
764 thread_t *new_thread);
1c79356b 765
91447636
A
766extern kern_return_t kernel_thread_start_priority(
767 thread_continue_t continuation,
768 void *parameter,
769 integer_t priority,
770 thread_t *new_thread);
1c79356b 771
55e303ae
A
772extern void machine_stack_attach(
773 thread_t thread,
91447636 774 vm_offset_t stack);
1c79356b 775
55e303ae
A
776extern vm_offset_t machine_stack_detach(
777 thread_t thread);
778
779extern void machine_stack_handoff(
780 thread_t old,
781 thread_t new);
782
783extern thread_t machine_switch_context(
784 thread_t old_thread,
785 thread_continue_t continuation,
786 thread_t new_thread);
787
788extern void machine_load_context(
5ba3f43e
A
789 thread_t thread) __attribute__((noreturn));
790
55e303ae 791
91447636
A
792extern kern_return_t machine_thread_state_initialize(
793 thread_t thread);
9bccf70c 794
55e303ae 795extern kern_return_t machine_thread_set_state(
91447636 796 thread_t thread,
55e303ae
A
797 thread_flavor_t flavor,
798 thread_state_t state,
799 mach_msg_type_number_t count);
800
801extern kern_return_t machine_thread_get_state(
91447636 802 thread_t thread,
55e303ae
A
803 thread_flavor_t flavor,
804 thread_state_t state,
805 mach_msg_type_number_t *count);
806
d9a64523
A
807extern kern_return_t machine_thread_state_convert_from_user(
808 thread_t thread,
809 thread_flavor_t flavor,
810 thread_state_t tstate,
811 mach_msg_type_number_t count);
812
813extern kern_return_t machine_thread_state_convert_to_user(
814 thread_t thread,
815 thread_flavor_t flavor,
816 thread_state_t tstate,
817 mach_msg_type_number_t *count);
818
55e303ae 819extern kern_return_t machine_thread_dup(
91447636 820 thread_t self,
d9a64523
A
821 thread_t target,
822 boolean_t is_corpse);
55e303ae
A
823
824extern void machine_thread_init(void);
825
826extern kern_return_t machine_thread_create(
827 thread_t thread,
828 task_t task);
0c530ab8 829extern void machine_thread_switch_addrmode(
2d21ac55 830 thread_t thread);
55e303ae
A
831
832extern void machine_thread_destroy(
833 thread_t thread);
834
91447636
A
835extern void machine_set_current_thread(
836 thread_t thread);
55e303ae 837
91447636
A
838extern kern_return_t machine_thread_get_kern_state(
839 thread_t thread,
840 thread_flavor_t flavor,
841 thread_state_t tstate,
842 mach_msg_type_number_t *count);
843
b0d623f7
A
844extern kern_return_t machine_thread_inherit_taskwide(
845 thread_t thread,
846 task_t parent_task);
91447636 847
fe8ab488
A
848extern kern_return_t machine_thread_set_tsd_base(
849 thread_t thread,
850 mach_vm_offset_t tsd_base);
55e303ae 851
b0d623f7
A
852#define thread_mtx_lock(thread) lck_mtx_lock(&(thread)->mutex)
853#define thread_mtx_try(thread) lck_mtx_try_lock(&(thread)->mutex)
854#define thread_mtx_unlock(thread) lck_mtx_unlock(&(thread)->mutex)
55e303ae 855
39037602 856extern void thread_apc_ast(thread_t thread);
55e303ae 857
39037602 858extern void thread_update_qos_cpu_time(thread_t thread);
fe8ab488 859
2d21ac55
A
860void act_machine_sv_free(thread_t, int);
861
b0d623f7
A
862vm_offset_t min_valid_stack_address(void);
863vm_offset_t max_valid_stack_address(void);
864
39236c6e 865static inline uint16_t thread_set_tag_internal(thread_t thread, uint16_t tag) {
4b17d6b6
A
866 return __sync_fetch_and_or(&thread->thread_tag, tag);
867}
39236c6e
A
868
869static inline uint16_t thread_get_tag_internal(thread_t thread) {
4b17d6b6
A
870 return thread->thread_tag;
871}
872
fe8ab488 873
3e170ce0
A
874extern void thread_set_options(uint32_t thopt);
875
5ba3f43e 876
9bccf70c 877#else /* MACH_KERNEL_PRIVATE */
1c79356b 878
91447636 879__BEGIN_DECLS
1c79356b 880
d9a64523
A
881extern void thread_mtx_lock(thread_t thread);
882
883extern void thread_mtx_unlock(thread_t thread);
884
91447636
A
885extern thread_t current_thread(void);
886
887extern void thread_reference(
888 thread_t thread);
55e303ae 889
91447636
A
890extern void thread_deallocate(
891 thread_t thread);
55e303ae 892
91447636 893__END_DECLS
1c79356b 894
9bccf70c 895#endif /* MACH_KERNEL_PRIVATE */
1c79356b 896
91447636 897#ifdef KERNEL_PRIVATE
1c79356b 898
91447636 899__BEGIN_DECLS
55e303ae 900
5ba3f43e
A
901extern void thread_starts_owning_workloop(
902 thread_t thread);
903
904extern void thread_ends_owning_workloop(
905 thread_t thread);
906
907extern uint32_t thread_owned_workloops_count(
908 thread_t thread);
909
910
911extern uint64_t thread_dispatchqaddr(
912 thread_t thread);
913
914extern uint64_t thread_rettokern_addr(
b0d623f7
A
915 thread_t thread);
916
91447636 917__END_DECLS
55e303ae 918
91447636 919#endif /* KERNEL_PRIVATE */
55e303ae 920
fe8ab488
A
921#ifdef KERNEL
922__BEGIN_DECLS
923
5ba3f43e 924extern uint64_t thread_tid(thread_t thread);
fe8ab488
A
925
926__END_DECLS
927
928#endif /* KERNEL */
929
91447636 930__BEGIN_DECLS
55e303ae 931
91447636 932#ifdef XNU_KERNEL_PRIVATE
9bccf70c 933
4b17d6b6
A
934/*
935 * Thread tags; for easy identification.
936 */
937#define THREAD_TAG_MAINTHREAD 0x1
938#define THREAD_TAG_CALLOUT 0x2
939#define THREAD_TAG_IOWORKLOOP 0x4
940
39037602
A
941#define THREAD_TAG_PTHREAD 0x10
942#define THREAD_TAG_WORKQUEUE 0x20
943
4b17d6b6
A
944uint16_t thread_set_tag(thread_t, uint16_t);
945uint16_t thread_get_tag(thread_t);
d9a64523 946uint64_t thread_last_run_time(thread_t);
4b17d6b6 947
316670eb
A
948extern kern_return_t thread_state_initialize(
949 thread_t thread);
950
951extern kern_return_t thread_setstatus(
952 thread_t thread,
953 int flavor,
954 thread_state_t tstate,
955 mach_msg_type_number_t count);
956
d9a64523
A
957extern kern_return_t thread_setstatus_from_user(
958 thread_t thread,
959 int flavor,
960 thread_state_t tstate,
961 mach_msg_type_number_t count);
962
316670eb
A
963extern kern_return_t thread_getstatus(
964 thread_t thread,
965 int flavor,
966 thread_state_t tstate,
967 mach_msg_type_number_t *count);
968
d9a64523
A
969extern kern_return_t thread_getstatus_to_user(
970 thread_t thread,
971 int flavor,
972 thread_state_t tstate,
973 mach_msg_type_number_t *count);
974
3e170ce0
A
975extern kern_return_t thread_create_with_continuation(
976 task_t task,
977 thread_t *new_thread,
978 thread_continue_t continuation);
979
743345f9
A
980extern kern_return_t thread_create_waiting(task_t task,
981 thread_continue_t continuation,
982 event_t event,
983 thread_t *new_thread);
984
39037602
A
985extern kern_return_t thread_create_workq_waiting(
986 task_t task,
987 thread_continue_t thread_return,
39037602
A
988 thread_t *new_thread);
989
2d21ac55
A
990extern void thread_yield_internal(
991 mach_msg_timeout_t interval);
992
d9a64523 993extern void thread_yield_to_preemption(void);
39037602 994
316670eb
A
995/*
996 * Thread-private CPU limits: apply a private CPU limit to this thread only. Available actions are:
997 *
998 * 1) Block. Prevent CPU consumption of the thread from exceeding the limit.
999 * 2) Exception. Generate a resource consumption exception when the limit is exceeded.
39236c6e 1000 * 3) Disable. Remove any existing CPU limit.
316670eb
A
1001 */
1002#define THREAD_CPULIMIT_BLOCK 0x1
1003#define THREAD_CPULIMIT_EXCEPTION 0x2
39236c6e 1004#define THREAD_CPULIMIT_DISABLE 0x3
316670eb
A
1005
1006struct _thread_ledger_indices {
1007 int cpu_time;
1008};
1009
1010extern struct _thread_ledger_indices thread_ledgers;
1011
39236c6e 1012extern int thread_get_cpulimit(int *action, uint8_t *percentage, uint64_t *interval_ns);
316670eb
A
1013extern int thread_set_cpulimit(int action, uint8_t percentage, uint64_t interval_ns);
1014
91447636 1015extern void thread_read_times(
d9a64523 1016 thread_t thread,
91447636 1017 time_value_t *user_time,
d9a64523
A
1018 time_value_t *system_time,
1019 time_value_t *runnable_time);
1c79356b 1020
fe8ab488
A
1021extern uint64_t thread_get_runtime_self(void);
1022
91447636
A
1023extern void thread_setuserstack(
1024 thread_t thread,
1025 mach_vm_offset_t user_stack);
1c79356b 1026
91447636
A
1027extern uint64_t thread_adjuserstack(
1028 thread_t thread,
1029 int adjust);
55e303ae 1030
91447636 1031extern void thread_setentrypoint(
55e303ae 1032 thread_t thread,
91447636
A
1033 mach_vm_offset_t entry);
1034
fe8ab488
A
1035extern kern_return_t thread_set_tsd_base(
1036 thread_t thread,
1037 mach_vm_offset_t tsd_base);
1038
2d21ac55 1039extern kern_return_t thread_setsinglestep(
0c530ab8
A
1040 thread_t thread,
1041 int on);
1042
6d2010ae
A
1043extern kern_return_t thread_userstack(
1044 thread_t,
1045 int,
1046 thread_state_t,
1047 unsigned int,
1048 mach_vm_offset_t *,
39037602
A
1049 int *,
1050 boolean_t);
6d2010ae 1051
316670eb
A
1052extern kern_return_t thread_entrypoint(
1053 thread_t,
1054 int,
1055 thread_state_t,
1056 unsigned int,
1057 mach_vm_offset_t *);
6d2010ae 1058
316670eb 1059extern kern_return_t thread_userstackdefault(
39037602
A
1060 mach_vm_offset_t *,
1061 boolean_t);
6d2010ae 1062
91447636
A
1063extern kern_return_t thread_wire_internal(
1064 host_priv_t host_priv,
1065 thread_t thread,
1066 boolean_t wired,
1067 boolean_t *prev_state);
1068
fe8ab488 1069
91447636
A
1070extern kern_return_t thread_dup(thread_t);
1071
39037602
A
1072extern kern_return_t thread_dup2(thread_t, thread_t);
1073
5ba3f43e
A
1074#if !defined(_SCHED_CALL_T_DEFINED)
1075#define _SCHED_CALL_T_DEFINED
2d21ac55
A
1076typedef void (*sched_call_t)(
1077 int type,
1078 thread_t thread);
5ba3f43e 1079#endif
2d21ac55
A
1080
1081#define SCHED_CALL_BLOCK 0x1
1082#define SCHED_CALL_UNBLOCK 0x2
1083
1084extern void thread_sched_call(
1085 thread_t thread,
1086 sched_call_t call);
1087
fe8ab488
A
1088extern boolean_t thread_is_static_param(
1089 thread_t thread);
1090
91447636 1091extern task_t get_threadtask(thread_t);
0c530ab8 1092
d9a64523
A
1093/*
1094 * Thread is running within a 64-bit address space.
1095 */
1096#define thread_is_64bit_addr(thd) \
1097 task_has_64Bit_addr(get_threadtask(thd))
1098
1099/*
1100 * Thread is using 64-bit machine state.
1101 */
1102#define thread_is_64bit_data(thd) \
1103 task_has_64Bit_data(get_threadtask(thd))
91447636
A
1104
1105extern void *get_bsdthread_info(thread_t);
1106extern void set_bsdthread_info(thread_t, void *);
b0d623f7 1107extern void *uthread_alloc(task_t, thread_t, int);
d9a64523 1108extern event_t workq_thread_init_and_wq_lock(task_t, thread_t); // bsd/pthread/
3e170ce0 1109extern void uthread_cleanup_name(void *uthread);
39037602 1110extern void uthread_cleanup(task_t, void *, void *);
2d21ac55 1111extern void uthread_zone_free(void *);
3e170ce0
A
1112extern void uthread_cred_free(void *);
1113
813fb2f6 1114extern void uthread_reset_proc_refcount(void *);
3e170ce0
A
1115#if PROC_REF_DEBUG
1116extern int uthread_get_proc_refcount(void *);
3e170ce0
A
1117extern int proc_ref_tracking_disabled;
1118#endif
91447636
A
1119
1120extern boolean_t thread_should_halt(
1121 thread_t thread);
1122
316670eb
A
1123extern boolean_t thread_should_abort(
1124 thread_t);
1125
2d21ac55
A
1126extern int is_64signalregset(void);
1127
3e170ce0 1128extern void act_set_kperf(thread_t);
5c9f4661
A
1129extern void act_set_astledger(thread_t thread);
1130extern void act_set_astledger_async(thread_t thread);
39037602 1131extern void act_set_io_telemetry_ast(thread_t);
2d21ac55
A
1132
1133extern uint32_t dtrace_get_thread_predcache(thread_t);
1134extern int64_t dtrace_get_thread_vtime(thread_t);
1135extern int64_t dtrace_get_thread_tracing(thread_t);
1136extern boolean_t dtrace_get_thread_reentering(thread_t);
3e170ce0 1137extern int dtrace_get_thread_last_cpu_id(thread_t);
2d21ac55
A
1138extern vm_offset_t dtrace_get_kernel_stack(thread_t);
1139extern void dtrace_set_thread_predcache(thread_t, uint32_t);
1140extern void dtrace_set_thread_vtime(thread_t, int64_t);
1141extern void dtrace_set_thread_tracing(thread_t, int64_t);
1142extern void dtrace_set_thread_reentering(thread_t, boolean_t);
1143extern vm_offset_t dtrace_set_thread_recover(thread_t, vm_offset_t);
b0d623f7 1144extern void dtrace_thread_bootstrap(void);
39236c6e 1145extern void dtrace_thread_didexec(thread_t);
2d21ac55
A
1146
1147extern int64_t dtrace_calc_thread_recent_vtime(thread_t);
1148
1149
39236c6e 1150extern kern_return_t thread_set_wq_state32(
2d21ac55
A
1151 thread_t thread,
1152 thread_state_t tstate);
1153
39236c6e 1154extern kern_return_t thread_set_wq_state64(
2d21ac55
A
1155 thread_t thread,
1156 thread_state_t tstate);
1157
b0d623f7
A
1158extern vm_offset_t kernel_stack_mask;
1159extern vm_offset_t kernel_stack_size;
1160extern vm_offset_t kernel_stack_depth_max;
1161
5ba3f43e
A
1162extern void guard_ast(thread_t);
1163extern void fd_guard_ast(thread_t,
1164 mach_exception_code_t, mach_exception_subcode_t);
1165#if CONFIG_VNGUARD
1166extern void vn_guard_ast(thread_t,
1167 mach_exception_code_t, mach_exception_subcode_t);
1168#endif
1169extern void mach_port_guard_ast(thread_t,
1170 mach_exception_code_t, mach_exception_subcode_t);
d9a64523
A
1171extern void virt_memory_guard_ast(thread_t,
1172 mach_exception_code_t, mach_exception_subcode_t);
5ba3f43e
A
1173extern void thread_guard_violation(thread_t,
1174 mach_exception_code_t, mach_exception_subcode_t);
1175extern void thread_update_io_stats(thread_t, int size, int io_flags);
fe8ab488
A
1176
1177extern kern_return_t thread_set_voucher_name(mach_port_name_t name);
1178extern kern_return_t thread_get_current_voucher_origin_pid(int32_t *pid);
39236c6e 1179
ecc0ceb4
A
1180extern void set_thread_rwlock_boost(void);
1181extern void clear_thread_rwlock_boost(void);
1182
39037602
A
1183/*! @function thread_has_thread_name
1184 @abstract Checks if a thread has a name.
1185 @discussion This function takes one input, a thread, and returns a boolean value indicating if that thread already has a name associated with it.
1186 @param th The thread to inspect.
1187 @result TRUE if the thread has a name, FALSE otherwise.
1188*/
1189extern boolean_t thread_has_thread_name(thread_t th);
1190
1191/*! @function thread_set_thread_name
1192 @abstract Set a thread's name.
1193 @discussion This function takes two input parameters: a thread to name, and the name to apply to the thread. The name will be attached to the thread in order to better identify the thread.
1194 @param th The thread to be named.
1195 @param name The name to apply to the thread.
1196*/
1197extern void thread_set_thread_name(thread_t th, const char* name);
1198
490019cf
A
1199extern void thread_enable_send_importance(thread_t thread, boolean_t enable);
1200
d9a64523
A
1201/*
1202 * Translate signal context data pointer to userspace representation
1203 */
1204
1205extern kern_return_t machine_thread_siguctx_pointer_convert_to_user(
1206 thread_t thread,
1207 user_addr_t *uctxp);
1208
1209/*
1210 * Translate array of function pointer syscall arguments from userspace representation
1211 */
1212
1213extern kern_return_t machine_thread_function_pointers_convert_from_user(
1214 thread_t thread,
1215 user_addr_t *fptrs,
1216 uint32_t count);
1217
39037602
A
1218/* Get a backtrace for a threads kernel or user stack (user_p), with pc and optionally
1219 * frame pointer (getfp). Returns bytes added to buffer, and kThreadTruncatedBT in
1220 * thread_trace_flags if a user page is not present after kdp_lightweight_fault() is
1221 * called.
1222 */
1223
1224extern int machine_trace_thread(
1225 thread_t thread,
1226 char *tracepos,
1227 char *tracebound,
1228 int nframes,
1229 boolean_t user_p,
1230 boolean_t getfp,
1231 uint32_t *thread_trace_flags);
1232
1233extern int machine_trace_thread64(thread_t thread,
d9a64523
A
1234 char *tracepos,
1235 char *tracebound,
1236 int nframes,
1237 boolean_t user_p,
1238 boolean_t getfp,
1239 uint32_t *thread_trace_flags,
1240 uint64_t *sp);
1241
1242/*
1243 * Get the duration of the given thread's last wait.
1244 */
1245uint64_t thread_get_last_wait_duration(thread_t thread);
39037602 1246
91447636
A
1247#endif /* XNU_KERNEL_PRIVATE */
1248
fe8ab488 1249
b0d623f7
A
1250/*! @function kernel_thread_start
1251 @abstract Create a kernel thread.
1252 @discussion This function takes three input parameters, namely reference to the function that the thread should execute, caller specified data and a reference which is used to return the newly created kernel thread. The function returns KERN_SUCCESS on success or an appropriate kernel code type indicating the error. It may be noted that the caller is responsible for explicitly releasing the reference to the created thread when no longer needed. This should be done by calling thread_deallocate(new_thread).
1253 @param continuation A C-function pointer where the thread will begin execution.
1254 @param parameter Caller specified data to be passed to the new thread.
1255 @param new_thread Reference to the new thread is returned in this parameter.
1256 @result Returns KERN_SUCCESS on success or an appropriate kernel code type.
1257*/
1258
91447636
A
1259extern kern_return_t kernel_thread_start(
1260 thread_continue_t continuation,
1261 void *parameter,
1262 thread_t *new_thread);
5ba3f43e 1263
6d2010ae
A
1264#ifdef KERNEL_PRIVATE
1265void thread_set_eager_preempt(thread_t thread);
1266void thread_clear_eager_preempt(thread_t thread);
a39ff7e2
A
1267void thread_set_honor_qlimit(thread_t thread);
1268void thread_clear_honor_qlimit(thread_t thread);
316670eb 1269extern ipc_port_t convert_thread_to_port(thread_t);
813fb2f6 1270extern ipc_port_t convert_thread_inspect_to_port(thread_inspect_t);
39037602 1271extern boolean_t is_vm_privileged(void);
fe8ab488 1272extern boolean_t set_vm_privilege(boolean_t);
5ba3f43e 1273extern kern_allocation_name_t thread_set_allocation_name(kern_allocation_name_t new_name);
6d2010ae 1274#endif /* KERNEL_PRIVATE */
55e303ae 1275
91447636 1276__END_DECLS
55e303ae 1277
1c79356b 1278#endif /* _KERN_THREAD_H_ */