]> git.saurik.com Git - apple/xnu.git/blame - osfmk/kern/thread.c
xnu-3789.1.32.tar.gz
[apple/xnu.git] / osfmk / kern / thread.c
CommitLineData
1c79356b 1/*
3e170ce0 2 * Copyright (c) 2000-2015 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: kern/thread.c
60 * Author: Avadis Tevanian, Jr., Michael Wayne Young, David Golub
61 * Date: 1986
62 *
91447636 63 * Thread management primitives implementation.
1c79356b
A
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
91447636 84#include <mach/mach_types.h>
1c79356b
A
85#include <mach/boolean.h>
86#include <mach/policy.h>
87#include <mach/thread_info.h>
88#include <mach/thread_special_ports.h>
89#include <mach/thread_status.h>
90#include <mach/time_value.h>
91#include <mach/vm_param.h>
91447636
A
92
93#include <machine/thread.h>
6d2010ae 94#include <machine/pal_routines.h>
316670eb 95#include <machine/limits.h>
91447636
A
96
97#include <kern/kern_types.h>
98#include <kern/kalloc.h>
1c79356b
A
99#include <kern/cpu_data.h>
100#include <kern/counters.h>
6d2010ae 101#include <kern/extmod_statistics.h>
1c79356b
A
102#include <kern/ipc_mig.h>
103#include <kern/ipc_tt.h>
104#include <kern/mach_param.h>
105#include <kern/machine.h>
106#include <kern/misc_protos.h>
107#include <kern/processor.h>
108#include <kern/queue.h>
109#include <kern/sched.h>
110#include <kern/sched_prim.h>
91447636
A
111#include <kern/sync_lock.h>
112#include <kern/syscall_subr.h>
1c79356b
A
113#include <kern/task.h>
114#include <kern/thread.h>
1c79356b
A
115#include <kern/host.h>
116#include <kern/zalloc.h>
1c79356b 117#include <kern/assert.h>
39236c6e
A
118#include <kern/exc_resource.h>
119#include <kern/telemetry.h>
39037602
A
120#include <kern/policy_internal.h>
121
3e170ce0 122#include <corpses/task_corpse.h>
39236c6e
A
123#if KPC
124#include <kern/kpc.h>
125#endif
91447636
A
126
127#include <ipc/ipc_kmsg.h>
128#include <ipc/ipc_port.h>
fe8ab488 129#include <bank/bank_types.h>
91447636
A
130
131#include <vm/vm_kern.h>
132#include <vm/vm_pageout.h>
133
1c79356b 134#include <sys/kdebug.h>
3e170ce0 135#include <sys/bsdtask_info.h>
2d21ac55
A
136#include <mach/sdt.h>
137
1c79356b
A
138/*
139 * Exported interfaces
140 */
91447636 141#include <mach/task_server.h>
1c79356b
A
142#include <mach/thread_act_server.h>
143#include <mach/mach_host_server.h>
91447636 144#include <mach/host_priv_server.h>
fe8ab488 145#include <mach/mach_voucher_server.h>
39037602 146#include <kern/policy_internal.h>
1c79356b 147
55e303ae 148static struct zone *thread_zone;
b0d623f7
A
149static lck_grp_attr_t thread_lck_grp_attr;
150lck_attr_t thread_lck_attr;
151lck_grp_t thread_lck_grp;
1c79356b 152
a1c7dba1
A
153struct zone *thread_qos_override_zone;
154
91447636
A
155decl_simple_lock_data(static,thread_stack_lock)
156static queue_head_t thread_stack_queue;
1c79356b 157
91447636
A
158decl_simple_lock_data(static,thread_terminate_lock)
159static queue_head_t thread_terminate_queue;
1c79356b 160
3e170ce0
A
161static queue_head_t crashed_threads_queue;
162
39037602
A
163decl_simple_lock_data(static,thread_exception_lock)
164static queue_head_t thread_exception_queue;
165
166struct thread_exception_elt {
167 queue_chain_t elt;
168 task_t exception_task;
169 thread_t exception_thread;
170};
171
55e303ae 172static struct thread thread_template, init_thread;
1c79356b 173
2d21ac55
A
174static void sched_call_null(
175 int type,
176 thread_t thread);
b0d623f7 177
91447636
A
178#ifdef MACH_BSD
179extern void proc_exit(void *);
39037602 180extern mach_exception_data_type_t proc_encode_exit_exception_code(void *);
b0d623f7 181extern uint64_t get_dispatchqueue_offset_from_proc(void *);
39236c6e
A
182extern int proc_selfpid(void);
183extern char * proc_name_address(void *p);
91447636 184#endif /* MACH_BSD */
b0d623f7 185
39236c6e 186extern int disable_exc_resource;
15129b1c 187extern int audio_active;
2d21ac55 188extern int debug_task;
b0d623f7
A
189int thread_max = CONFIG_THREAD_MAX; /* Max number of threads */
190int task_threadmax = CONFIG_THREAD_MAX;
191
fe8ab488 192static uint64_t thread_unique_id = 100;
55e303ae 193
316670eb
A
194struct _thread_ledger_indices thread_ledgers = { -1 };
195static ledger_template_t thread_ledger_template = NULL;
39037602 196static void init_thread_ledgers(void);
39236c6e 197
fe8ab488
A
198#if CONFIG_JETSAM
199void jetsam_on_ledger_cpulimit_exceeded(void);
200#endif
201
39236c6e
A
202/*
203 * Level (in terms of percentage of the limit) at which the CPU usage monitor triggers telemetry.
204 *
205 * (ie when any thread's CPU consumption exceeds 70% of the limit, start taking user
206 * stacktraces, aka micro-stackshots)
207 */
208#define CPUMON_USTACKSHOTS_TRIGGER_DEFAULT_PCT 70
209
210int cpumon_ustackshots_trigger_pct; /* Percentage. Level at which we start gathering telemetry. */
39037602 211void __attribute__((noinline)) SENDING_NOTIFICATION__THIS_THREAD_IS_CONSUMING_TOO_MUCH_CPU(void);
39236c6e
A
212
213/*
214 * The smallest interval over which we support limiting CPU consumption is 1ms
215 */
216#define MINIMUM_CPULIMIT_INTERVAL_MS 1
316670eb 217
91447636
A
218void
219thread_bootstrap(void)
220{
221 /*
222 * Fill in a template thread for fast initialization.
223 */
1c79356b 224
39037602
A
225#if MACH_ASSERT
226 thread_template.thread_magic = THREAD_MAGIC;
227#endif /* MACH_ASSERT */
228
2d21ac55 229 thread_template.runq = PROCESSOR_NULL;
1c79356b 230
91447636 231 thread_template.ref_count = 2;
55e303ae 232
91447636
A
233 thread_template.reason = AST_NONE;
234 thread_template.at_safe_point = FALSE;
235 thread_template.wait_event = NO_EVENT64;
3e170ce0 236 thread_template.waitq = NULL;
91447636
A
237 thread_template.wait_result = THREAD_WAITING;
238 thread_template.options = THREAD_ABORTSAFE;
239 thread_template.state = TH_WAIT | TH_UNINT;
240 thread_template.wake_active = FALSE;
241 thread_template.continuation = THREAD_CONTINUE_NULL;
242 thread_template.parameter = NULL;
1c79356b 243
91447636 244 thread_template.importance = 0;
6d2010ae
A
245 thread_template.sched_mode = TH_MODE_NONE;
246 thread_template.sched_flags = 0;
247 thread_template.saved_mode = TH_MODE_NONE;
91447636 248 thread_template.safe_release = 0;
39037602 249 thread_template.th_sched_bucket = TH_BUCKET_RUN;
0b4e3aa0 250
fe8ab488
A
251 thread_template.sfi_class = SFI_CLASS_UNSPECIFIED;
252 thread_template.sfi_wait_class = SFI_CLASS_UNSPECIFIED;
253
254 thread_template.active = 0;
255 thread_template.started = 0;
256 thread_template.static_param = 0;
257 thread_template.policy_reset = 0;
258
490019cf 259 thread_template.base_pri = BASEPRI_DEFAULT;
91447636
A
260 thread_template.sched_pri = 0;
261 thread_template.max_priority = 0;
262 thread_template.task_priority = 0;
263 thread_template.promotions = 0;
264 thread_template.pending_promoter_index = 0;
3e170ce0 265 thread_template.pending_promoter[0] = NULL;
316670eb 266 thread_template.pending_promoter[1] = NULL;
39236c6e 267 thread_template.rwlock_count = 0;
1c79356b 268
fe8ab488 269
91447636 270 thread_template.realtime.deadline = UINT64_MAX;
1c79356b 271
fe8ab488 272 thread_template.quantum_remaining = 0;
6d2010ae 273 thread_template.last_run_time = 0;
3e170ce0 274 thread_template.last_made_runnable_time = 0;
1c79356b 275
91447636
A
276 thread_template.computation_metered = 0;
277 thread_template.computation_epoch = 0;
1c79356b 278
fe8ab488 279#if defined(CONFIG_SCHED_TIMESHARE_CORE)
91447636 280 thread_template.sched_stamp = 0;
91447636 281 thread_template.pri_shift = INT8_MAX;
6d2010ae 282 thread_template.sched_usage = 0;
91447636 283 thread_template.cpu_usage = thread_template.cpu_delta = 0;
6d2010ae 284#endif
2d21ac55 285 thread_template.c_switch = thread_template.p_switch = thread_template.ps_switch = 0;
0b4e3aa0 286
91447636
A
287 thread_template.bound_processor = PROCESSOR_NULL;
288 thread_template.last_processor = PROCESSOR_NULL;
1c79356b 289
2d21ac55
A
290 thread_template.sched_call = sched_call_null;
291
91447636
A
292 timer_init(&thread_template.user_timer);
293 timer_init(&thread_template.system_timer);
294 thread_template.user_timer_save = 0;
295 thread_template.system_timer_save = 0;
2d21ac55
A
296 thread_template.vtimer_user_save = 0;
297 thread_template.vtimer_prof_save = 0;
298 thread_template.vtimer_rlim_save = 0;
39037602 299 thread_template.vtimer_qos_save = 0;
1c79356b 300
3e170ce0 301#if CONFIG_SCHED_SFI
fe8ab488 302 thread_template.wait_sfi_begin_time = 0;
3e170ce0 303#endif
fe8ab488 304
91447636
A
305 thread_template.wait_timer_is_set = FALSE;
306 thread_template.wait_timer_active = 0;
1c79356b 307
91447636 308 thread_template.depress_timer_active = 0;
0b4e3aa0 309
91447636 310 thread_template.recover = (vm_offset_t)NULL;
2d21ac55
A
311
312 thread_template.map = VM_MAP_NULL;
313
314#if CONFIG_DTRACE
315 thread_template.t_dtrace_predcache = 0;
316 thread_template.t_dtrace_vtime = 0;
317 thread_template.t_dtrace_tracing = 0;
318#endif /* CONFIG_DTRACE */
b0d623f7 319
39037602
A
320#if KPERF
321 thread_template.kperf_flags = 0;
322 thread_template.kperf_pet_gen = 0;
323 thread_template.kperf_c_switch = 0;
324 thread_template.kperf_pet_cnt = 0;
325#endif
326
39236c6e
A
327#if KPC
328 thread_template.kpc_buf = NULL;
329#endif
330
fe8ab488
A
331#if HYPERVISOR
332 thread_template.hv_thread_target = NULL;
333#endif /* HYPERVISOR */
334
04b8595b
A
335#if (DEVELOPMENT || DEBUG)
336 thread_template.t_page_creation_throttled_hard = 0;
337 thread_template.t_page_creation_throttled_soft = 0;
338#endif /* DEVELOPMENT || DEBUG */
339 thread_template.t_page_creation_throttled = 0;
b0d623f7
A
340 thread_template.t_page_creation_count = 0;
341 thread_template.t_page_creation_time = 0;
55e303ae 342
2d21ac55
A
343 thread_template.affinity_set = NULL;
344
6d2010ae
A
345 thread_template.syscalls_unix = 0;
346 thread_template.syscalls_mach = 0;
347
316670eb
A
348 thread_template.t_ledger = LEDGER_NULL;
349 thread_template.t_threadledger = LEDGER_NULL;
fe8ab488
A
350#ifdef CONFIG_BANK
351 thread_template.t_bankledger = LEDGER_NULL;
352 thread_template.t_deduct_bank_ledger_time = 0;
353#endif
316670eb 354
39037602
A
355 thread_template.requested_policy = (struct thread_requested_policy) {};
356 thread_template.effective_policy = (struct thread_effective_policy) {};
39236c6e 357
a1c7dba1 358 bzero(&thread_template.overrides, sizeof(thread_template.overrides));
39236c6e 359
fe8ab488
A
360 thread_template.iotier_override = THROTTLE_LEVEL_NONE;
361 thread_template.thread_io_stats = NULL;
39236c6e
A
362 thread_template.thread_callout_interrupt_wakeups = thread_template.thread_callout_platform_idle_wakeups = 0;
363
364 thread_template.thread_timer_wakeups_bin_1 = thread_template.thread_timer_wakeups_bin_2 = 0;
365 thread_template.callout_woken_from_icontext = thread_template.callout_woken_from_platform_idle = 0;
366
367 thread_template.thread_tag = 0;
6d2010ae 368
fe8ab488
A
369 thread_template.ith_voucher_name = MACH_PORT_NULL;
370 thread_template.ith_voucher = IPC_VOUCHER_NULL;
371
3e170ce0
A
372 thread_template.work_interval_id = 0;
373
91447636
A
374 init_thread = thread_template;
375 machine_set_current_thread(&init_thread);
1c79356b
A
376}
377
fe8ab488
A
378extern boolean_t allow_qos_policy_set;
379
55e303ae 380void
91447636 381thread_init(void)
0b4e3aa0 382{
91447636
A
383 thread_zone = zinit(
384 sizeof(struct thread),
b0d623f7 385 thread_max * sizeof(struct thread),
91447636
A
386 THREAD_CHUNK * sizeof(struct thread),
387 "threads");
6d2010ae 388
a1c7dba1
A
389 thread_qos_override_zone = zinit(
390 sizeof(struct thread_qos_override),
391 4 * thread_max * sizeof(struct thread_qos_override),
392 PAGE_SIZE,
393 "thread qos override");
394 zone_change(thread_qos_override_zone, Z_EXPAND, TRUE);
395 zone_change(thread_qos_override_zone, Z_COLLECT, TRUE);
396 zone_change(thread_qos_override_zone, Z_CALLERACCT, FALSE);
397 zone_change(thread_qos_override_zone, Z_NOENCRYPT, TRUE);
398
b0d623f7
A
399 lck_grp_attr_setdefault(&thread_lck_grp_attr);
400 lck_grp_init(&thread_lck_grp, "thread", &thread_lck_grp_attr);
401 lck_attr_setdefault(&thread_lck_attr);
39037602 402
91447636 403 stack_init();
55e303ae 404
39037602
A
405 thread_policy_init();
406
91447636
A
407 /*
408 * Initialize any machine-dependent
409 * per-thread structures necessary.
410 */
411 machine_thread_init();
316670eb 412
39236c6e
A
413 if (!PE_parse_boot_argn("cpumon_ustackshots_trigger_pct", &cpumon_ustackshots_trigger_pct,
414 sizeof (cpumon_ustackshots_trigger_pct))) {
415 cpumon_ustackshots_trigger_pct = CPUMON_USTACKSHOTS_TRIGGER_DEFAULT_PCT;
416 }
417
fe8ab488
A
418 PE_parse_boot_argn("-qos-policy-allow", &allow_qos_policy_set, sizeof(allow_qos_policy_set));
419
316670eb 420 init_thread_ledgers();
91447636 421}
0b4e3aa0 422
39037602
A
423void
424thread_corpse_continue(void)
425{
426 thread_t thread = current_thread();
427
428 thread_terminate_internal(thread);
429 ml_set_interrupts_enabled(FALSE);
430 ast_taken(AST_APC, TRUE);
431
432 panic("thread_corpse_continue");
433 /*NOTREACHED*/
434}
435
91447636
A
436static void
437thread_terminate_continue(void)
438{
439 panic("thread_terminate_continue");
440 /*NOTREACHED*/
0b4e3aa0
A
441}
442
1c79356b 443/*
91447636 444 * thread_terminate_self:
1c79356b 445 */
1c79356b 446void
91447636 447thread_terminate_self(void)
1c79356b 448{
91447636
A
449 thread_t thread = current_thread();
450 task_t task;
451 spl_t s;
b0d623f7
A
452 int threadcnt;
453
6d2010ae
A
454 pal_thread_terminate_self(thread);
455
b0d623f7 456 DTRACE_PROC(lwp__exit);
2d21ac55
A
457
458 thread_mtx_lock(thread);
459
2d21ac55 460 ipc_thread_disable(thread);
39037602 461
2d21ac55 462 thread_mtx_unlock(thread);
55e303ae 463
91447636
A
464 s = splsched();
465 thread_lock(thread);
1c79356b 466
91447636 467 /*
2d21ac55
A
468 * Cancel priority depression, wait for concurrent expirations
469 * on other processors.
91447636 470 */
6d2010ae
A
471 if (thread->sched_flags & TH_SFLAG_DEPRESSED_MASK) {
472 thread->sched_flags &= ~TH_SFLAG_DEPRESSED_MASK;
1c79356b 473
fe8ab488 474 /* If our priority was low because of a depressed yield, restore it in case we block below */
3e170ce0 475 thread_recompute_sched_pri(thread, FALSE);
fe8ab488 476
91447636
A
477 if (timer_call_cancel(&thread->depress_timer))
478 thread->depress_timer_active--;
1c79356b 479 }
1c79356b 480
91447636
A
481 while (thread->depress_timer_active > 0) {
482 thread_unlock(thread);
483 splx(s);
55e303ae 484
91447636 485 delay(1);
55e303ae 486
91447636
A
487 s = splsched();
488 thread_lock(thread);
55e303ae
A
489 }
490
b0d623f7
A
491 thread_sched_call(thread, NULL);
492
91447636
A
493 thread_unlock(thread);
494 splx(s);
55e303ae 495
fe8ab488
A
496
497 thread_mtx_lock(thread);
498
2d21ac55 499 thread_policy_reset(thread);
55e303ae 500
fe8ab488 501 thread_mtx_unlock(thread);
316670eb 502
b0d623f7 503 task = thread->task;
39037602 504 uthread_cleanup(task, thread->uthread, task->bsd_info);
b0d623f7
A
505 threadcnt = hw_atomic_sub(&task->active_thread_count, 1);
506
39037602
A
507 if (task->bsd_info) {
508 /* trace out pid before we sign off */
509 long dbg_arg1 = 0;
510
511 kdbg_trace_data(thread->task->bsd_info, &dbg_arg1);
512
513 KERNEL_DEBUG_CONSTANT(TRACE_DATA_THREAD_TERMINATE_PID | DBG_FUNC_NONE,
514 dbg_arg1, 0, 0, 0, 0);
515 }
516
91447636
A
517 /*
518 * If we are the last thread to terminate and the task is
519 * associated with a BSD process, perform BSD process exit.
520 */
3e170ce0 521 if (threadcnt == 0 && task->bsd_info != NULL) {
39037602
A
522 mach_exception_data_type_t subcode = 0;
523 {
524 /* since we're the last thread in this process, trace out the command name too */
525 long dbg_arg1 = 0, dbg_arg2 = 0, dbg_arg3 = 0, dbg_arg4 = 0;
526
527 kdbg_trace_string(thread->task->bsd_info, &dbg_arg1, &dbg_arg2, &dbg_arg3, &dbg_arg4);
528
529 KERNEL_DEBUG_CONSTANT(TRACE_STRING_PROC_EXIT | DBG_FUNC_NONE,
530 dbg_arg1, dbg_arg2, dbg_arg3, dbg_arg4, 0);
531 }
532
533 /* Get the exit reason before proc_exit */
534 subcode = proc_encode_exit_exception_code(task->bsd_info);
91447636 535 proc_exit(task->bsd_info);
3e170ce0
A
536 /*
537 * if there is crash info in task
538 * then do the deliver action since this is
539 * last thread for this task.
540 */
541 if (task->corpse_info) {
39037602
A
542 task_deliver_crash_notification(task, current_thread(), subcode);
543 }
544 }
545
546 if (threadcnt == 0) {
547 task_lock(task);
548 if (task_is_a_corpse_fork(task)) {
549 thread_wakeup((event_t)&task->active_thread_count);
3e170ce0 550 }
39037602 551 task_unlock(task);
3e170ce0 552 }
39037602 553
2d21ac55
A
554 uthread_cred_free(thread->uthread);
555
91447636
A
556 s = splsched();
557 thread_lock(thread);
1c79356b 558
91447636
A
559 /*
560 * Cancel wait timer, and wait for
561 * concurrent expirations.
562 */
563 if (thread->wait_timer_is_set) {
564 thread->wait_timer_is_set = FALSE;
1c79356b 565
91447636
A
566 if (timer_call_cancel(&thread->wait_timer))
567 thread->wait_timer_active--;
568 }
1c79356b 569
91447636
A
570 while (thread->wait_timer_active > 0) {
571 thread_unlock(thread);
572 splx(s);
0b4e3aa0 573
91447636 574 delay(1);
1c79356b 575
91447636
A
576 s = splsched();
577 thread_lock(thread);
578 }
1c79356b 579
91447636
A
580 /*
581 * If there is a reserved stack, release it.
582 */
583 if (thread->reserved_stack != 0) {
6d2010ae 584 stack_free_reserved(thread);
91447636
A
585 thread->reserved_stack = 0;
586 }
1c79356b 587
91447636
A
588 /*
589 * Mark thread as terminating, and block.
590 */
591 thread->state |= TH_TERMINATE;
592 thread_mark_wait_locked(thread, THREAD_UNINT);
3e170ce0 593 assert((thread->sched_flags & TH_SFLAG_PROMOTED) == 0);
91447636 594 assert(thread->promotions == 0);
3e170ce0 595 assert(!(thread->sched_flags & TH_SFLAG_WAITQ_PROMOTED));
39236c6e 596 assert(thread->rwlock_count == 0);
91447636
A
597 thread_unlock(thread);
598 /* splsched */
1c79356b 599
91447636
A
600 thread_block((thread_continue_t)thread_terminate_continue);
601 /*NOTREACHED*/
55e303ae
A
602}
603
3e170ce0
A
604/* Drop a thread refcount that definitely isn't the last one. */
605void
606thread_deallocate_safe(thread_t thread)
607{
39037602
A
608 assert_thread_magic(thread);
609
610 uint32_t old_refcount = hw_atomic_sub(&(thread)->ref_count, 1) + 1;
611
612 if (__improbable(old_refcount <= 1))
613 panic("bad thread refcount: %d", old_refcount);
3e170ce0
A
614}
615
55e303ae 616void
91447636
A
617thread_deallocate(
618 thread_t thread)
1c79356b 619{
91447636 620 task_t task;
1c79356b 621
91447636
A
622 if (thread == THREAD_NULL)
623 return;
1c79356b 624
39037602
A
625 assert_thread_magic(thread);
626 assert(thread->ref_count > 0);
627
3e170ce0 628 if (__probable(hw_atomic_sub(&(thread)->ref_count, 1) > 0))
91447636 629 return;
1c79356b 630
39236c6e
A
631 if(!(thread->state & TH_TERMINATE2))
632 panic("thread_deallocate: thread not properly terminated\n");
633
3e170ce0
A
634 assert(thread->runq == PROCESSOR_NULL);
635
39037602
A
636 assert(thread->user_promotions == 0);
637
39236c6e
A
638#if KPC
639 kpc_thread_destroy(thread);
640#endif
641
91447636 642 ipc_thread_terminate(thread);
1c79356b 643
a1c7dba1
A
644 proc_thread_qos_deallocate(thread);
645
91447636 646 task = thread->task;
0b4e3aa0 647
91447636
A
648#ifdef MACH_BSD
649 {
650 void *ut = thread->uthread;
0b4e3aa0 651
91447636 652 thread->uthread = NULL;
2d21ac55 653 uthread_zone_free(ut);
91447636
A
654 }
655#endif /* MACH_BSD */
0b4e3aa0 656
316670eb
A
657 if (thread->t_ledger)
658 ledger_dereference(thread->t_ledger);
659 if (thread->t_threadledger)
660 ledger_dereference(thread->t_threadledger);
661
fe8ab488
A
662 if (IPC_VOUCHER_NULL != thread->ith_voucher)
663 ipc_voucher_release(thread->ith_voucher);
664
665 if (thread->thread_io_stats)
666 kfree(thread->thread_io_stats, sizeof(struct io_stat_info));
667
91447636
A
668 if (thread->kernel_stack != 0)
669 stack_free(thread);
0b4e3aa0 670
b0d623f7 671 lck_mtx_destroy(&thread->mutex, &thread_lck_grp);
91447636 672 machine_thread_destroy(thread);
1c79356b 673
6d2010ae
A
674 task_deallocate(task);
675
39037602
A
676#if MACH_ASSERT
677 assert_thread_magic(thread);
678 thread->thread_magic = 0;
679#endif /* MACH_ASSERT */
680
91447636
A
681 zfree(thread_zone, thread);
682}
0b4e3aa0 683
39037602
A
684/*
685 * thread_exception_daemon:
686 *
687 * Deliver EXC_RESOURCE exception
688 */
689static void
690thread_exception_daemon(void)
691{
692 struct thread_exception_elt *elt;
693 task_t task;
694 thread_t thread;
695
696 simple_lock(&thread_exception_lock);
697 while ((elt = (struct thread_exception_elt *)dequeue_head(&thread_exception_queue)) != NULL) {
698 simple_unlock(&thread_exception_lock);
699
700 task = elt->exception_task;
701 thread = elt->exception_thread;
702 assert_thread_magic(thread);
703
704 kfree(elt, sizeof(struct thread_exception_elt));
705
706 /* wait for all the threads in the task to terminate */
707 task_lock(task);
708 task_wait_till_threads_terminate_locked(task);
709 task_unlock(task);
710
711 /* Consumes the task ref returned by task_generate_corpse_internal */
712 task_deallocate(task);
713 /* Consumes the thread ref returned by task_generate_corpse_internal */
714 thread_deallocate(thread);
715
716 /* Deliver the EXC_RESOURCE notification, also clears the corpse. */
717 task_deliver_crash_notification(task, thread, 0);
718
719 simple_lock(&thread_exception_lock);
720 }
721
722 assert_wait((event_t)&thread_exception_queue, THREAD_UNINT);
723 simple_unlock(&thread_exception_lock);
724
725 thread_block((thread_continue_t)thread_exception_daemon);
726}
727
728/*
729 * thread_exception_enqueue:
730 *
731 * Enqueue a corpse port to be delivered an EXC_RESOURCE.
732 */
733void
734thread_exception_enqueue(
735 task_t task,
736 thread_t thread)
737{
738 struct thread_exception_elt *elt = (struct thread_exception_elt*) kalloc(
739 sizeof(struct thread_exception_elt));
740
741 elt->exception_task = task;
742 elt->exception_thread = thread;
743
744 simple_lock(&thread_exception_lock);
745 enqueue_tail(&thread_exception_queue, (queue_entry_t)elt);
746 simple_unlock(&thread_exception_lock);
747
748 thread_wakeup((event_t)&thread_exception_queue);
749}
750
751/*
752 * thread_copy_resource_info
753 *
754 * Copy the resource info counters from source
755 * thread to destination thread.
756 */
757void
758thread_copy_resource_info(
759 thread_t dst_thread,
760 thread_t src_thread)
761{
762 dst_thread->thread_tag = src_thread->thread_tag;
763 dst_thread->c_switch = src_thread->c_switch;
764 dst_thread->p_switch = src_thread->p_switch;
765 dst_thread->ps_switch = src_thread->ps_switch;
766 dst_thread->precise_user_kernel_time = src_thread->precise_user_kernel_time;
767 dst_thread->user_timer = src_thread->user_timer;
768 dst_thread->user_timer_save = src_thread->user_timer_save;
769 dst_thread->system_timer_save = src_thread->system_timer_save;
770 dst_thread->syscalls_unix = src_thread->syscalls_unix;
771 dst_thread->syscalls_mach = src_thread->syscalls_mach;
772 ledger_rollup(dst_thread->t_threadledger, src_thread->t_threadledger);
773 *dst_thread->thread_io_stats = *src_thread->thread_io_stats;
774
775}
776
91447636
A
777/*
778 * thread_terminate_daemon:
779 *
780 * Perform final clean up for terminating threads.
781 */
782static void
783thread_terminate_daemon(void)
784{
6d2010ae
A
785 thread_t self, thread;
786 task_t task;
787
788 self = current_thread();
789 self->options |= TH_OPT_SYSTEM_CRITICAL;
0b4e3aa0 790
91447636
A
791 (void)splsched();
792 simple_lock(&thread_terminate_lock);
0b4e3aa0 793
39037602
A
794 while ((thread = qe_dequeue_head(&thread_terminate_queue, struct thread, runq_links)) != THREAD_NULL) {
795 assert_thread_magic(thread);
3e170ce0
A
796
797 /*
798 * if marked for crash reporting, skip reaping.
799 * The corpse delivery thread will clear bit and enqueue
800 * for reaping when done
801 */
802 if (thread->inspection){
39037602 803 enqueue_tail(&crashed_threads_queue, &thread->runq_links);
3e170ce0
A
804 continue;
805 }
806
91447636
A
807 simple_unlock(&thread_terminate_lock);
808 (void)spllo();
0b4e3aa0 809
91447636 810 task = thread->task;
55e303ae 811
91447636
A
812 task_lock(task);
813 task->total_user_time += timer_grab(&thread->user_timer);
316670eb
A
814 if (thread->precise_user_kernel_time) {
815 task->total_system_time += timer_grab(&thread->system_timer);
816 } else {
817 task->total_user_time += timer_grab(&thread->system_timer);
818 }
55e303ae 819
2d21ac55
A
820 task->c_switch += thread->c_switch;
821 task->p_switch += thread->p_switch;
822 task->ps_switch += thread->ps_switch;
823
6d2010ae
A
824 task->syscalls_unix += thread->syscalls_unix;
825 task->syscalls_mach += thread->syscalls_mach;
826
4b17d6b6
A
827 task->task_timer_wakeups_bin_1 += thread->thread_timer_wakeups_bin_1;
828 task->task_timer_wakeups_bin_2 += thread->thread_timer_wakeups_bin_2;
fe8ab488 829 task->task_gpu_ns += ml_gpu_stat(thread);
39037602
A
830 task->task_energy += ml_energy_stat(thread);
831
832 thread_update_qos_cpu_time(thread);
833
91447636
A
834 queue_remove(&task->threads, thread, thread_t, task_threads);
835 task->thread_count--;
b0d623f7
A
836
837 /*
838 * If the task is being halted, and there is only one thread
839 * left in the task after this one, then wakeup that thread.
840 */
841 if (task->thread_count == 1 && task->halting)
842 thread_wakeup((event_t)&task->halting);
843
91447636 844 task_unlock(task);
1c79356b 845
b0d623f7 846 lck_mtx_lock(&tasks_threads_lock);
2d21ac55
A
847 queue_remove(&threads, thread, thread_t, threads);
848 threads_count--;
b0d623f7 849 lck_mtx_unlock(&tasks_threads_lock);
1c79356b 850
91447636 851 thread_deallocate(thread);
1c79356b 852
91447636
A
853 (void)splsched();
854 simple_lock(&thread_terminate_lock);
0b4e3aa0 855 }
1c79356b 856
91447636
A
857 assert_wait((event_t)&thread_terminate_queue, THREAD_UNINT);
858 simple_unlock(&thread_terminate_lock);
859 /* splsched */
860
6d2010ae 861 self->options &= ~TH_OPT_SYSTEM_CRITICAL;
91447636
A
862 thread_block((thread_continue_t)thread_terminate_daemon);
863 /*NOTREACHED*/
1c79356b
A
864}
865
9bccf70c 866/*
91447636
A
867 * thread_terminate_enqueue:
868 *
869 * Enqueue a terminating thread for final disposition.
870 *
871 * Called at splsched.
9bccf70c 872 */
1c79356b 873void
91447636 874thread_terminate_enqueue(
1c79356b
A
875 thread_t thread)
876{
04b8595b 877 KERNEL_DEBUG_CONSTANT(TRACE_DATA_THREAD_TERMINATE | DBG_FUNC_NONE, thread->thread_id, 0, 0, 0, 0);
fe8ab488 878
91447636 879 simple_lock(&thread_terminate_lock);
39037602 880 enqueue_tail(&thread_terminate_queue, &thread->runq_links);
91447636 881 simple_unlock(&thread_terminate_lock);
1c79356b 882
91447636 883 thread_wakeup((event_t)&thread_terminate_queue);
1c79356b
A
884}
885
3e170ce0
A
886/*
887 * thread_terminate_crashed_threads:
39037602 888 * walk the list of crashed threads and put back set of threads
3e170ce0
A
889 * who are no longer being inspected.
890 */
891void
892thread_terminate_crashed_threads()
893{
39037602 894 thread_t th_remove;
3e170ce0
A
895 boolean_t should_wake_terminate_queue = FALSE;
896
897 simple_lock(&thread_terminate_lock);
898 /*
899 * loop through the crashed threads queue
900 * to put any threads that are not being inspected anymore
901 */
3e170ce0 902
39037602 903 qe_foreach_element_safe(th_remove, &crashed_threads_queue, runq_links) {
3e170ce0
A
904 /* make sure current_thread is never in crashed queue */
905 assert(th_remove != current_thread());
39037602
A
906
907 if (th_remove->inspection == FALSE) {
908 re_queue_tail(&thread_terminate_queue, &th_remove->runq_links);
3e170ce0
A
909 should_wake_terminate_queue = TRUE;
910 }
911 }
912
913 simple_unlock(&thread_terminate_lock);
914 if (should_wake_terminate_queue == TRUE) {
915 thread_wakeup((event_t)&thread_terminate_queue);
916 }
917}
918
91447636
A
919/*
920 * thread_stack_daemon:
921 *
922 * Perform stack allocation as required due to
923 * invoke failures.
924 */
925static void
926thread_stack_daemon(void)
9bccf70c 927{
91447636 928 thread_t thread;
39236c6e 929 spl_t s;
91447636 930
39236c6e 931 s = splsched();
91447636
A
932 simple_lock(&thread_stack_lock);
933
39037602
A
934 while ((thread = qe_dequeue_head(&thread_stack_queue, struct thread, runq_links)) != THREAD_NULL) {
935 assert_thread_magic(thread);
936
91447636 937 simple_unlock(&thread_stack_lock);
39236c6e 938 splx(s);
91447636 939
39236c6e 940 /* allocate stack with interrupts enabled so that we can call into VM */
91447636 941 stack_alloc(thread);
3e170ce0
A
942
943 KERNEL_DEBUG_CONSTANT(MACHDBG_CODE(DBG_MACH_SCHED,MACH_STACK_WAIT) | DBG_FUNC_END, thread_tid(thread), 0, 0, 0, 0);
2d21ac55 944
39236c6e 945 s = splsched();
91447636
A
946 thread_lock(thread);
947 thread_setrun(thread, SCHED_PREEMPT | SCHED_TAILQ);
948 thread_unlock(thread);
91447636 949
91447636
A
950 simple_lock(&thread_stack_lock);
951 }
952
953 assert_wait((event_t)&thread_stack_queue, THREAD_UNINT);
954 simple_unlock(&thread_stack_lock);
39236c6e 955 splx(s);
91447636
A
956
957 thread_block((thread_continue_t)thread_stack_daemon);
9bccf70c
A
958 /*NOTREACHED*/
959}
1c79356b
A
960
961/*
91447636 962 * thread_stack_enqueue:
1c79356b 963 *
91447636 964 * Enqueue a thread for stack allocation.
1c79356b 965 *
91447636 966 * Called at splsched.
1c79356b
A
967 */
968void
91447636
A
969thread_stack_enqueue(
970 thread_t thread)
1c79356b 971{
3e170ce0 972 KERNEL_DEBUG_CONSTANT(MACHDBG_CODE(DBG_MACH_SCHED,MACH_STACK_WAIT) | DBG_FUNC_START, thread_tid(thread), 0, 0, 0, 0);
39037602 973 assert_thread_magic(thread);
3e170ce0 974
91447636 975 simple_lock(&thread_stack_lock);
39037602 976 enqueue_tail(&thread_stack_queue, &thread->runq_links);
91447636 977 simple_unlock(&thread_stack_lock);
1c79356b 978
91447636
A
979 thread_wakeup((event_t)&thread_stack_queue);
980}
9bccf70c 981
91447636
A
982void
983thread_daemon_init(void)
984{
985 kern_return_t result;
6d2010ae 986 thread_t thread = NULL;
0b4e3aa0 987
91447636
A
988 simple_lock_init(&thread_terminate_lock, 0);
989 queue_init(&thread_terminate_queue);
3e170ce0 990 queue_init(&crashed_threads_queue);
1c79356b 991
91447636
A
992 result = kernel_thread_start_priority((thread_continue_t)thread_terminate_daemon, NULL, MINPRI_KERNEL, &thread);
993 if (result != KERN_SUCCESS)
994 panic("thread_daemon_init: thread_terminate_daemon");
1c79356b 995
91447636 996 thread_deallocate(thread);
1c79356b 997
91447636
A
998 simple_lock_init(&thread_stack_lock, 0);
999 queue_init(&thread_stack_queue);
1c79356b 1000
91447636
A
1001 result = kernel_thread_start_priority((thread_continue_t)thread_stack_daemon, NULL, BASEPRI_PREEMPT, &thread);
1002 if (result != KERN_SUCCESS)
1003 panic("thread_daemon_init: thread_stack_daemon");
1c79356b 1004
91447636 1005 thread_deallocate(thread);
39037602
A
1006
1007 simple_lock_init(&thread_exception_lock, 0);
1008 queue_init(&thread_exception_queue);
1009
1010 result = kernel_thread_start_priority((thread_continue_t)thread_exception_daemon, NULL, MINPRI_KERNEL, &thread);
1011 if (result != KERN_SUCCESS)
1012 panic("thread_daemon_init: thread_exception_daemon");
1013
1014 thread_deallocate(thread);
1c79356b
A
1015}
1016
3e170ce0
A
1017#define TH_OPTION_NONE 0x00
1018#define TH_OPTION_NOCRED 0x01
1019#define TH_OPTION_NOSUSP 0x02
39037602 1020
1c79356b
A
1021/*
1022 * Create a new thread.
55e303ae 1023 * Doesn't start the thread running.
fe8ab488
A
1024 *
1025 * Task and tasks_threads_lock are returned locked on success.
1c79356b 1026 */
55e303ae
A
1027static kern_return_t
1028thread_create_internal(
1029 task_t parent_task,
1c79356b 1030 integer_t priority,
91447636 1031 thread_continue_t continuation,
b0d623f7 1032 int options,
55e303ae 1033 thread_t *out_thread)
1c79356b 1034{
55e303ae 1035 thread_t new_thread;
55e303ae 1036 static thread_t first_thread;
1c79356b
A
1037
1038 /*
1039 * Allocate a thread and initialize static fields
1040 */
b0d623f7 1041 if (first_thread == THREAD_NULL)
91447636 1042 new_thread = first_thread = current_thread();
55e303ae
A
1043 else
1044 new_thread = (thread_t)zalloc(thread_zone);
b0d623f7 1045 if (new_thread == THREAD_NULL)
1c79356b
A
1046 return (KERN_RESOURCE_SHORTAGE);
1047
55e303ae
A
1048 if (new_thread != first_thread)
1049 *new_thread = thread_template;
1050
1051#ifdef MACH_BSD
b0d623f7
A
1052 new_thread->uthread = uthread_alloc(parent_task, new_thread, (options & TH_OPTION_NOCRED) != 0);
1053 if (new_thread->uthread == NULL) {
39037602
A
1054#if MACH_ASSERT
1055 new_thread->thread_magic = 0;
1056#endif /* MACH_ASSERT */
1057
b0d623f7
A
1058 zfree(thread_zone, new_thread);
1059 return (KERN_RESOURCE_SHORTAGE);
55e303ae
A
1060 }
1061#endif /* MACH_BSD */
1c79356b 1062
55e303ae
A
1063 if (machine_thread_create(new_thread, parent_task) != KERN_SUCCESS) {
1064#ifdef MACH_BSD
b0d623f7 1065 void *ut = new_thread->uthread;
1c79356b 1066
b0d623f7
A
1067 new_thread->uthread = NULL;
1068 /* cred free may not be necessary */
39037602 1069 uthread_cleanup(parent_task, ut, parent_task->bsd_info);
b0d623f7
A
1070 uthread_cred_free(ut);
1071 uthread_zone_free(ut);
55e303ae 1072#endif /* MACH_BSD */
b0d623f7 1073
39037602
A
1074#if MACH_ASSERT
1075 new_thread->thread_magic = 0;
1076#endif /* MACH_ASSERT */
1077
91447636 1078 zfree(thread_zone, new_thread);
55e303ae
A
1079 return (KERN_FAILURE);
1080 }
1081
316670eb 1082 new_thread->task = parent_task;
55e303ae
A
1083
1084 thread_lock_init(new_thread);
1085 wake_lock_init(new_thread);
1086
b0d623f7 1087 lck_mtx_init(&new_thread->mutex, &thread_lck_grp, &thread_lck_attr);
0b4e3aa0 1088
55e303ae 1089 ipc_thread_init(new_thread);
55e303ae 1090
91447636 1091 new_thread->continuation = continuation;
0b4e3aa0 1092
fe8ab488
A
1093 /* Allocate I/O Statistics structure */
1094 new_thread->thread_io_stats = (io_stat_info_t)kalloc(sizeof(struct io_stat_info));
1095 assert(new_thread->thread_io_stats != NULL);
1096 bzero(new_thread->thread_io_stats, sizeof(struct io_stat_info));
1097
1098#if CONFIG_IOSCHED
1099 /* Clear out the I/O Scheduling info for AppleFSCompression */
1100 new_thread->decmp_upl = NULL;
1101#endif /* CONFIG_IOSCHED */
1102
b0d623f7 1103 lck_mtx_lock(&tasks_threads_lock);
1c79356b
A
1104 task_lock(parent_task);
1105
39037602
A
1106 /*
1107 * Fail thread creation if parent task is being torn down or has too many threads
1108 * If the caller asked for TH_OPTION_NOSUSP, also fail if the parent task is suspended
1109 */
1110 if (parent_task->active == 0 || parent_task->halting ||
1111 (parent_task->suspend_count > 0 && (options & TH_OPTION_NOSUSP) != 0) ||
1112 (parent_task->thread_count >= task_threadmax && parent_task != kernel_task)) {
1c79356b 1113 task_unlock(parent_task);
b0d623f7 1114 lck_mtx_unlock(&tasks_threads_lock);
55e303ae
A
1115
1116#ifdef MACH_BSD
1117 {
55e303ae
A
1118 void *ut = new_thread->uthread;
1119
1120 new_thread->uthread = NULL;
39037602 1121 uthread_cleanup(parent_task, ut, parent_task->bsd_info);
2d21ac55
A
1122 /* cred free may not be necessary */
1123 uthread_cred_free(ut);
1124 uthread_zone_free(ut);
55e303ae
A
1125 }
1126#endif /* MACH_BSD */
91447636
A
1127 ipc_thread_disable(new_thread);
1128 ipc_thread_terminate(new_thread);
fe8ab488 1129 kfree(new_thread->thread_io_stats, sizeof(struct io_stat_info));
b0d623f7 1130 lck_mtx_destroy(&new_thread->mutex, &thread_lck_grp);
55e303ae 1131 machine_thread_destroy(new_thread);
91447636 1132 zfree(thread_zone, new_thread);
1c79356b
A
1133 return (KERN_FAILURE);
1134 }
1135
b0d623f7
A
1136 /* New threads inherit any default state on the task */
1137 machine_thread_inherit_taskwide(new_thread, parent_task);
1138
91447636 1139 task_reference_internal(parent_task);
55e303ae 1140
316670eb
A
1141 if (new_thread->task->rusage_cpu_flags & TASK_RUSECPU_FLAGS_PERTHR_LIMIT) {
1142 /*
1143 * This task has a per-thread CPU limit; make sure this new thread
1144 * gets its limit set too, before it gets out of the kernel.
1145 */
1146 set_astledger(new_thread);
1147 }
fe8ab488
A
1148
1149 /* Instantiate a thread ledger. Do not fail thread creation if ledger creation fails. */
1150 if ((new_thread->t_threadledger = ledger_instantiate(thread_ledger_template,
1151 LEDGER_CREATE_INACTIVE_ENTRIES)) != LEDGER_NULL) {
1152
1153 ledger_entry_setactive(new_thread->t_threadledger, thread_ledgers.cpu_time);
1154 }
1155
fe8ab488
A
1156#ifdef CONFIG_BANK
1157 new_thread->t_bankledger = LEDGER_NULL;
1158 new_thread->t_deduct_bank_ledger_time = 0;
1159#endif
1160
316670eb
A
1161 new_thread->t_ledger = new_thread->task->ledger;
1162 if (new_thread->t_ledger)
1163 ledger_reference(new_thread->t_ledger);
1164
fe8ab488
A
1165#if defined(CONFIG_SCHED_MULTIQ)
1166 /* Cache the task's sched_group */
1167 new_thread->sched_group = parent_task->sched_group;
1168#endif /* defined(CONFIG_SCHED_MULTIQ) */
1169
55e303ae
A
1170 /* Cache the task's map */
1171 new_thread->map = parent_task->map;
1c79356b 1172
91447636
A
1173 timer_call_setup(&new_thread->wait_timer, thread_timer_expire, new_thread);
1174 timer_call_setup(&new_thread->depress_timer, thread_depress_expire, new_thread);
1c79356b 1175
39236c6e
A
1176#if KPC
1177 kpc_thread_create(new_thread);
1178#endif
b0d623f7 1179
1c79356b 1180 /* Set the thread's scheduling parameters */
6d2010ae 1181 new_thread->sched_mode = SCHED(initial_thread_sched_mode)(parent_task);
55e303ae
A
1182 new_thread->max_priority = parent_task->max_priority;
1183 new_thread->task_priority = parent_task->priority;
316670eb 1184
3e170ce0
A
1185 int new_priority = (priority < 0) ? parent_task->priority: priority;
1186 new_priority = (priority < 0)? parent_task->priority: priority;
1187 if (new_priority > new_thread->max_priority)
1188 new_priority = new_thread->max_priority;
1189
1190 new_thread->importance = new_priority - new_thread->task_priority;
fe8ab488 1191
3e170ce0 1192 sched_set_thread_base_priority(new_thread, new_priority);
1c79356b 1193
39037602
A
1194#if defined(CONFIG_SCHED_TIMESHARE_CORE)
1195 new_thread->sched_stamp = sched_tick;
1196 new_thread->pri_shift = sched_pri_shifts[new_thread->th_sched_bucket];
1197#endif /* defined(CONFIG_SCHED_TIMESHARE_CORE) */
1198
490019cf 1199
fe8ab488
A
1200 thread_policy_create(new_thread);
1201
1202 /* Chain the thread onto the task's list */
1203 queue_enter(&parent_task->threads, new_thread, thread_t, task_threads);
1204 parent_task->thread_count++;
1205
1206 /* So terminating threads don't need to take the task lock to decrement */
1207 hw_atomic_add(&parent_task->active_thread_count, 1);
1208
1209 /* Protected by the tasks_threads_lock */
1210 new_thread->thread_id = ++thread_unique_id;
1211
1212 queue_enter(&threads, new_thread, thread_t, threads);
1213 threads_count++;
1214
55e303ae 1215 new_thread->active = TRUE;
39037602
A
1216 if (task_is_a_corpse_fork(parent_task)) {
1217 /* Set the inspection bit if the task is a corpse fork */
1218 new_thread->inspection = TRUE;
1219 } else {
1220 new_thread->inspection = FALSE;
1221 }
1222 new_thread->corpse_dup = FALSE;
55e303ae 1223 *out_thread = new_thread;
1c79356b
A
1224
1225 {
9bccf70c 1226 long dbg_arg1, dbg_arg2, dbg_arg3, dbg_arg4;
1c79356b 1227
55e303ae
A
1228 kdbg_trace_data(parent_task->bsd_info, &dbg_arg2);
1229
316670eb 1230 KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE,
39037602 1231 TRACE_DATA_NEWTHREAD | DBG_FUNC_NONE,
316670eb 1232 (vm_address_t)(uintptr_t)thread_tid(new_thread), dbg_arg2, 0, 0, 0);
1c79356b 1233
9bccf70c
A
1234 kdbg_trace_string(parent_task->bsd_info,
1235 &dbg_arg1, &dbg_arg2, &dbg_arg3, &dbg_arg4);
1236
316670eb 1237 KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE,
39037602 1238 TRACE_STRING_NEWTHREAD | DBG_FUNC_NONE,
316670eb 1239 dbg_arg1, dbg_arg2, dbg_arg3, dbg_arg4, 0);
1c79356b
A
1240 }
1241
2d21ac55
A
1242 DTRACE_PROC1(lwp__create, thread_t, *out_thread);
1243
1c79356b
A
1244 return (KERN_SUCCESS);
1245}
1246
6d2010ae
A
1247static kern_return_t
1248thread_create_internal2(
1c79356b 1249 task_t task,
6d2010ae 1250 thread_t *new_thread,
3e170ce0
A
1251 boolean_t from_user,
1252 thread_continue_t continuation)
1c79356b 1253{
1c79356b 1254 kern_return_t result;
9bccf70c 1255 thread_t thread;
1c79356b 1256
55e303ae
A
1257 if (task == TASK_NULL || task == kernel_task)
1258 return (KERN_INVALID_ARGUMENT);
1c79356b 1259
3e170ce0 1260 result = thread_create_internal(task, -1, continuation, TH_OPTION_NONE, &thread);
1c79356b
A
1261 if (result != KERN_SUCCESS)
1262 return (result);
1263
55e303ae
A
1264 thread->user_stop_count = 1;
1265 thread_hold(thread);
9bccf70c 1266 if (task->suspend_count > 0)
55e303ae 1267 thread_hold(thread);
1c79356b 1268
6d2010ae
A
1269 if (from_user)
1270 extmod_statistics_incr_thread_create(task);
1271
9bccf70c 1272 task_unlock(task);
b0d623f7 1273 lck_mtx_unlock(&tasks_threads_lock);
1c79356b 1274
55e303ae 1275 *new_thread = thread;
1c79356b
A
1276
1277 return (KERN_SUCCESS);
1278}
1279
6d2010ae 1280/* No prototype, since task_server.h has the _from_user version if KERNEL_SERVER */
1c79356b 1281kern_return_t
6d2010ae
A
1282thread_create(
1283 task_t task,
1284 thread_t *new_thread);
1285
1286kern_return_t
1287thread_create(
1288 task_t task,
1289 thread_t *new_thread)
1290{
3e170ce0 1291 return thread_create_internal2(task, new_thread, FALSE, (thread_continue_t)thread_bootstrap_return);
6d2010ae
A
1292}
1293
1294kern_return_t
1295thread_create_from_user(
1296 task_t task,
1297 thread_t *new_thread)
1298{
3e170ce0
A
1299 return thread_create_internal2(task, new_thread, TRUE, (thread_continue_t)thread_bootstrap_return);
1300}
1301
1302kern_return_t
1303thread_create_with_continuation(
1304 task_t task,
1305 thread_t *new_thread,
1306 thread_continue_t continuation)
1307{
1308 return thread_create_internal2(task, new_thread, FALSE, continuation);
6d2010ae
A
1309}
1310
1311static kern_return_t
1312thread_create_running_internal2(
39037602 1313 task_t task,
1c79356b
A
1314 int flavor,
1315 thread_state_t new_state,
1316 mach_msg_type_number_t new_state_count,
6d2010ae
A
1317 thread_t *new_thread,
1318 boolean_t from_user)
1c79356b 1319{
39037602 1320 kern_return_t result;
9bccf70c 1321 thread_t thread;
9bccf70c 1322
55e303ae
A
1323 if (task == TASK_NULL || task == kernel_task)
1324 return (KERN_INVALID_ARGUMENT);
1c79356b 1325
b0d623f7 1326 result = thread_create_internal(task, -1, (thread_continue_t)thread_bootstrap_return, TH_OPTION_NONE, &thread);
1c79356b
A
1327 if (result != KERN_SUCCESS)
1328 return (result);
1329
39037602
A
1330 if (task->suspend_count > 0)
1331 thread_hold(thread);
1332
3e170ce0 1333 result = machine_thread_set_state(thread, flavor, new_state, new_state_count);
1c79356b 1334 if (result != KERN_SUCCESS) {
9bccf70c 1335 task_unlock(task);
b0d623f7 1336 lck_mtx_unlock(&tasks_threads_lock);
9bccf70c 1337
55e303ae 1338 thread_terminate(thread);
91447636 1339 thread_deallocate(thread);
1c79356b
A
1340 return (result);
1341 }
1342
91447636 1343 thread_mtx_lock(thread);
39037602 1344 thread_start(thread);
91447636 1345 thread_mtx_unlock(thread);
2d21ac55 1346
6d2010ae
A
1347 if (from_user)
1348 extmod_statistics_incr_thread_create(task);
1349
9bccf70c 1350 task_unlock(task);
b0d623f7 1351 lck_mtx_unlock(&tasks_threads_lock);
9bccf70c 1352
55e303ae 1353 *new_thread = thread;
9bccf70c 1354
1c79356b
A
1355 return (result);
1356}
1357
6d2010ae
A
1358/* Prototype, see justification above */
1359kern_return_t
1360thread_create_running(
39037602 1361 task_t task,
6d2010ae
A
1362 int flavor,
1363 thread_state_t new_state,
1364 mach_msg_type_number_t new_state_count,
1365 thread_t *new_thread);
1366
1367kern_return_t
1368thread_create_running(
39037602 1369 task_t task,
6d2010ae
A
1370 int flavor,
1371 thread_state_t new_state,
1372 mach_msg_type_number_t new_state_count,
1373 thread_t *new_thread)
1374{
1375 return thread_create_running_internal2(
1376 task, flavor, new_state, new_state_count,
1377 new_thread, FALSE);
1378}
1379
1380kern_return_t
1381thread_create_running_from_user(
39037602 1382 task_t task,
6d2010ae
A
1383 int flavor,
1384 thread_state_t new_state,
1385 mach_msg_type_number_t new_state_count,
1386 thread_t *new_thread)
1387{
1388 return thread_create_running_internal2(
1389 task, flavor, new_state, new_state_count,
1390 new_thread, TRUE);
1391}
1392
b0d623f7
A
1393kern_return_t
1394thread_create_workq(
1395 task_t task,
b7266188 1396 thread_continue_t thread_return,
b0d623f7
A
1397 thread_t *new_thread)
1398{
1399 kern_return_t result;
1400 thread_t thread;
1401
1402 if (task == TASK_NULL || task == kernel_task)
1403 return (KERN_INVALID_ARGUMENT);
1404
b7266188 1405 result = thread_create_internal(task, -1, thread_return, TH_OPTION_NOCRED | TH_OPTION_NOSUSP, &thread);
b0d623f7
A
1406 if (result != KERN_SUCCESS)
1407 return (result);
1408
1409 thread->user_stop_count = 1;
1410 thread_hold(thread);
1411 if (task->suspend_count > 0)
1412 thread_hold(thread);
1413
1414 task_unlock(task);
1415 lck_mtx_unlock(&tasks_threads_lock);
1416
1417 *new_thread = thread;
1418
1419 return (KERN_SUCCESS);
1420}
1421
39037602
A
1422kern_return_t
1423thread_create_workq_waiting(
1424 task_t task,
1425 thread_continue_t thread_return,
1426 event_t event,
1427 thread_t *new_thread)
1428{
1429 thread_t thread;
1430 kern_return_t result;
1431
1432 if (task == TASK_NULL || task == kernel_task)
1433 return KERN_INVALID_ARGUMENT;
1434
1435 result = thread_create_internal(task, -1, thread_return, TH_OPTION_NOCRED | TH_OPTION_NOSUSP, &thread);
1436
1437 if (result != KERN_SUCCESS)
1438 return result;
1439
1440 if (task->suspend_count > 0)
1441 thread_hold(thread);
1442
1443 thread_mtx_lock(thread);
1444 thread_start_in_assert_wait(thread, event, THREAD_INTERRUPTIBLE);
1445 thread_mtx_unlock(thread);
1446
1447 task_unlock(task);
1448 lck_mtx_unlock(&tasks_threads_lock);
1449
1450 *new_thread = thread;
1451
1452 return result;
1453}
1454
1c79356b 1455/*
91447636 1456 * kernel_thread_create:
1c79356b 1457 *
55e303ae
A
1458 * Create a thread in the kernel task
1459 * to execute in kernel context.
1c79356b 1460 */
91447636 1461kern_return_t
55e303ae 1462kernel_thread_create(
91447636
A
1463 thread_continue_t continuation,
1464 void *parameter,
1465 integer_t priority,
1466 thread_t *new_thread)
1c79356b
A
1467{
1468 kern_return_t result;
1469 thread_t thread;
91447636 1470 task_t task = kernel_task;
1c79356b 1471
b0d623f7 1472 result = thread_create_internal(task, priority, continuation, TH_OPTION_NONE, &thread);
9bccf70c 1473 if (result != KERN_SUCCESS)
91447636 1474 return (result);
1c79356b 1475
9bccf70c 1476 task_unlock(task);
b0d623f7 1477 lck_mtx_unlock(&tasks_threads_lock);
9bccf70c 1478
91447636 1479 stack_alloc(thread);
55e303ae
A
1480 assert(thread->kernel_stack != 0);
1481 thread->reserved_stack = thread->kernel_stack;
1482
91447636 1483 thread->parameter = parameter;
55e303ae 1484
2d21ac55
A
1485if(debug_task & 1)
1486 kprintf("kernel_thread_create: thread = %p continuation = %p\n", thread, continuation);
91447636
A
1487 *new_thread = thread;
1488
1489 return (result);
55e303ae
A
1490}
1491
91447636
A
1492kern_return_t
1493kernel_thread_start_priority(
1494 thread_continue_t continuation,
1495 void *parameter,
1496 integer_t priority,
1497 thread_t *new_thread)
55e303ae 1498{
91447636 1499 kern_return_t result;
55e303ae 1500 thread_t thread;
1c79356b 1501
91447636
A
1502 result = kernel_thread_create(continuation, parameter, priority, &thread);
1503 if (result != KERN_SUCCESS)
1504 return (result);
1c79356b 1505
b0d623f7
A
1506 *new_thread = thread;
1507
91447636 1508 thread_mtx_lock(thread);
39037602 1509 thread_start(thread);
91447636 1510 thread_mtx_unlock(thread);
1c79356b 1511
91447636
A
1512 return (result);
1513}
1514
1515kern_return_t
1516kernel_thread_start(
1517 thread_continue_t continuation,
1518 void *parameter,
1519 thread_t *new_thread)
1520{
1521 return kernel_thread_start_priority(continuation, parameter, -1, new_thread);
1c79356b
A
1522}
1523
3e170ce0
A
1524/* Separated into helper function so it can be used by THREAD_BASIC_INFO and THREAD_EXTENDED_INFO */
1525/* it is assumed that the thread is locked by the caller */
1526static void
1527retrieve_thread_basic_info(thread_t thread, thread_basic_info_t basic_info)
1528{
1529 int state, flags;
1530
1531 /* fill in info */
1532
1533 thread_read_times(thread, &basic_info->user_time,
1534 &basic_info->system_time);
1535
1536 /*
1537 * Update lazy-evaluated scheduler info because someone wants it.
1538 */
1539 if (SCHED(can_update_priority)(thread))
1540 SCHED(update_priority)(thread);
1541
1542 basic_info->sleep_time = 0;
1543
1544 /*
1545 * To calculate cpu_usage, first correct for timer rate,
1546 * then for 5/8 ageing. The correction factor [3/5] is
1547 * (1/(5/8) - 1).
1548 */
1549 basic_info->cpu_usage = 0;
1550#if defined(CONFIG_SCHED_TIMESHARE_CORE)
1551 if (sched_tick_interval) {
1552 basic_info->cpu_usage = (integer_t)(((uint64_t)thread->cpu_usage
1553 * TH_USAGE_SCALE) / sched_tick_interval);
1554 basic_info->cpu_usage = (basic_info->cpu_usage * 3) / 5;
1555 }
1556#endif
1557
1558 if (basic_info->cpu_usage > TH_USAGE_SCALE)
1559 basic_info->cpu_usage = TH_USAGE_SCALE;
1560
1561 basic_info->policy = ((thread->sched_mode == TH_MODE_TIMESHARE)?
1562 POLICY_TIMESHARE: POLICY_RR);
1563
1564 flags = 0;
1565 if (thread->options & TH_OPT_IDLE_THREAD)
1566 flags |= TH_FLAGS_IDLE;
1567
1568 if (thread->options & TH_OPT_GLOBAL_FORCED_IDLE) {
1569 flags |= TH_FLAGS_GLOBAL_FORCED_IDLE;
1570 }
1571
1572 if (!thread->kernel_stack)
1573 flags |= TH_FLAGS_SWAPPED;
1574
1575 state = 0;
1576 if (thread->state & TH_TERMINATE)
1577 state = TH_STATE_HALTED;
1578 else
1579 if (thread->state & TH_RUN)
1580 state = TH_STATE_RUNNING;
1581 else
1582 if (thread->state & TH_UNINT)
1583 state = TH_STATE_UNINTERRUPTIBLE;
1584 else
1585 if (thread->state & TH_SUSP)
1586 state = TH_STATE_STOPPED;
1587 else
1588 if (thread->state & TH_WAIT)
1589 state = TH_STATE_WAITING;
1590
1591 basic_info->run_state = state;
1592 basic_info->flags = flags;
1593
1594 basic_info->suspend_count = thread->user_stop_count;
1595
1596 return;
1597}
b0d623f7 1598
1c79356b 1599kern_return_t
91447636 1600thread_info_internal(
39037602 1601 thread_t thread,
1c79356b
A
1602 thread_flavor_t flavor,
1603 thread_info_t thread_info_out, /* ptr to OUT array */
1604 mach_msg_type_number_t *thread_info_count) /*IN/OUT*/
1605{
3e170ce0 1606 spl_t s;
1c79356b
A
1607
1608 if (thread == THREAD_NULL)
1609 return (KERN_INVALID_ARGUMENT);
1610
1611 if (flavor == THREAD_BASIC_INFO) {
1c79356b 1612
3e170ce0 1613 if (*thread_info_count < THREAD_BASIC_INFO_COUNT)
1c79356b
A
1614 return (KERN_INVALID_ARGUMENT);
1615
3e170ce0
A
1616 s = splsched();
1617 thread_lock(thread);
1c79356b 1618
3e170ce0 1619 retrieve_thread_basic_info(thread, (thread_basic_info_t) thread_info_out);
1c79356b 1620
3e170ce0
A
1621 thread_unlock(thread);
1622 splx(s);
0b4e3aa0 1623
3e170ce0 1624 *thread_info_count = THREAD_BASIC_INFO_COUNT;
0b4e3aa0 1625
3e170ce0 1626 return (KERN_SUCCESS);
1c79356b
A
1627 }
1628 else
b0d623f7 1629 if (flavor == THREAD_IDENTIFIER_INFO) {
39037602 1630 thread_identifier_info_t identifier_info;
b0d623f7 1631
3e170ce0 1632 if (*thread_info_count < THREAD_IDENTIFIER_INFO_COUNT)
b0d623f7
A
1633 return (KERN_INVALID_ARGUMENT);
1634
3e170ce0 1635 identifier_info = (thread_identifier_info_t) thread_info_out;
b0d623f7 1636
3e170ce0
A
1637 s = splsched();
1638 thread_lock(thread);
b0d623f7 1639
3e170ce0
A
1640 identifier_info->thread_id = thread->thread_id;
1641 identifier_info->thread_handle = thread->machine.cthread_self;
1642 identifier_info->dispatch_qaddr = thread_dispatchqaddr(thread);
b0d623f7 1643
3e170ce0
A
1644 thread_unlock(thread);
1645 splx(s);
1646 return KERN_SUCCESS;
b0d623f7
A
1647 }
1648 else
1c79356b
A
1649 if (flavor == THREAD_SCHED_TIMESHARE_INFO) {
1650 policy_timeshare_info_t ts_info;
1651
1652 if (*thread_info_count < POLICY_TIMESHARE_INFO_COUNT)
1653 return (KERN_INVALID_ARGUMENT);
1654
1655 ts_info = (policy_timeshare_info_t)thread_info_out;
1656
3e170ce0 1657 s = splsched();
1c79356b
A
1658 thread_lock(thread);
1659
3e170ce0
A
1660 if (thread->sched_mode != TH_MODE_TIMESHARE) {
1661 thread_unlock(thread);
1c79356b 1662 splx(s);
1c79356b 1663 return (KERN_INVALID_POLICY);
3e170ce0 1664 }
1c79356b 1665
6d2010ae 1666 ts_info->depressed = (thread->sched_flags & TH_SFLAG_DEPRESSED_MASK) != 0;
9bccf70c
A
1667 if (ts_info->depressed) {
1668 ts_info->base_priority = DEPRESSPRI;
3e170ce0 1669 ts_info->depress_priority = thread->base_pri;
9bccf70c
A
1670 }
1671 else {
3e170ce0 1672 ts_info->base_priority = thread->base_pri;
9bccf70c
A
1673 ts_info->depress_priority = -1;
1674 }
1c79356b 1675
9bccf70c
A
1676 ts_info->cur_priority = thread->sched_pri;
1677 ts_info->max_priority = thread->max_priority;
1c79356b
A
1678
1679 thread_unlock(thread);
3e170ce0 1680 splx(s);
1c79356b
A
1681
1682 *thread_info_count = POLICY_TIMESHARE_INFO_COUNT;
1683
3e170ce0 1684 return (KERN_SUCCESS);
1c79356b
A
1685 }
1686 else
1687 if (flavor == THREAD_SCHED_FIFO_INFO) {
1c79356b
A
1688 if (*thread_info_count < POLICY_FIFO_INFO_COUNT)
1689 return (KERN_INVALID_ARGUMENT);
1690
0b4e3aa0 1691 return (KERN_INVALID_POLICY);
1c79356b
A
1692 }
1693 else
1694 if (flavor == THREAD_SCHED_RR_INFO) {
1695 policy_rr_info_t rr_info;
6d2010ae
A
1696 uint32_t quantum_time;
1697 uint64_t quantum_ns;
3e170ce0 1698
1c79356b
A
1699 if (*thread_info_count < POLICY_RR_INFO_COUNT)
1700 return (KERN_INVALID_ARGUMENT);
1701
1702 rr_info = (policy_rr_info_t) thread_info_out;
1703
3e170ce0 1704 s = splsched();
1c79356b
A
1705 thread_lock(thread);
1706
3e170ce0
A
1707 if (thread->sched_mode == TH_MODE_TIMESHARE) {
1708 thread_unlock(thread);
1c79356b
A
1709 splx(s);
1710
1711 return (KERN_INVALID_POLICY);
1712 }
1713
6d2010ae 1714 rr_info->depressed = (thread->sched_flags & TH_SFLAG_DEPRESSED_MASK) != 0;
9bccf70c
A
1715 if (rr_info->depressed) {
1716 rr_info->base_priority = DEPRESSPRI;
3e170ce0 1717 rr_info->depress_priority = thread->base_pri;
9bccf70c
A
1718 }
1719 else {
3e170ce0 1720 rr_info->base_priority = thread->base_pri;
9bccf70c
A
1721 rr_info->depress_priority = -1;
1722 }
1723
6d2010ae
A
1724 quantum_time = SCHED(initial_quantum_size)(THREAD_NULL);
1725 absolutetime_to_nanoseconds(quantum_time, &quantum_ns);
3e170ce0 1726
1c79356b 1727 rr_info->max_priority = thread->max_priority;
3e170ce0 1728 rr_info->quantum = (uint32_t)(quantum_ns / 1000 / 1000);
1c79356b 1729
1c79356b 1730 thread_unlock(thread);
3e170ce0 1731 splx(s);
1c79356b
A
1732
1733 *thread_info_count = POLICY_RR_INFO_COUNT;
1734
3e170ce0
A
1735 return (KERN_SUCCESS);
1736 }
1737 else
1738 if (flavor == THREAD_EXTENDED_INFO) {
1739 thread_basic_info_data_t basic_info;
1740 thread_extended_info_t extended_info = (thread_extended_info_t) thread_info_out;
1741
1742 if (*thread_info_count < THREAD_EXTENDED_INFO_COUNT) {
1743 return (KERN_INVALID_ARGUMENT);
1744 }
1745
1746 s = splsched();
1747 thread_lock(thread);
1748
1749 /* NOTE: This mimics fill_taskthreadinfo(), which is the function used by proc_pidinfo() for
1750 * the PROC_PIDTHREADINFO flavor (which can't be used on corpses)
1751 */
1752 retrieve_thread_basic_info(thread, &basic_info);
1753 extended_info->pth_user_time = ((basic_info.user_time.seconds * (integer_t)NSEC_PER_SEC) + (basic_info.user_time.microseconds * (integer_t)NSEC_PER_USEC));
1754 extended_info->pth_system_time = ((basic_info.system_time.seconds * (integer_t)NSEC_PER_SEC) + (basic_info.system_time.microseconds * (integer_t)NSEC_PER_USEC));
1755
1756 extended_info->pth_cpu_usage = basic_info.cpu_usage;
1757 extended_info->pth_policy = basic_info.policy;
1758 extended_info->pth_run_state = basic_info.run_state;
1759 extended_info->pth_flags = basic_info.flags;
1760 extended_info->pth_sleep_time = basic_info.sleep_time;
1761 extended_info->pth_curpri = thread->sched_pri;
1762 extended_info->pth_priority = thread->base_pri;
1763 extended_info->pth_maxpriority = thread->max_priority;
1764
1765 bsd_getthreadname(thread->uthread,extended_info->pth_name);
1766
1767 thread_unlock(thread);
1768 splx(s);
1769
1770 *thread_info_count = THREAD_EXTENDED_INFO_COUNT;
1771
1772 return (KERN_SUCCESS);
1773 }
1774 else
1775 if (flavor == THREAD_DEBUG_INFO_INTERNAL) {
1776#if DEVELOPMENT || DEBUG
1777 thread_debug_info_internal_t dbg_info;
1778 if (*thread_info_count < THREAD_DEBUG_INFO_INTERNAL_COUNT)
1779 return (KERN_NOT_SUPPORTED);
1780
1781 if (thread_info_out == NULL)
1782 return (KERN_INVALID_ARGUMENT);
1783
1784 dbg_info = (thread_debug_info_internal_t) thread_info_out;
1785 dbg_info->page_creation_count = thread->t_page_creation_count;
1786
1787 *thread_info_count = THREAD_DEBUG_INFO_INTERNAL_COUNT;
1788 return (KERN_SUCCESS);
1789#endif /* DEVELOPMENT || DEBUG */
1790 return (KERN_NOT_SUPPORTED);
1c79356b
A
1791 }
1792
1793 return (KERN_INVALID_ARGUMENT);
1794}
1795
1796void
91447636
A
1797thread_read_times(
1798 thread_t thread,
1799 time_value_t *user_time,
1800 time_value_t *system_time)
1c79356b 1801{
b0d623f7
A
1802 clock_sec_t secs;
1803 clock_usec_t usecs;
316670eb 1804 uint64_t tval_user, tval_system;
b0d623f7 1805
316670eb
A
1806 tval_user = timer_grab(&thread->user_timer);
1807 tval_system = timer_grab(&thread->system_timer);
9bccf70c 1808
316670eb
A
1809 if (thread->precise_user_kernel_time) {
1810 absolutetime_to_microtime(tval_user, &secs, &usecs);
1811 user_time->seconds = (typeof(user_time->seconds))secs;
1812 user_time->microseconds = usecs;
1813
1814 absolutetime_to_microtime(tval_system, &secs, &usecs);
1815 system_time->seconds = (typeof(system_time->seconds))secs;
1816 system_time->microseconds = usecs;
1817 } else {
1818 /* system_timer may represent either sys or user */
1819 tval_user += tval_system;
1820 absolutetime_to_microtime(tval_user, &secs, &usecs);
1821 user_time->seconds = (typeof(user_time->seconds))secs;
1822 user_time->microseconds = usecs;
1823
1824 system_time->seconds = 0;
1825 system_time->microseconds = 0;
1826 }
1c79356b
A
1827}
1828
fe8ab488
A
1829uint64_t thread_get_runtime_self(void)
1830{
1831 boolean_t interrupt_state;
1832 uint64_t runtime;
1833 thread_t thread = NULL;
1834 processor_t processor = NULL;
1835
1836 thread = current_thread();
1837
1838 /* Not interrupt safe, as the scheduler may otherwise update timer values underneath us */
1839 interrupt_state = ml_set_interrupts_enabled(FALSE);
1840 processor = current_processor();
1841 timer_switch(PROCESSOR_DATA(processor, thread_timer), mach_absolute_time(), PROCESSOR_DATA(processor, thread_timer));
1842 runtime = (timer_grab(&thread->user_timer) + timer_grab(&thread->system_timer));
1843 ml_set_interrupts_enabled(interrupt_state);
1844
1845 return runtime;
1846}
1847
1c79356b
A
1848kern_return_t
1849thread_assign(
91447636
A
1850 __unused thread_t thread,
1851 __unused processor_set_t new_pset)
1c79356b 1852{
91447636 1853 return (KERN_FAILURE);
1c79356b
A
1854}
1855
1856/*
1857 * thread_assign_default:
1858 *
1859 * Special version of thread_assign for assigning threads to default
1860 * processor set.
1861 */
1862kern_return_t
1863thread_assign_default(
91447636 1864 thread_t thread)
1c79356b 1865{
2d21ac55 1866 return (thread_assign(thread, &pset0));
1c79356b
A
1867}
1868
1869/*
1870 * thread_get_assignment
1871 *
1872 * Return current assignment for this thread.
1873 */
1874kern_return_t
1875thread_get_assignment(
91447636 1876 thread_t thread,
1c79356b
A
1877 processor_set_t *pset)
1878{
91447636
A
1879 if (thread == NULL)
1880 return (KERN_INVALID_ARGUMENT);
1881
2d21ac55
A
1882 *pset = &pset0;
1883
91447636 1884 return (KERN_SUCCESS);
1c79356b
A
1885}
1886
1887/*
55e303ae 1888 * thread_wire_internal:
1c79356b
A
1889 *
1890 * Specify that the target thread must always be able
1891 * to run and to allocate memory.
1892 */
1893kern_return_t
55e303ae 1894thread_wire_internal(
91447636
A
1895 host_priv_t host_priv,
1896 thread_t thread,
1897 boolean_t wired,
1898 boolean_t *prev_state)
1c79356b 1899{
91447636 1900 if (host_priv == NULL || thread != current_thread())
1c79356b
A
1901 return (KERN_INVALID_ARGUMENT);
1902
1903 assert(host_priv == &realhost);
1904
91447636
A
1905 if (prev_state)
1906 *prev_state = (thread->options & TH_OPT_VMPRIV) != 0;
55e303ae 1907
1c79356b 1908 if (wired) {
91447636 1909 if (!(thread->options & TH_OPT_VMPRIV))
1c79356b 1910 vm_page_free_reserve(1); /* XXX */
91447636
A
1911 thread->options |= TH_OPT_VMPRIV;
1912 }
1913 else {
1914 if (thread->options & TH_OPT_VMPRIV)
1c79356b 1915 vm_page_free_reserve(-1); /* XXX */
91447636 1916 thread->options &= ~TH_OPT_VMPRIV;
1c79356b
A
1917 }
1918
91447636 1919 return (KERN_SUCCESS);
1c79356b
A
1920}
1921
1c79356b
A
1922
1923/*
55e303ae 1924 * thread_wire:
1c79356b 1925 *
55e303ae 1926 * User-api wrapper for thread_wire_internal()
1c79356b 1927 */
55e303ae
A
1928kern_return_t
1929thread_wire(
1930 host_priv_t host_priv,
91447636 1931 thread_t thread,
55e303ae 1932 boolean_t wired)
1c79356b 1933{
91447636 1934 return (thread_wire_internal(host_priv, thread, wired, NULL));
1c79356b
A
1935}
1936
39236c6e 1937
39037602
A
1938boolean_t
1939is_vm_privileged(void)
1940{
1941 return current_thread()->options & TH_OPT_VMPRIV ? TRUE : FALSE;
1942}
1943
fe8ab488
A
1944boolean_t
1945set_vm_privilege(boolean_t privileged)
1946{
1947 boolean_t was_vmpriv;
1948
1949 if (current_thread()->options & TH_OPT_VMPRIV)
1950 was_vmpriv = TRUE;
1951 else
1952 was_vmpriv = FALSE;
1953
1954 if (privileged != FALSE)
1955 current_thread()->options |= TH_OPT_VMPRIV;
1956 else
1957 current_thread()->options &= ~TH_OPT_VMPRIV;
1958
1959 return (was_vmpriv);
1960}
1961
ecc0ceb4
A
1962void
1963set_thread_rwlock_boost(void)
1964{
1965 current_thread()->rwlock_count++;
1966}
1967
1968void
1969clear_thread_rwlock_boost(void)
1970{
1971 thread_t thread = current_thread();
1972
1973 if ((thread->rwlock_count-- == 1) && (thread->sched_flags & TH_SFLAG_RW_PROMOTED)) {
1974
1975 lck_rw_clear_promotion(thread);
1976 }
1977}
fe8ab488 1978
39236c6e
A
1979/*
1980 * XXX assuming current thread only, for now...
1981 */
1982void
1983thread_guard_violation(thread_t thread, unsigned type)
1984{
1985 assert(thread == current_thread());
1986
1987 spl_t s = splsched();
1988 /*
1989 * Use the saved state area of the thread structure
1990 * to store all info required to handle the AST when
1991 * returning to userspace
1992 */
1993 thread->guard_exc_info.type = type;
1994 thread_ast_set(thread, AST_GUARD);
1995 ast_propagate(thread->ast);
1996
1997 splx(s);
1998}
1999
2000/*
2001 * guard_ast:
2002 *
2003 * Handle AST_GUARD for a thread. This routine looks at the
2004 * state saved in the thread structure to determine the cause
2005 * of this exception. Based on this value, it invokes the
2006 * appropriate routine which determines other exception related
2007 * info and raises the exception.
2008 */
2009void
2010guard_ast(thread_t thread)
2011{
2012 if (thread->guard_exc_info.type == GUARD_TYPE_MACH_PORT)
2013 mach_port_guard_ast(thread);
2014 else
2015 fd_guard_ast(thread);
2016}
2017
316670eb 2018static void
39236c6e 2019thread_cputime_callback(int warning, __unused const void *arg0, __unused const void *arg1)
316670eb 2020{
39236c6e
A
2021 if (warning == LEDGER_WARNING_ROSE_ABOVE) {
2022#if CONFIG_TELEMETRY
2023 /*
2024 * This thread is in danger of violating the CPU usage monitor. Enable telemetry
2025 * on the entire task so there are micro-stackshots available if and when
2026 * EXC_RESOURCE is triggered. We could have chosen to enable micro-stackshots
2027 * for this thread only; but now that this task is suspect, knowing what all of
2028 * its threads are up to will be useful.
2029 */
2030 telemetry_task_ctl(current_task(), TF_CPUMON_WARNING, 1);
2031#endif
2032 return;
2033 }
2034
2035#if CONFIG_TELEMETRY
2036 /*
2037 * If the balance has dipped below the warning level (LEDGER_WARNING_DIPPED_BELOW) or
2038 * exceeded the limit, turn telemetry off for the task.
2039 */
2040 telemetry_task_ctl(current_task(), TF_CPUMON_WARNING, 0);
2041#endif
2042
2043 if (warning == 0) {
39037602 2044 SENDING_NOTIFICATION__THIS_THREAD_IS_CONSUMING_TOO_MUCH_CPU();
39236c6e
A
2045 }
2046}
2047
2048void __attribute__((noinline))
39037602 2049SENDING_NOTIFICATION__THIS_THREAD_IS_CONSUMING_TOO_MUCH_CPU(void)
39236c6e
A
2050{
2051 int pid = 0;
2052 task_t task = current_task();
2053 thread_t thread = current_thread();
2054 uint64_t tid = thread->thread_id;
3e170ce0 2055 const char *procname = "unknown";
39236c6e
A
2056 time_value_t thread_total_time = {0, 0};
2057 time_value_t thread_system_time;
2058 time_value_t thread_user_time;
2059 int action;
2060 uint8_t percentage;
39037602 2061 uint32_t usage_percent = 0;
39236c6e
A
2062 uint32_t interval_sec;
2063 uint64_t interval_ns;
2064 uint64_t balance_ns;
2065 boolean_t fatal = FALSE;
39037602
A
2066 boolean_t send_exc_resource = TRUE; /* in addition to RESOURCE_NOTIFY */
2067 kern_return_t kr;
39236c6e 2068
39037602 2069#ifdef EXC_RESOURCE_MONITORS
39236c6e 2070 mach_exception_data_type_t code[EXCEPTION_CODE_MAX];
39037602 2071#endif /* EXC_RESOURCE_MONITORS */
39236c6e
A
2072 struct ledger_entry_info lei;
2073
316670eb
A
2074 assert(thread->t_threadledger != LEDGER_NULL);
2075
2076 /*
39037602 2077 * Extract the fatal bit and suspend the monitor (which clears the bit).
316670eb 2078 */
39236c6e 2079 task_lock(task);
39236c6e
A
2080 if (task->rusage_cpu_flags & TASK_RUSECPU_FLAGS_FATAL_CPUMON) {
2081 fatal = TRUE;
39037602 2082 send_exc_resource = TRUE;
39236c6e 2083 }
39037602
A
2084 /* Only one thread can be here at a time. Whichever makes it through
2085 first will successfully suspend the monitor and proceed to send the
2086 notification. Other threads will get an error trying to suspend the
2087 monitor and give up on sending the notification. In the first release,
2088 the monitor won't be resumed for a number of seconds, but we may
2089 eventually need to handle low-latency resume.
2090 */
2091 kr = task_suspend_cpumon(task);
39236c6e 2092 task_unlock(task);
39037602 2093 if (kr == KERN_INVALID_ARGUMENT) return;
39236c6e
A
2094
2095#ifdef MACH_BSD
2096 pid = proc_selfpid();
39037602 2097 if (task->bsd_info != NULL) {
39236c6e 2098 procname = proc_name_address(task->bsd_info);
39037602 2099 }
39236c6e
A
2100#endif
2101
2102 thread_get_cpulimit(&action, &percentage, &interval_ns);
2103
2104 interval_sec = (uint32_t)(interval_ns / NSEC_PER_SEC);
2105
2106 thread_read_times(thread, &thread_user_time, &thread_system_time);
2107 time_value_add(&thread_total_time, &thread_user_time);
2108 time_value_add(&thread_total_time, &thread_system_time);
39236c6e 2109 ledger_get_entry_info(thread->t_threadledger, thread_ledgers.cpu_time, &lei);
316670eb 2110
39037602
A
2111 /* credit/debit/balance/limit are in absolute time units;
2112 the refill info is in nanoseconds. */
39236c6e 2113 absolutetime_to_nanoseconds(lei.lei_balance, &balance_ns);
39037602
A
2114 if (lei.lei_last_refill > 0) {
2115 usage_percent = (uint32_t)((balance_ns*100ULL) / lei.lei_last_refill);
2116 }
39236c6e 2117
39037602
A
2118 /* TODO: show task total runtime (via TASK_ABSOLUTETIME_INFO)? */
2119 printf("process %s[%d] thread %llu caught burning CPU! "
2120 "It used more than %d%% CPU over %u seconds "
2121 "(actual recent usage: %d%% over ~%llu seconds). "
2122 "Thread lifetime cpu usage %d.%06ds, (%d.%06d user, %d.%06d sys) "
2123 "ledger balance: %lld mabs credit: %lld mabs debit: %lld mabs "
2124 "limit: %llu mabs period: %llu ns last refill: %llu ns%s.\n",
2125 procname, pid, tid,
2126 percentage, interval_sec,
2127 usage_percent,
2128 (lei.lei_last_refill + NSEC_PER_SEC/2) / NSEC_PER_SEC,
2129 thread_total_time.seconds, thread_total_time.microseconds,
2130 thread_user_time.seconds, thread_user_time.microseconds,
2131 thread_system_time.seconds,thread_system_time.microseconds,
2132 lei.lei_balance, lei.lei_credit, lei.lei_debit,
2133 lei.lei_limit, lei.lei_refill_period, lei.lei_last_refill,
2134 (fatal ? " [fatal violation]" : ""));
39236c6e 2135
39037602
A
2136 /*
2137 For now, send RESOURCE_NOTIFY in parallel with EXC_RESOURCE. Once
2138 we have logging parity, we will stop sending EXC_RESOURCE (24508922).
2139 */
39236c6e 2140
39037602
A
2141 /* RESOURCE_NOTIFY MIG specifies nanoseconds of CPU time */
2142 lei.lei_balance = balance_ns;
2143 absolutetime_to_nanoseconds(lei.lei_limit, &lei.lei_limit);
2144 trace_resource_violation(RMON_CPUUSAGE_VIOLATED, &lei);
2145 kr = send_resource_violation(send_cpu_usage_violation, task, &lei,
2146 fatal ? kRNFatalLimitFlag : 0);
2147 if (kr) {
2148 printf("send_resource_violation(CPU usage, ...): error %#x\n", kr);
39236c6e
A
2149 }
2150
39037602
A
2151#ifdef EXC_RESOURCE_MONITORS
2152 if (send_exc_resource) {
2153 if (disable_exc_resource) {
2154 printf("process %s[%d] thread %llu caught burning CPU! "
2155 "EXC_RESOURCE%s supressed by a boot-arg\n",
2156 procname, pid, tid, fatal ? " (and termination)" : "");
2157 return;
2158 }
2159
2160 if (audio_active) {
2161 printf("process %s[%d] thread %llu caught burning CPU! "
2162 "EXC_RESOURCE & termination supressed due to audio playback\n",
2163 procname, pid, tid);
2164 return;
2165 }
15129b1c 2166 }
39037602
A
2167
2168
2169 if (send_exc_resource) {
2170 code[0] = code[1] = 0;
2171 EXC_RESOURCE_ENCODE_TYPE(code[0], RESOURCE_TYPE_CPU);
2172 if (fatal) {
2173 EXC_RESOURCE_ENCODE_FLAVOR(code[0], FLAVOR_CPU_MONITOR_FATAL);
2174 }else {
2175 EXC_RESOURCE_ENCODE_FLAVOR(code[0], FLAVOR_CPU_MONITOR);
2176 }
2177 EXC_RESOURCE_CPUMONITOR_ENCODE_INTERVAL(code[0], interval_sec);
2178 EXC_RESOURCE_CPUMONITOR_ENCODE_PERCENTAGE(code[0], percentage);
2179 EXC_RESOURCE_CPUMONITOR_ENCODE_PERCENTAGE(code[1], usage_percent);
2180 exception_triage(EXC_RESOURCE, code, EXCEPTION_CODE_MAX);
fe8ab488 2181 }
39037602 2182#endif /* EXC_RESOURCE_MONITORS */
39236c6e
A
2183
2184 if (fatal) {
fe8ab488
A
2185#if CONFIG_JETSAM
2186 jetsam_on_ledger_cpulimit_exceeded();
2187#else
39236c6e 2188 task_terminate_internal(task);
fe8ab488
A
2189#endif
2190 }
2191}
2192
fe8ab488
A
2193void thread_update_io_stats(thread_t thread, int size, int io_flags)
2194{
2195 int io_tier;
2196
2197 if (thread->thread_io_stats == NULL || thread->task->task_io_stats == NULL)
2198 return;
2199
2200 if (io_flags & DKIO_READ) {
2201 UPDATE_IO_STATS(thread->thread_io_stats->disk_reads, size);
2202 UPDATE_IO_STATS_ATOMIC(thread->task->task_io_stats->disk_reads, size);
2203 }
2204
2205 if (io_flags & DKIO_META) {
2206 UPDATE_IO_STATS(thread->thread_io_stats->metadata, size);
2207 UPDATE_IO_STATS_ATOMIC(thread->task->task_io_stats->metadata, size);
39236c6e 2208 }
fe8ab488
A
2209
2210 if (io_flags & DKIO_PAGING) {
2211 UPDATE_IO_STATS(thread->thread_io_stats->paging, size);
2212 UPDATE_IO_STATS_ATOMIC(thread->task->task_io_stats->paging, size);
2213 }
2214
2215 io_tier = ((io_flags & DKIO_TIER_MASK) >> DKIO_TIER_SHIFT);
2216 assert (io_tier < IO_NUM_PRIORITIES);
2217
2218 UPDATE_IO_STATS(thread->thread_io_stats->io_priority[io_tier], size);
2219 UPDATE_IO_STATS_ATOMIC(thread->task->task_io_stats->io_priority[io_tier], size);
2220
2221 /* Update Total I/O Counts */
2222 UPDATE_IO_STATS(thread->thread_io_stats->total_io, size);
2223 UPDATE_IO_STATS_ATOMIC(thread->task->task_io_stats->total_io, size);
2224
39037602
A
2225 if (!(io_flags & DKIO_READ)) {
2226 DTRACE_IO3(physical_writes, struct task *, thread->task, uint32_t, size, int, io_flags);
2227 ledger_credit(thread->task->ledger, task_ledgers.physical_writes, size);
2228 }
316670eb
A
2229}
2230
39037602 2231static void
316670eb
A
2232init_thread_ledgers(void) {
2233 ledger_template_t t;
2234 int idx;
2235
2236 assert(thread_ledger_template == NULL);
2237
2238 if ((t = ledger_template_create("Per-thread ledger")) == NULL)
2239 panic("couldn't create thread ledger template");
2240
2241 if ((idx = ledger_entry_add(t, "cpu_time", "sched", "ns")) < 0) {
2242 panic("couldn't create cpu_time entry for thread ledger template");
2243 }
2244
39236c6e 2245 if (ledger_set_callback(t, idx, thread_cputime_callback, NULL, NULL) < 0) {
316670eb
A
2246 panic("couldn't set thread ledger callback for cpu_time entry");
2247 }
2248
2249 thread_ledgers.cpu_time = idx;
fe8ab488 2250
316670eb
A
2251 thread_ledger_template = t;
2252}
2253
39236c6e
A
2254/*
2255 * Returns currently applied CPU usage limit, or 0/0 if none is applied.
2256 */
2257int
2258thread_get_cpulimit(int *action, uint8_t *percentage, uint64_t *interval_ns)
2259{
2260 int64_t abstime = 0;
2261 uint64_t limittime = 0;
2262 thread_t thread = current_thread();
2263
2264 *percentage = 0;
2265 *interval_ns = 0;
2266 *action = 0;
2267
2268 if (thread->t_threadledger == LEDGER_NULL) {
2269 /*
2270 * This thread has no per-thread ledger, so it can't possibly
2271 * have a CPU limit applied.
2272 */
2273 return (KERN_SUCCESS);
2274 }
2275
2276 ledger_get_period(thread->t_threadledger, thread_ledgers.cpu_time, interval_ns);
2277 ledger_get_limit(thread->t_threadledger, thread_ledgers.cpu_time, &abstime);
2278
2279 if ((abstime == LEDGER_LIMIT_INFINITY) || (*interval_ns == 0)) {
2280 /*
2281 * This thread's CPU time ledger has no period or limit; so it
2282 * doesn't have a CPU limit applied.
2283 */
2284 return (KERN_SUCCESS);
2285 }
2286
2287 /*
2288 * This calculation is the converse to the one in thread_set_cpulimit().
2289 */
2290 absolutetime_to_nanoseconds(abstime, &limittime);
2291 *percentage = (limittime * 100ULL) / *interval_ns;
2292 assert(*percentage <= 100);
2293
2294 if (thread->options & TH_OPT_PROC_CPULIMIT) {
2295 assert((thread->options & TH_OPT_PRVT_CPULIMIT) == 0);
2296
2297 *action = THREAD_CPULIMIT_BLOCK;
2298 } else if (thread->options & TH_OPT_PRVT_CPULIMIT) {
2299 assert((thread->options & TH_OPT_PROC_CPULIMIT) == 0);
2300
2301 *action = THREAD_CPULIMIT_EXCEPTION;
2302 } else {
2303 *action = THREAD_CPULIMIT_DISABLE;
2304 }
2305
2306 return (KERN_SUCCESS);
2307}
2308
316670eb
A
2309/*
2310 * Set CPU usage limit on a thread.
2311 *
2312 * Calling with percentage of 0 will unset the limit for this thread.
2313 */
316670eb
A
2314int
2315thread_set_cpulimit(int action, uint8_t percentage, uint64_t interval_ns)
2316{
2317 thread_t thread = current_thread();
2318 ledger_t l;
2319 uint64_t limittime = 0;
2320 uint64_t abstime = 0;
2321
2322 assert(percentage <= 100);
2323
39236c6e 2324 if (action == THREAD_CPULIMIT_DISABLE) {
316670eb
A
2325 /*
2326 * Remove CPU limit, if any exists.
2327 */
2328 if (thread->t_threadledger != LEDGER_NULL) {
39236c6e 2329 l = thread->t_threadledger;
fe8ab488
A
2330 ledger_set_limit(l, thread_ledgers.cpu_time, LEDGER_LIMIT_INFINITY, 0);
2331 ledger_set_action(l, thread_ledgers.cpu_time, LEDGER_ACTION_IGNORE);
316670eb
A
2332 thread->options &= ~(TH_OPT_PROC_CPULIMIT | TH_OPT_PRVT_CPULIMIT);
2333 }
2334
2335 return (0);
2336 }
2337
39236c6e
A
2338 if (interval_ns < MINIMUM_CPULIMIT_INTERVAL_MS * NSEC_PER_MSEC) {
2339 return (KERN_INVALID_ARGUMENT);
2340 }
2341
316670eb
A
2342 l = thread->t_threadledger;
2343 if (l == LEDGER_NULL) {
2344 /*
2345 * This thread doesn't yet have a per-thread ledger; so create one with the CPU time entry active.
2346 */
2347 if ((l = ledger_instantiate(thread_ledger_template, LEDGER_CREATE_INACTIVE_ENTRIES)) == LEDGER_NULL)
2348 return (KERN_RESOURCE_SHORTAGE);
2349
2350 /*
2351 * We are the first to create this thread's ledger, so only activate our entry.
2352 */
2353 ledger_entry_setactive(l, thread_ledgers.cpu_time);
2354 thread->t_threadledger = l;
2355 }
2356
2357 /*
2358 * The limit is specified as a percentage of CPU over an interval in nanoseconds.
2359 * Calculate the amount of CPU time that the thread needs to consume in order to hit the limit.
2360 */
2361 limittime = (interval_ns * percentage) / 100;
2362 nanoseconds_to_absolutetime(limittime, &abstime);
39236c6e 2363 ledger_set_limit(l, thread_ledgers.cpu_time, abstime, cpumon_ustackshots_trigger_pct);
316670eb
A
2364 /*
2365 * Refill the thread's allotted CPU time every interval_ns nanoseconds.
2366 */
2367 ledger_set_period(l, thread_ledgers.cpu_time, interval_ns);
2368
316670eb 2369 if (action == THREAD_CPULIMIT_EXCEPTION) {
39236c6e
A
2370 /*
2371 * We don't support programming the CPU usage monitor on a task if any of its
2372 * threads have a per-thread blocking CPU limit configured.
2373 */
2374 if (thread->options & TH_OPT_PRVT_CPULIMIT) {
2375 panic("CPU usage monitor activated, but blocking thread limit exists");
2376 }
2377
2378 /*
2379 * Make a note that this thread's CPU limit is being used for the task-wide CPU
2380 * usage monitor. We don't have to arm the callback which will trigger the
2381 * exception, because that was done for us in ledger_instantiate (because the
2382 * ledger template used has a default callback).
2383 */
316670eb 2384 thread->options |= TH_OPT_PROC_CPULIMIT;
39236c6e
A
2385 } else {
2386 /*
2387 * We deliberately override any CPU limit imposed by a task-wide limit (eg
2388 * CPU usage monitor).
2389 */
2390 thread->options &= ~TH_OPT_PROC_CPULIMIT;
316670eb 2391
316670eb
A
2392 thread->options |= TH_OPT_PRVT_CPULIMIT;
2393 /* The per-thread ledger template by default has a callback for CPU time */
2394 ledger_disable_callback(l, thread_ledgers.cpu_time);
2395 ledger_set_action(l, thread_ledgers.cpu_time, LEDGER_ACTION_BLOCK);
2396 }
2397
316670eb
A
2398 return (0);
2399}
2400
2d21ac55
A
2401static void
2402sched_call_null(
2403__unused int type,
2404__unused thread_t thread)
2405{
2406 return;
2407}
2408
2409void
2410thread_sched_call(
2411 thread_t thread,
2412 sched_call_t call)
2413{
2414 thread->sched_call = (call != NULL)? call: sched_call_null;
2415}
2416
39037602
A
2417sched_call_t
2418thread_disable_sched_call(
2419 thread_t thread,
2420 sched_call_t call)
2421{
2422 if (call) {
2423 spl_t s = splsched();
2424 thread_lock(thread);
2425 if (thread->sched_call == call) {
2426 thread->sched_call = sched_call_null;
2427 } else {
2428 call = NULL;
2429 }
2430 thread_unlock(thread);
2431 splx(s);
2432 }
2433 return call;
2434}
2435
2436void
2437thread_reenable_sched_call(
2438 thread_t thread,
2439 sched_call_t call)
2440{
2441 if (call) {
2442 spl_t s = splsched();
2443 thread_lock(thread);
2444 thread_sched_call(thread, call);
2445 thread_unlock(thread);
2446 splx(s);
2447 }
2448}
2449
2d21ac55
A
2450void
2451thread_static_param(
2452 thread_t thread,
2453 boolean_t state)
2454{
2455 thread_mtx_lock(thread);
2456 thread->static_param = state;
2457 thread_mtx_unlock(thread);
2458}
1c79356b 2459
b0d623f7
A
2460uint64_t
2461thread_tid(
2462 thread_t thread)
2463{
2464 return (thread != THREAD_NULL? thread->thread_id: 0);
2465}
2466
39236c6e 2467uint16_t thread_set_tag(thread_t th, uint16_t tag) {
4b17d6b6
A
2468 return thread_set_tag_internal(th, tag);
2469}
39236c6e 2470uint16_t thread_get_tag(thread_t th) {
4b17d6b6
A
2471 return thread_get_tag_internal(th);
2472}
2473
b0d623f7
A
2474uint64_t
2475thread_dispatchqaddr(
2476 thread_t thread)
2477{
39037602
A
2478 uint64_t dispatchqueue_addr;
2479 uint64_t thread_handle;
b0d623f7 2480
39037602
A
2481 if (thread == THREAD_NULL)
2482 return 0;
2483
2484 thread_handle = thread->machine.cthread_self;
2485 if (thread_handle == 0)
2486 return 0;
2487
2488 if (thread->inspection == TRUE)
2489 dispatchqueue_addr = thread_handle + get_task_dispatchqueue_offset(thread->task);
2490 else if (thread->task->bsd_info)
2491 dispatchqueue_addr = thread_handle + get_dispatchqueue_offset_from_proc(thread->task->bsd_info);
2492 else
2493 dispatchqueue_addr = 0;
b0d623f7 2494
39037602 2495 return dispatchqueue_addr;
b0d623f7
A
2496}
2497
91447636
A
2498/*
2499 * Export routines to other components for things that are done as macros
2500 * within the osfmk component.
2501 */
1c79356b 2502
91447636
A
2503#undef thread_reference
2504void thread_reference(thread_t thread);
1c79356b 2505void
91447636
A
2506thread_reference(
2507 thread_t thread)
1c79356b 2508{
91447636
A
2509 if (thread != THREAD_NULL)
2510 thread_reference_internal(thread);
1c79356b
A
2511}
2512
1c79356b 2513#undef thread_should_halt
91447636 2514
1c79356b
A
2515boolean_t
2516thread_should_halt(
55e303ae 2517 thread_t th)
1c79356b 2518{
91447636 2519 return (thread_should_halt_fast(th));
55e303ae 2520}
2d21ac55 2521
fe8ab488
A
2522/*
2523 * thread_set_voucher_name - reset the voucher port name bound to this thread
2524 *
2525 * Conditions: nothing locked
2526 *
2527 * If we already converted the previous name to a cached voucher
2528 * reference, then we discard that reference here. The next lookup
2529 * will cache it again.
2530 */
2531
2532kern_return_t
2533thread_set_voucher_name(mach_port_name_t voucher_name)
2534{
2535 thread_t thread = current_thread();
2536 ipc_voucher_t new_voucher = IPC_VOUCHER_NULL;
2537 ipc_voucher_t voucher;
2538#ifdef CONFIG_BANK
2539 ledger_t bankledger = NULL;
2540#endif
2541
2542 if (MACH_PORT_DEAD == voucher_name)
2543 return KERN_INVALID_RIGHT;
2544
2545 /*
2546 * agressively convert to voucher reference
2547 */
2548 if (MACH_PORT_VALID(voucher_name)) {
2549 new_voucher = convert_port_name_to_voucher(voucher_name);
2550 if (IPC_VOUCHER_NULL == new_voucher)
2551 return KERN_INVALID_ARGUMENT;
2552 }
2553#ifdef CONFIG_BANK
2554 bankledger = bank_get_voucher_ledger(new_voucher);
2555#endif
2556
2557 thread_mtx_lock(thread);
2558 voucher = thread->ith_voucher;
2559 thread->ith_voucher_name = voucher_name;
2560 thread->ith_voucher = new_voucher;
2561#ifdef CONFIG_BANK
2562 bank_swap_thread_bank_ledger(thread, bankledger);
2563#endif
2564 thread_mtx_unlock(thread);
2565
2566 KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE,
2567 MACHDBG_CODE(DBG_MACH_IPC,MACH_THREAD_SET_VOUCHER) | DBG_FUNC_NONE,
2568 (uintptr_t)thread_tid(thread),
2569 (uintptr_t)voucher_name,
2570 VM_KERNEL_ADDRPERM((uintptr_t)new_voucher),
2571 1, 0);
2572
2573 if (IPC_VOUCHER_NULL != voucher)
2574 ipc_voucher_release(voucher);
2575
2576 return KERN_SUCCESS;
2577}
2578
2579/*
2580 * thread_get_mach_voucher - return a voucher reference for the specified thread voucher
2581 *
2582 * Conditions: nothing locked
2583 *
2584 * A reference to the voucher may be lazily pending, if someone set the voucher name
2585 * but nobody has done a lookup yet. In that case, we'll have to do the equivalent
2586 * lookup here.
2587 *
2588 * NOTE: At the moment, there is no distinction between the current and effective
2589 * vouchers because we only set them at the thread level currently.
2590 */
2591kern_return_t
2592thread_get_mach_voucher(
2593 thread_act_t thread,
2594 mach_voucher_selector_t __unused which,
2595 ipc_voucher_t *voucherp)
2596{
2597 ipc_voucher_t voucher;
2598 mach_port_name_t voucher_name;
2599
2600 if (THREAD_NULL == thread)
2601 return KERN_INVALID_ARGUMENT;
2602
2603 thread_mtx_lock(thread);
2604 voucher = thread->ith_voucher;
2605
2606 /* if already cached, just return a ref */
2607 if (IPC_VOUCHER_NULL != voucher) {
2608 ipc_voucher_reference(voucher);
2609 thread_mtx_unlock(thread);
2610 *voucherp = voucher;
2611 return KERN_SUCCESS;
2612 }
2613
2614 voucher_name = thread->ith_voucher_name;
2615
2616 /* convert the name to a port, then voucher reference */
2617 if (MACH_PORT_VALID(voucher_name)) {
2618 ipc_port_t port;
2619
2620 if (KERN_SUCCESS !=
2621 ipc_object_copyin(thread->task->itk_space, voucher_name,
2622 MACH_MSG_TYPE_COPY_SEND, (ipc_object_t *)&port)) {
2623 thread->ith_voucher_name = MACH_PORT_NULL;
2624 thread_mtx_unlock(thread);
2625 *voucherp = IPC_VOUCHER_NULL;
2626 return KERN_SUCCESS;
2627 }
2628
2629 /* convert to a voucher ref to return, and cache a ref on thread */
2630 voucher = convert_port_to_voucher(port);
2631 ipc_voucher_reference(voucher);
2632 thread->ith_voucher = voucher;
2633 thread_mtx_unlock(thread);
2634
2635 KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE,
2636 MACHDBG_CODE(DBG_MACH_IPC,MACH_THREAD_SET_VOUCHER) | DBG_FUNC_NONE,
2637 (uintptr_t)thread_tid(thread),
2638 (uintptr_t)port,
2639 VM_KERNEL_ADDRPERM((uintptr_t)voucher),
2640 2, 0);
2641
2642
2643 ipc_port_release_send(port);
2644 } else
2645 thread_mtx_unlock(thread);
2646
2647 *voucherp = voucher;
2648 return KERN_SUCCESS;
2649}
2650
2651/*
2652 * thread_set_mach_voucher - set a voucher reference for the specified thread voucher
2653 *
2654 * Conditions: callers holds a reference on the voucher.
2655 * nothing locked.
2656 *
2657 * We grab another reference to the voucher and bind it to the thread. Any lazy
2658 * binding is erased. The old voucher reference associated with the thread is
2659 * discarded.
2660 */
2661kern_return_t
2662thread_set_mach_voucher(
2663 thread_t thread,
2664 ipc_voucher_t voucher)
2665{
2666 ipc_voucher_t old_voucher;
2667#ifdef CONFIG_BANK
2668 ledger_t bankledger = NULL;
2669#endif
2670
2671 if (THREAD_NULL == thread)
2672 return KERN_INVALID_ARGUMENT;
2673
2674 if (thread != current_thread() || thread->started)
2675 return KERN_INVALID_ARGUMENT;
2676
2677
2678 ipc_voucher_reference(voucher);
2679#ifdef CONFIG_BANK
2680 bankledger = bank_get_voucher_ledger(voucher);
2681#endif
2682 thread_mtx_lock(thread);
2683 old_voucher = thread->ith_voucher;
2684 thread->ith_voucher = voucher;
2685 thread->ith_voucher_name = MACH_PORT_NULL;
2686#ifdef CONFIG_BANK
2687 bank_swap_thread_bank_ledger(thread, bankledger);
2688#endif
2689 thread_mtx_unlock(thread);
2690
2691 KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE,
2692 MACHDBG_CODE(DBG_MACH_IPC,MACH_THREAD_SET_VOUCHER) | DBG_FUNC_NONE,
2693 (uintptr_t)thread_tid(thread),
2694 (uintptr_t)MACH_PORT_NULL,
2695 VM_KERNEL_ADDRPERM((uintptr_t)voucher),
2696 3, 0);
2697
2698 ipc_voucher_release(old_voucher);
2699
2700 return KERN_SUCCESS;
2701}
2702
2703/*
2704 * thread_swap_mach_voucher - swap a voucher reference for the specified thread voucher
2705 *
2706 * Conditions: callers holds a reference on the new and presumed old voucher(s).
2707 * nothing locked.
2708 *
2709 * If the old voucher is still the same as passed in, replace it with new voucher
2710 * and discard the old (and the reference passed in). Otherwise, discard the new
2711 * and return an updated old voucher.
2712 */
2713kern_return_t
2714thread_swap_mach_voucher(
2715 thread_t thread,
2716 ipc_voucher_t new_voucher,
2717 ipc_voucher_t *in_out_old_voucher)
2718{
2719 mach_port_name_t old_voucher_name;
2720 ipc_voucher_t old_voucher;
2721#ifdef CONFIG_BANK
2722 ledger_t bankledger = NULL;
2723#endif
2724
2725 if (THREAD_NULL == thread)
2726 return KERN_INVALID_TASK;
2727
2728 if (thread != current_thread() || thread->started)
2729 return KERN_INVALID_ARGUMENT;
2730
2731#ifdef CONFIG_BANK
2732 bankledger = bank_get_voucher_ledger(new_voucher);
2733#endif
2734
2735 thread_mtx_lock(thread);
2736
2737 old_voucher = thread->ith_voucher;
2738
2739 if (IPC_VOUCHER_NULL == old_voucher) {
2740 old_voucher_name = thread->ith_voucher_name;
2741
2742 /* perform lazy binding if needed */
2743 if (MACH_PORT_VALID(old_voucher_name)) {
2744 old_voucher = convert_port_name_to_voucher(old_voucher_name);
2745 thread->ith_voucher_name = MACH_PORT_NULL;
2746 thread->ith_voucher = old_voucher;
2747
2748 KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE,
2749 MACHDBG_CODE(DBG_MACH_IPC,MACH_THREAD_SET_VOUCHER) | DBG_FUNC_NONE,
2750 (uintptr_t)thread_tid(thread),
2751 (uintptr_t)old_voucher_name,
2752 VM_KERNEL_ADDRPERM((uintptr_t)old_voucher),
2753 4, 0);
2754
2755 }
2756 }
2757
2758 /* swap in new voucher, if old voucher matches the one supplied */
2759 if (old_voucher == *in_out_old_voucher) {
2760 ipc_voucher_reference(new_voucher);
2761 thread->ith_voucher = new_voucher;
2762 thread->ith_voucher_name = MACH_PORT_NULL;
2763#ifdef CONFIG_BANK
2764 bank_swap_thread_bank_ledger(thread, bankledger);
2765#endif
2766 thread_mtx_unlock(thread);
2767
2768 KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE,
2769 MACHDBG_CODE(DBG_MACH_IPC,MACH_THREAD_SET_VOUCHER) | DBG_FUNC_NONE,
2770 (uintptr_t)thread_tid(thread),
2771 (uintptr_t)MACH_PORT_NULL,
2772 VM_KERNEL_ADDRPERM((uintptr_t)new_voucher),
2773 5, 0);
2774
2775 ipc_voucher_release(old_voucher);
2776
2777 *in_out_old_voucher = IPC_VOUCHER_NULL;
2778 return KERN_SUCCESS;
2779 }
2780
2781 /* Otherwise, just return old voucher reference */
2782 ipc_voucher_reference(old_voucher);
2783 thread_mtx_unlock(thread);
2784 *in_out_old_voucher = old_voucher;
2785 return KERN_SUCCESS;
2786}
2787
2788/*
2789 * thread_get_current_voucher_origin_pid - get the pid of the originator of the current voucher.
2790 */
2791kern_return_t
2792thread_get_current_voucher_origin_pid(
2793 int32_t *pid)
2794{
2795 uint32_t buf_size;
2796 kern_return_t kr;
2797 thread_t thread = current_thread();
2798
2799 buf_size = sizeof(*pid);
2800 kr = mach_voucher_attr_command(thread->ith_voucher,
2801 MACH_VOUCHER_ATTR_KEY_BANK,
2802 BANK_ORIGINATOR_PID,
2803 NULL,
2804 0,
2805 (mach_voucher_attr_content_t)pid,
2806 &buf_size);
2807
2808 return kr;
2809}
2810
39037602
A
2811boolean_t
2812thread_has_thread_name(thread_t th)
2813{
2814 if ((th) && (th->uthread)) {
2815 return bsd_hasthreadname(th->uthread);
2816 }
2817
2818 /*
2819 * This is an odd case; clients may set the thread name based on the lack of
2820 * a name, but in this context there is no uthread to attach the name to.
2821 */
2822 return FALSE;
2823}
2824
2825void
2826thread_set_thread_name(thread_t th, const char* name)
2827{
2828 if ((th) && (th->uthread) && name) {
2829 bsd_setthreadname(th->uthread, name);
2830 }
2831}
2832
490019cf
A
2833/*
2834 * thread_enable_send_importance - set/clear the SEND_IMPORTANCE thread option bit.
2835 */
2836void thread_enable_send_importance(thread_t thread, boolean_t enable)
2837{
2838 if (enable == TRUE)
2839 thread->options |= TH_OPT_SEND_IMPORTANCE;
2840 else
2841 thread->options &= ~TH_OPT_SEND_IMPORTANCE;
2842}
2843
2d21ac55
A
2844#if CONFIG_DTRACE
2845uint32_t dtrace_get_thread_predcache(thread_t thread)
2846{
2847 if (thread != THREAD_NULL)
2848 return thread->t_dtrace_predcache;
2849 else
2850 return 0;
2851}
2852
2853int64_t dtrace_get_thread_vtime(thread_t thread)
2854{
2855 if (thread != THREAD_NULL)
2856 return thread->t_dtrace_vtime;
2857 else
2858 return 0;
2859}
2860
3e170ce0
A
2861int dtrace_get_thread_last_cpu_id(thread_t thread)
2862{
2863 if ((thread != THREAD_NULL) && (thread->last_processor != PROCESSOR_NULL)) {
2864 return thread->last_processor->cpu_id;
2865 } else {
2866 return -1;
2867 }
2868}
2869
2d21ac55
A
2870int64_t dtrace_get_thread_tracing(thread_t thread)
2871{
2872 if (thread != THREAD_NULL)
2873 return thread->t_dtrace_tracing;
2874 else
2875 return 0;
2876}
2877
2878boolean_t dtrace_get_thread_reentering(thread_t thread)
2879{
2880 if (thread != THREAD_NULL)
2881 return (thread->options & TH_OPT_DTRACE) ? TRUE : FALSE;
2882 else
2883 return 0;
2884}
2885
2886vm_offset_t dtrace_get_kernel_stack(thread_t thread)
2887{
2888 if (thread != THREAD_NULL)
2889 return thread->kernel_stack;
2890 else
2891 return 0;
2892}
2893
2894int64_t dtrace_calc_thread_recent_vtime(thread_t thread)
2895{
2d21ac55
A
2896 if (thread != THREAD_NULL) {
2897 processor_t processor = current_processor();
2898 uint64_t abstime = mach_absolute_time();
2899 timer_t timer;
2900
2901 timer = PROCESSOR_DATA(processor, thread_timer);
2902
2903 return timer_grab(&(thread->system_timer)) + timer_grab(&(thread->user_timer)) +
2904 (abstime - timer->tstamp); /* XXX need interrupts off to prevent missed time? */
2905 } else
2906 return 0;
2d21ac55
A
2907}
2908
2909void dtrace_set_thread_predcache(thread_t thread, uint32_t predcache)
2910{
2911 if (thread != THREAD_NULL)
2912 thread->t_dtrace_predcache = predcache;
2913}
2914
2915void dtrace_set_thread_vtime(thread_t thread, int64_t vtime)
2916{
2917 if (thread != THREAD_NULL)
2918 thread->t_dtrace_vtime = vtime;
2919}
2920
2921void dtrace_set_thread_tracing(thread_t thread, int64_t accum)
2922{
2923 if (thread != THREAD_NULL)
2924 thread->t_dtrace_tracing = accum;
2925}
2926
2927void dtrace_set_thread_reentering(thread_t thread, boolean_t vbool)
2928{
2929 if (thread != THREAD_NULL) {
2930 if (vbool)
2931 thread->options |= TH_OPT_DTRACE;
2932 else
2933 thread->options &= (~TH_OPT_DTRACE);
2934 }
2935}
2936
2937vm_offset_t dtrace_set_thread_recover(thread_t thread, vm_offset_t recover)
2938{
2939 vm_offset_t prev = 0;
2940
2941 if (thread != THREAD_NULL) {
2942 prev = thread->recover;
2943 thread->recover = recover;
2944 }
2945 return prev;
2946}
2947
b0d623f7
A
2948void dtrace_thread_bootstrap(void)
2949{
2950 task_t task = current_task();
39236c6e
A
2951
2952 if (task->thread_count == 1) {
2953 thread_t thread = current_thread();
2954 if (thread->t_dtrace_flags & TH_DTRACE_EXECSUCCESS) {
2955 thread->t_dtrace_flags &= ~TH_DTRACE_EXECSUCCESS;
2956 DTRACE_PROC(exec__success);
39037602
A
2957 KDBG(BSDDBG_CODE(DBG_BSD_PROC,BSD_PROC_EXEC),
2958 task_pid(task));
39236c6e 2959 }
b0d623f7
A
2960 DTRACE_PROC(start);
2961 }
2962 DTRACE_PROC(lwp__start);
2963
2964}
39236c6e
A
2965
2966void
2967dtrace_thread_didexec(thread_t thread)
2968{
2969 thread->t_dtrace_flags |= TH_DTRACE_EXECSUCCESS;
2970}
2d21ac55 2971#endif /* CONFIG_DTRACE */