2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
23 * @OSF_FREE_COPYRIGHT@
26 * Mach Operating System
27 * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
28 * All Rights Reserved.
30 * Permission to use, copy, modify and distribute this software and its
31 * documentation is hereby granted, provided that both the copyright
32 * notice and this permission notice appear in all copies of the
33 * software, derivative works or modified versions, and any portions
34 * thereof, and that both notices appear in supporting documentation.
36 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
37 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
38 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
40 * Carnegie Mellon requests users of this software to return to
42 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
43 * School of Computer Science
44 * Carnegie Mellon University
45 * Pittsburgh PA 15213-3890
47 * any improvements or extensions that they make and grant Carnegie Mellon
48 * the rights to redistribute these changes.
54 * Author: Avadis Tevanian, Jr., Michael Wayne Young, David Golub
57 * Thread/thread_shuttle management primitives implementation.
60 * Copyright (c) 1993 The University of Utah and
61 * the Computer Systems Laboratory (CSL). All rights reserved.
63 * Permission to use, copy, modify and distribute this software and its
64 * documentation is hereby granted, provided that both the copyright
65 * notice and this permission notice appear in all copies of the
66 * software, derivative works or modified versions, and any portions
67 * thereof, and that both notices appear in supporting documentation.
69 * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS
70 * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF
71 * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
73 * CSL requests users of this software to return to csl-dist@cs.utah.edu any
74 * improvements that they make and grant CSL redistribution rights.
79 #include <mach_host.h>
80 #include <simple_clock.h>
81 #include <mach_debug.h>
82 #include <mach_prof.h>
84 #include <mach/boolean.h>
85 #include <mach/policy.h>
86 #include <mach/thread_info.h>
87 #include <mach/thread_special_ports.h>
88 #include <mach/thread_status.h>
89 #include <mach/time_value.h>
90 #include <mach/vm_param.h>
92 #include <kern/cpu_data.h>
93 #include <kern/counters.h>
94 #include <kern/etap_macros.h>
95 #include <kern/ipc_mig.h>
96 #include <kern/ipc_tt.h>
97 #include <kern/mach_param.h>
98 #include <kern/machine.h>
99 #include <kern/misc_protos.h>
100 #include <kern/processor.h>
101 #include <kern/queue.h>
102 #include <kern/sched.h>
103 #include <kern/sched_prim.h>
104 #include <kern/mk_sp.h> /*** ??? fix so this can be removed ***/
105 #include <kern/task.h>
106 #include <kern/thread.h>
107 #include <kern/thread_act.h>
108 #include <kern/thread_swap.h>
109 #include <kern/host.h>
110 #include <kern/zalloc.h>
111 #include <vm/vm_kern.h>
112 #include <ipc/ipc_kmsg.h>
113 #include <ipc/ipc_port.h>
114 #include <machine/thread.h> /* for MACHINE_STACK */
115 #include <kern/profile.h>
116 #include <kern/assert.h>
117 #include <sys/kdebug.h>
120 * Exported interfaces
123 #include <mach/thread_act_server.h>
124 #include <mach/mach_host_server.h>
127 * Per-Cpu stashed global state
129 vm_offset_t active_stacks
[NCPUS
]; /* per-cpu active stacks */
130 vm_offset_t kernel_stack
[NCPUS
]; /* top of active stacks */
131 thread_act_t active_kloaded
[NCPUS
]; /* + act if kernel loaded */
132 boolean_t first_thread
;
134 struct zone
*thread_shuttle_zone
;
136 queue_head_t reaper_queue
;
137 decl_simple_lock_data(,reaper_lock
)
141 extern void pcb_module_init(void);
143 struct thread_shuttle pageout_thread
;
146 static struct thread_shuttle thr_sh_template
;
151 extern void stack_statistics(
152 unsigned int *totalp
,
153 vm_size_t
*maxusagep
);
154 #endif /* MACHINE_STACK */
155 #endif /* MACH_DEBUG */
158 void thread_collect_scan(void);
160 kern_return_t
thread_create_shuttle(
161 thread_act_t thr_act
,
164 thread_t
*new_thread
);
166 extern void Load_context(
171 * Machine-dependent code must define:
172 * thread_machine_init
173 * thread_machine_terminate
174 * thread_machine_collect
176 * The thread->pcb field is reserved for machine-dependent code.
181 * Machine-dependent code must define:
190 #else /* MACHINE_STACK */
192 * We allocate stacks from generic kernel VM.
193 * Machine-dependent code must define:
194 * machine_kernel_stack_init
196 * The stack_free_list can only be accessed at splsched,
197 * because stack_alloc_try/thread_invoke operate at splsched.
200 decl_simple_lock_data(,stack_lock_data
) /* splsched only */
201 #define stack_lock() simple_lock(&stack_lock_data)
202 #define stack_unlock() simple_unlock(&stack_lock_data)
204 mutex_t stack_map_lock
; /* Lock when allocating stacks maps */
205 vm_map_t stack_map
; /* Map for allocating stacks */
206 vm_offset_t stack_free_list
; /* splsched only */
207 unsigned int stack_free_max
= 0;
208 unsigned int stack_free_count
= 0; /* splsched only */
209 unsigned int stack_free_limit
= 1; /* Arbitrary */
211 unsigned int stack_alloc_hits
= 0; /* debugging */
212 unsigned int stack_alloc_misses
= 0; /* debugging */
214 unsigned int stack_alloc_total
= 0;
215 unsigned int stack_alloc_hiwater
= 0;
216 unsigned int stack_alloc_bndry
= 0;
220 * The next field is at the base of the stack,
221 * so the low end is left unsullied.
224 #define stack_next(stack) (*((vm_offset_t *)((stack) + KERNEL_STACK_SIZE) - 1))
229 * Allocate a kernel stack for an activation.
235 void (*start_pos
)(thread_t
))
237 vm_offset_t stack
= thread
->kernel_stack
;
244 * We first try the free list. It is probably empty, or
245 * stack_alloc_try would have succeeded, but possibly a stack was
246 * freed before the swapin thread got to us.
248 * We allocate stacks from their own map which is submaps of the
249 * kernel map. Because we want to have a guard page (at least) in
250 * front of each stack to catch evil code that overruns its stack, we
251 * allocate the stack on aligned boundaries. The boundary is
252 * calculated as the next power of 2 above the stack size. For
253 * example, a stack of 4 pages would have a boundry of 8, likewise 5
256 * We limit the number of stacks to be one allocation chunk
257 * (THREAD_CHUNK) more than the maximum number of threads
258 * (THREAD_MAX). The extra is to allow for priviliged threads that
259 * can sometimes have 2 stacks.
265 stack
= stack_free_list
;
267 stack_free_list
= stack_next(stack
);
273 if (stack
!= 0) { /* Did we find a free one? */
274 stack_attach(thread
, stack
, start_pos
); /* Initialize it */
275 return (stack
); /* Send it on home */
278 if (kernel_memory_allocate(
280 KERNEL_STACK_SIZE
, stack_alloc_bndry
- 1,
281 KMA_KOBJECT
) != KERN_SUCCESS
)
282 panic("stack_alloc: no space left for stack maps");
285 if (stack_alloc_total
> stack_alloc_hiwater
)
286 stack_alloc_hiwater
= stack_alloc_total
;
288 stack_attach(thread
, stack
, start_pos
);
295 * Free a kernel stack.
296 * Called at splsched.
303 vm_offset_t stack
= stack_detach(thread
);
306 if (stack
!= thread
->stack_privilege
) {
308 stack_next(stack
) = stack_free_list
;
309 stack_free_list
= stack
;
310 if (++stack_free_count
> stack_free_max
)
311 stack_free_max
= stack_free_count
;
324 stack_next(stack
) = stack_free_list
;
325 stack_free_list
= stack
;
326 if (++stack_free_count
> stack_free_max
)
327 stack_free_max
= stack_free_count
;
335 * Free excess kernel stacks.
348 while (stack_free_count
> stack_free_limit
) {
349 stack
= stack_free_list
;
350 stack_free_list
= stack_next(stack
);
356 stack_map
, stack
, stack
+ KERNEL_STACK_SIZE
,
357 VM_MAP_REMOVE_KUNWIRE
) != KERN_SUCCESS
)
358 panic("stack_collect: vm_map_remove failed");
373 * Return statistics on cached kernel stacks.
374 * *maxusagep must be initialized by the caller.
379 unsigned int *totalp
,
380 vm_size_t
*maxusagep
)
387 *totalp
= stack_free_count
;
393 #endif /* MACH_DEBUG */
395 #endif /* MACHINE_STACK */
398 stack_fake_zone_info(int *count
, vm_size_t
*cur_size
, vm_size_t
*max_size
, vm_size_t
*elem_size
,
399 vm_size_t
*alloc_size
, int *collectable
, int *exhaustable
)
401 *count
= stack_alloc_total
- stack_free_count
;
402 *cur_size
= KERNEL_STACK_SIZE
* stack_alloc_total
;
403 *max_size
= KERNEL_STACK_SIZE
* stack_alloc_hiwater
;
404 *elem_size
= KERNEL_STACK_SIZE
;
405 *alloc_size
= KERNEL_STACK_SIZE
;
414 * stack_alloc_try on this thread must always succeed.
419 register thread_t thread
)
422 * This implementation only works for the current thread.
425 if (thread
!= current_thread())
426 panic("stack_privilege");
428 if (thread
->stack_privilege
== 0)
429 thread
->stack_privilege
= current_stack();
435 * Non-blocking attempt to allocate a kernel stack.
436 * Called at splsched with the thread locked.
439 boolean_t
stack_alloc_try(
441 void (*start_pos
)(thread_t
))
443 register vm_offset_t stack
= thread
->stack_privilege
;
448 stack
= stack_free_list
;
449 if (stack
!= (vm_offset_t
)0) {
450 stack_free_list
= stack_next(stack
);
458 stack_attach(thread
, stack
, start_pos
);
464 stack_alloc_misses
++;
470 uint64_t max_unsafe_computation
;
471 extern int max_unsafe_quanta
;
473 uint32_t sched_safe_duration
;
475 uint64_t max_poll_computation
;
476 extern int max_poll_quanta
;
478 uint32_t std_quantum
;
479 uint32_t min_std_quantum
;
481 uint32_t max_rt_quantum
;
482 uint32_t min_rt_quantum
;
490 thread_shuttle_zone
= zinit(
491 sizeof(struct thread_shuttle
),
492 THREAD_MAX
* sizeof(struct thread_shuttle
),
493 THREAD_CHUNK
* sizeof(struct thread_shuttle
),
497 * Fill in a template thread_shuttle for fast initialization.
498 * [Fields that must be (or are typically) reset at
499 * time of creation are so noted.]
502 /* thr_sh_template.links (none) */
503 thr_sh_template
.runq
= RUN_QUEUE_NULL
;
506 /* thr_sh_template.task (later) */
507 /* thr_sh_template.thread_list (later) */
508 /* thr_sh_template.pset_threads (later) */
510 /* reference for activation */
511 thr_sh_template
.ref_count
= 1;
513 thr_sh_template
.reason
= AST_NONE
;
514 thr_sh_template
.at_safe_point
= FALSE
;
515 thr_sh_template
.wait_event
= NO_EVENT64
;
516 thr_sh_template
.wait_queue
= WAIT_QUEUE_NULL
;
517 thr_sh_template
.wait_result
= THREAD_WAITING
;
518 thr_sh_template
.interrupt_level
= THREAD_ABORTSAFE
;
519 thr_sh_template
.state
= TH_STACK_HANDOFF
| TH_WAIT
| TH_UNINT
;
520 thr_sh_template
.wake_active
= FALSE
;
521 thr_sh_template
.active_callout
= FALSE
;
522 thr_sh_template
.continuation
= (void (*)(void))0;
523 thr_sh_template
.top_act
= THR_ACT_NULL
;
525 thr_sh_template
.importance
= 0;
526 thr_sh_template
.sched_mode
= 0;
527 thr_sh_template
.safe_mode
= 0;
529 thr_sh_template
.priority
= 0;
530 thr_sh_template
.sched_pri
= 0;
531 thr_sh_template
.max_priority
= 0;
532 thr_sh_template
.task_priority
= 0;
533 thr_sh_template
.promotions
= 0;
534 thr_sh_template
.pending_promoter_index
= 0;
535 thr_sh_template
.pending_promoter
[0] =
536 thr_sh_template
.pending_promoter
[1] = NULL
;
538 thr_sh_template
.current_quantum
= 0;
540 thr_sh_template
.computation_metered
= 0;
541 thr_sh_template
.computation_epoch
= 0;
543 thr_sh_template
.cpu_usage
= 0;
544 thr_sh_template
.cpu_delta
= 0;
545 thr_sh_template
.sched_usage
= 0;
546 thr_sh_template
.sched_delta
= 0;
547 thr_sh_template
.sched_stamp
= 0;
548 thr_sh_template
.sleep_stamp
= 0;
549 thr_sh_template
.safe_release
= 0;
551 thr_sh_template
.bound_processor
= PROCESSOR_NULL
;
552 thr_sh_template
.last_processor
= PROCESSOR_NULL
;
553 thr_sh_template
.last_switch
= 0;
555 thr_sh_template
.vm_privilege
= FALSE
;
557 timer_init(&(thr_sh_template
.user_timer
));
558 timer_init(&(thr_sh_template
.system_timer
));
559 thr_sh_template
.user_timer_save
.low
= 0;
560 thr_sh_template
.user_timer_save
.high
= 0;
561 thr_sh_template
.system_timer_save
.low
= 0;
562 thr_sh_template
.system_timer_save
.high
= 0;
564 thr_sh_template
.active
= FALSE
; /* reset */
566 thr_sh_template
.processor_set
= PROCESSOR_SET_NULL
;
568 thr_sh_template
.may_assign
= TRUE
;
569 thr_sh_template
.assign_active
= FALSE
;
570 #endif /* MACH_HOST */
571 thr_sh_template
.funnel_state
= 0;
574 * Initialize other data structures used in
578 queue_init(&reaper_queue
);
579 simple_lock_init(&reaper_lock
, ETAP_THREAD_REAPER
);
580 thr_sh_template
.funnel_lock
= THR_FUNNEL_NULL
;
582 #ifndef MACHINE_STACK
583 simple_lock_init(&stack_lock_data
, ETAP_THREAD_STACK
); /* Initialize the stack lock */
585 if (KERNEL_STACK_SIZE
< round_page(KERNEL_STACK_SIZE
)) { /* Kernel stacks must be multiples of pages */
586 panic("thread_init: kernel stack size (%08X) must be a multiple of page size (%08X)\n",
587 KERNEL_STACK_SIZE
, PAGE_SIZE
);
590 for(stack_alloc_bndry
= PAGE_SIZE
; stack_alloc_bndry
<= KERNEL_STACK_SIZE
; stack_alloc_bndry
<<= 1); /* Find next power of 2 above stack size */
592 ret
= kmem_suballoc(kernel_map
, /* Suballocate from the kernel map */
595 (stack_alloc_bndry
* (2*THREAD_MAX
+ 64)), /* Allocate enough for all of it */
596 FALSE
, /* Say not pageable so that it is wired */
597 TRUE
, /* Allocate from anywhere */
598 &stack_map
); /* Allocate a submap */
600 if(ret
!= KERN_SUCCESS
) { /* Did we get one? */
601 panic("thread_init: kmem_suballoc for stacks failed - ret = %d\n", ret
); /* Die */
603 stack
= vm_map_min(stack_map
); /* Make sure we skip the first hunk */
604 ret
= vm_map_enter(stack_map
, &stack
, PAGE_SIZE
, 0, /* Make sure there is nothing at the start */
605 0, /* Force it at start */
606 VM_OBJECT_NULL
, 0, /* No object yet */
608 VM_PROT_NONE
, /* Allow no access */
609 VM_PROT_NONE
, /* Allow no access */
610 VM_INHERIT_DEFAULT
); /* Just be normal */
612 if(ret
!= KERN_SUCCESS
) { /* Did it work? */
613 panic("thread_init: dummy alignment allocation failed; ret = %d\n", ret
);
616 #endif /* MACHINE_STACK */
619 thr_sh_template
.mutex_count
= 0;
620 #endif /* MACH_LDEBUG */
625 clock_interval_to_absolutetime_interval(
626 std_quantum_us
, NSEC_PER_USEC
, &abstime
);
627 assert((abstime
>> 32) == 0 && (uint32_t)abstime
!= 0);
628 std_quantum
= abstime
;
631 clock_interval_to_absolutetime_interval(250, NSEC_PER_USEC
, &abstime
);
632 assert((abstime
>> 32) == 0 && (uint32_t)abstime
!= 0);
633 min_std_quantum
= abstime
;
636 clock_interval_to_absolutetime_interval(50, NSEC_PER_USEC
, &abstime
);
637 assert((abstime
>> 32) == 0 && (uint32_t)abstime
!= 0);
638 min_rt_quantum
= abstime
;
641 clock_interval_to_absolutetime_interval(
642 50, 1000*NSEC_PER_USEC
, &abstime
);
643 assert((abstime
>> 32) == 0 && (uint32_t)abstime
!= 0);
644 max_rt_quantum
= abstime
;
646 max_unsafe_computation
= max_unsafe_quanta
* std_quantum
;
647 max_poll_computation
= max_poll_quanta
* std_quantum
;
649 sched_safe_duration
= 2 * max_unsafe_quanta
*
650 (std_quantum_us
/ (1000 * 1000)) *
651 (1 << SCHED_TICK_SHIFT
);
656 * Initialize any machine-dependent
657 * per-thread structures necessary.
659 thread_machine_init();
663 * Called at splsched.
666 thread_reaper_enqueue(
669 simple_lock(&reaper_lock
);
670 enqueue_tail(&reaper_queue
, (queue_entry_t
)thread
);
671 simple_unlock(&reaper_lock
);
673 thread_wakeup((event_t
)&reaper_queue
);
677 thread_termination_continue(void)
679 panic("thread_termination_continue");
684 * Routine: thread_terminate_self
686 * This routine is called by a thread which has unwound from
687 * its current RPC and kernel contexts and found that it's
688 * root activation has been marked for extinction. This lets
689 * it clean up the last few things that can only be cleaned
690 * up in this context and then impale itself on the reaper
693 * When the reaper gets the thread, it will deallocate the
694 * thread_act's reference on itself, which in turn will release
695 * its own reference on this thread. By doing things in that
696 * order, a thread_act will always have a valid thread - but the
697 * thread may persist beyond having a thread_act (but must never
701 thread_terminate_self(void)
703 thread_act_t thr_act
= current_act();
705 task_t task
= thr_act
->task
;
710 * We should be at the base of the inheritance chain.
712 thread
= act_lock_thread(thr_act
);
713 assert(thr_act
->thread
== thread
);
715 /* This will allow no more control ops on this thr_act. */
716 ipc_thr_act_disable(thr_act
);
718 /* Clean-up any ulocks that are still owned by the thread
719 * activation (acquired but not released or handed-off).
721 act_ulock_release_all(thr_act
);
723 act_unlock_thread(thr_act
);
725 _mk_sp_thread_depress_abort(thread
, TRUE
);
728 * Check to see if this is the last active activation. By
729 * this we mean the last activation to call thread_terminate_self.
730 * If so, and the task is associated with a BSD process, we
731 * need to call BSD and let them clean up.
733 active_acts
= hw_atomic_sub(&task
->active_act_count
, 1);
735 if (active_acts
== 0 && task
->bsd_info
)
736 proc_exit(task
->bsd_info
);
738 /* JMM - for now, no migration */
739 assert(!thr_act
->lower
);
743 thread
->active
= FALSE
;
744 thread_unlock(thread
);
747 thread_timer_terminate();
749 /* flush any lazy HW state while in own context */
750 thread_machine_flush(thr_act
);
752 ipc_thread_terminate(thread
);
756 thread
->state
|= TH_TERMINATE
;
757 assert((thread
->state
& TH_UNINT
) == 0);
758 thread_mark_wait_locked(thread
, THREAD_UNINT
);
759 assert(thread
->promotions
== 0);
760 thread_unlock(thread
);
763 ETAP_SET_REASON(thread
, BLOCKED_ON_TERMINATION
);
764 thread_block(thread_termination_continue
);
769 * Create a new thread.
770 * Doesn't start the thread running; It first must be attached to
771 * an activation - then use thread_go to start it.
774 thread_create_shuttle(
775 thread_act_t thr_act
,
778 thread_t
*new_thread
)
780 kern_return_t result
;
781 thread_t new_shuttle
;
782 task_t parent_task
= thr_act
->task
;
783 processor_set_t pset
;
786 * Allocate a thread and initialize static fields
789 new_shuttle
= &pageout_thread
;
790 first_thread
= FALSE
;
792 new_shuttle
= (thread_t
)zalloc(thread_shuttle_zone
);
793 if (new_shuttle
== THREAD_NULL
)
794 return (KERN_RESOURCE_SHORTAGE
);
797 if (new_shuttle
!= &pageout_thread
)
798 assert(!thr_act
->thread
);
801 *new_shuttle
= thr_sh_template
;
803 thread_lock_init(new_shuttle
);
804 wake_lock_init(new_shuttle
);
805 new_shuttle
->sleep_stamp
= sched_tick
;
808 * Thread still isn't runnable yet (our caller will do
809 * that). Initialize runtime-dependent fields here.
811 result
= thread_machine_create(new_shuttle
, thr_act
, thread_continue
);
812 assert (result
== KERN_SUCCESS
);
814 thread_start(new_shuttle
, start
);
815 thread_timer_setup(new_shuttle
);
816 ipc_thread_init(new_shuttle
);
818 pset
= parent_task
->processor_set
;
819 assert(pset
== &default_pset
);
822 task_lock(parent_task
);
823 assert(parent_task
->processor_set
== pset
);
826 * Don't need to initialize because the context switch
827 * code will set it before it can be used.
829 if (!parent_task
->active
) {
830 task_unlock(parent_task
);
832 thread_machine_destroy(new_shuttle
);
833 zfree(thread_shuttle_zone
, (vm_offset_t
) new_shuttle
);
834 return (KERN_FAILURE
);
837 act_attach(thr_act
, new_shuttle
, 0);
839 /* Chain the thr_act onto the task's list */
840 queue_enter(&parent_task
->thr_acts
, thr_act
, thread_act_t
, thr_acts
);
841 parent_task
->thr_act_count
++;
842 parent_task
->res_act_count
++;
844 /* So terminating threads don't need to take the task lock to decrement */
845 hw_atomic_add(&parent_task
->active_act_count
, 1);
847 /* Associate the thread with the processor set */
848 pset_add_thread(pset
, new_shuttle
);
850 /* Set the thread's scheduling parameters */
851 if (parent_task
!= kernel_task
)
852 new_shuttle
->sched_mode
|= TH_MODE_TIMESHARE
;
853 new_shuttle
->max_priority
= parent_task
->max_priority
;
854 new_shuttle
->task_priority
= parent_task
->priority
;
855 new_shuttle
->priority
= (priority
< 0)? parent_task
->priority
: priority
;
856 if (new_shuttle
->priority
> new_shuttle
->max_priority
)
857 new_shuttle
->priority
= new_shuttle
->max_priority
;
858 new_shuttle
->importance
=
859 new_shuttle
->priority
- new_shuttle
->task_priority
;
860 new_shuttle
->sched_stamp
= sched_tick
;
861 compute_priority(new_shuttle
, FALSE
);
863 #if ETAP_EVENT_MONITOR
864 new_thread
->etap_reason
= 0;
865 new_thread
->etap_trace
= FALSE
;
866 #endif /* ETAP_EVENT_MONITOR */
868 new_shuttle
->active
= TRUE
;
869 thr_act
->active
= TRUE
;
871 *new_thread
= new_shuttle
;
874 long dbg_arg1
, dbg_arg2
, dbg_arg3
, dbg_arg4
;
876 KERNEL_DEBUG_CONSTANT(
877 TRACEDBG_CODE(DBG_TRACE_DATA
, 1) | DBG_FUNC_NONE
,
878 (vm_address_t
)new_shuttle
, 0, 0, 0, 0);
880 kdbg_trace_string(parent_task
->bsd_info
,
881 &dbg_arg1
, &dbg_arg2
, &dbg_arg3
, &dbg_arg4
);
883 KERNEL_DEBUG_CONSTANT(
884 TRACEDBG_CODE(DBG_TRACE_STRING
, 1) | DBG_FUNC_NONE
,
885 dbg_arg1
, dbg_arg2
, dbg_arg3
, dbg_arg4
, 0);
888 return (KERN_SUCCESS
);
891 extern void thread_bootstrap_return(void);
896 thread_act_t
*new_act
)
898 kern_return_t result
;
902 if (task
== TASK_NULL
)
903 return KERN_INVALID_ARGUMENT
;
905 result
= act_create(task
, &act
);
906 if (result
!= KERN_SUCCESS
)
909 result
= thread_create_shuttle(act
, -1, thread_bootstrap_return
, &thread
);
910 if (result
!= KERN_SUCCESS
) {
915 act
->user_stop_count
= 1;
917 if (task
->suspend_count
> 0)
920 pset_unlock(task
->processor_set
);
925 return (KERN_SUCCESS
);
929 thread_create_running(
930 register task_t task
,
932 thread_state_t new_state
,
933 mach_msg_type_number_t new_state_count
,
934 thread_act_t
*new_act
) /* OUT */
936 register kern_return_t result
;
940 if (task
== TASK_NULL
)
941 return KERN_INVALID_ARGUMENT
;
943 result
= act_create(task
, &act
);
944 if (result
!= KERN_SUCCESS
)
947 result
= thread_create_shuttle(act
, -1, thread_bootstrap_return
, &thread
);
948 if (result
!= KERN_SUCCESS
) {
954 result
= act_machine_set_state(act
, flavor
, new_state
, new_state_count
);
955 if (result
!= KERN_SUCCESS
) {
957 pset_unlock(task
->processor_set
);
960 (void)thread_terminate(act
);
964 clear_wait(thread
, THREAD_AWAKENED
);
967 pset_unlock(task
->processor_set
);
978 * Create and kernel thread in the specified task, and
979 * optionally start it running.
982 kernel_thread_with_priority(
986 boolean_t alloc_stack
,
987 boolean_t start_running
)
989 kern_return_t result
;
993 result
= act_create(task
, &act
);
994 if (result
!= KERN_SUCCESS
)
995 return (THREAD_NULL
);
997 result
= thread_create_shuttle(act
, priority
, start
, &thread
);
998 if (result
!= KERN_SUCCESS
) {
1000 return (THREAD_NULL
);
1003 pset_unlock(task
->processor_set
);
1007 thread_doswapin(thread
);
1011 clear_wait(thread
, THREAD_AWAKENED
);
1015 act_deallocate(act
);
1023 void (*start
)(void))
1025 return kernel_thread_with_priority(task
, -1, start
, FALSE
, TRUE
);
1028 unsigned int c_weird_pset_ref_exit
= 0; /* pset code raced us */
1031 /* Preclude thread processor set assignement */
1032 #define thread_freeze(thread) assert((thread)->processor_set == &default_pset)
1034 /* Allow thread processor set assignement */
1035 #define thread_unfreeze(thread) assert((thread)->processor_set == &default_pset)
1037 #endif /* MACH_HOST */
1044 processor_set_t pset
;
1048 if (thread
== THREAD_NULL
)
1052 * First, check for new count > 0 (the common case).
1053 * Only the thread needs to be locked.
1056 thread_lock(thread
);
1057 refs
= --thread
->ref_count
;
1058 thread_unlock(thread
);
1064 if (thread
== current_thread())
1065 panic("thread deallocating itself");
1068 * There is a dangling pointer to the thread from the
1069 * processor_set. To clean it up, we freeze the thread
1070 * in the pset (because pset destruction can cause even
1071 * reference-less threads to be reassigned to the default
1072 * pset) and then remove it.
1076 thread_freeze(thread
);
1079 pset
= thread
->processor_set
;
1081 pset_remove_thread(pset
, thread
);
1085 thread_unfreeze(thread
);
1088 pset_deallocate(pset
);
1090 if (thread
->stack_privilege
!= 0) {
1091 if (thread
->stack_privilege
!= thread
->kernel_stack
)
1092 stack_free_stack(thread
->stack_privilege
);
1093 thread
->stack_privilege
= 0;
1095 /* frees kernel stack & other MD resources */
1096 thread_machine_destroy(thread
);
1098 zfree(thread_shuttle_zone
, (vm_offset_t
) thread
);
1107 if (thread
== THREAD_NULL
)
1111 thread_lock(thread
);
1112 thread_reference_locked(thread
);
1113 thread_unlock(thread
);
1118 * Called with "appropriate" thread-related locks held on
1119 * thread and its top_act for synchrony with RPC (see
1120 * act_lock_thread()).
1123 thread_info_shuttle(
1124 register thread_act_t thr_act
,
1125 thread_flavor_t flavor
,
1126 thread_info_t thread_info_out
, /* ptr to OUT array */
1127 mach_msg_type_number_t
*thread_info_count
) /*IN/OUT*/
1129 register thread_t thread
= thr_act
->thread
;
1133 if (thread
== THREAD_NULL
)
1134 return (KERN_INVALID_ARGUMENT
);
1136 if (flavor
== THREAD_BASIC_INFO
) {
1137 register thread_basic_info_t basic_info
;
1139 if (*thread_info_count
< THREAD_BASIC_INFO_COUNT
)
1140 return (KERN_INVALID_ARGUMENT
);
1142 basic_info
= (thread_basic_info_t
) thread_info_out
;
1145 thread_lock(thread
);
1149 thread_read_times(thread
, &basic_info
->user_time
,
1150 &basic_info
->system_time
);
1153 * Update lazy-evaluated scheduler info because someone wants it.
1155 if (thread
->sched_stamp
!= sched_tick
)
1156 update_priority(thread
);
1158 basic_info
->sleep_time
= 0;
1161 * To calculate cpu_usage, first correct for timer rate,
1162 * then for 5/8 ageing. The correction factor [3/5] is
1165 basic_info
->cpu_usage
= (thread
->cpu_usage
<< SCHED_TICK_SHIFT
) /
1166 (TIMER_RATE
/ TH_USAGE_SCALE
);
1167 basic_info
->cpu_usage
= (basic_info
->cpu_usage
* 3) / 5;
1170 * Clock drift compensation.
1172 basic_info
->cpu_usage
= (basic_info
->cpu_usage
* 1000000) / sched_usec
;
1173 #endif /* SIMPLE_CLOCK */
1175 basic_info
->policy
= ((thread
->sched_mode
& TH_MODE_TIMESHARE
)?
1176 POLICY_TIMESHARE
: POLICY_RR
);
1179 if (thread
->state
& TH_IDLE
)
1180 flags
|= TH_FLAGS_IDLE
;
1182 if (thread
->state
& TH_STACK_HANDOFF
)
1183 flags
|= TH_FLAGS_SWAPPED
;
1186 if (thread
->state
& TH_TERMINATE
)
1187 state
= TH_STATE_HALTED
;
1189 if (thread
->state
& TH_RUN
)
1190 state
= TH_STATE_RUNNING
;
1192 if (thread
->state
& TH_UNINT
)
1193 state
= TH_STATE_UNINTERRUPTIBLE
;
1195 if (thread
->state
& TH_SUSP
)
1196 state
= TH_STATE_STOPPED
;
1198 if (thread
->state
& TH_WAIT
)
1199 state
= TH_STATE_WAITING
;
1201 basic_info
->run_state
= state
;
1202 basic_info
->flags
= flags
;
1204 basic_info
->suspend_count
= thr_act
->user_stop_count
;
1206 thread_unlock(thread
);
1209 *thread_info_count
= THREAD_BASIC_INFO_COUNT
;
1211 return (KERN_SUCCESS
);
1214 if (flavor
== THREAD_SCHED_TIMESHARE_INFO
) {
1215 policy_timeshare_info_t ts_info
;
1217 if (*thread_info_count
< POLICY_TIMESHARE_INFO_COUNT
)
1218 return (KERN_INVALID_ARGUMENT
);
1220 ts_info
= (policy_timeshare_info_t
)thread_info_out
;
1223 thread_lock(thread
);
1225 if (!(thread
->sched_mode
& TH_MODE_TIMESHARE
)) {
1226 thread_unlock(thread
);
1229 return (KERN_INVALID_POLICY
);
1232 ts_info
->depressed
= (thread
->sched_mode
& TH_MODE_ISDEPRESSED
) != 0;
1233 if (ts_info
->depressed
) {
1234 ts_info
->base_priority
= DEPRESSPRI
;
1235 ts_info
->depress_priority
= thread
->priority
;
1238 ts_info
->base_priority
= thread
->priority
;
1239 ts_info
->depress_priority
= -1;
1242 ts_info
->cur_priority
= thread
->sched_pri
;
1243 ts_info
->max_priority
= thread
->max_priority
;
1245 thread_unlock(thread
);
1248 *thread_info_count
= POLICY_TIMESHARE_INFO_COUNT
;
1250 return (KERN_SUCCESS
);
1253 if (flavor
== THREAD_SCHED_FIFO_INFO
) {
1254 if (*thread_info_count
< POLICY_FIFO_INFO_COUNT
)
1255 return (KERN_INVALID_ARGUMENT
);
1257 return (KERN_INVALID_POLICY
);
1260 if (flavor
== THREAD_SCHED_RR_INFO
) {
1261 policy_rr_info_t rr_info
;
1263 if (*thread_info_count
< POLICY_RR_INFO_COUNT
)
1264 return (KERN_INVALID_ARGUMENT
);
1266 rr_info
= (policy_rr_info_t
) thread_info_out
;
1269 thread_lock(thread
);
1271 if (thread
->sched_mode
& TH_MODE_TIMESHARE
) {
1272 thread_unlock(thread
);
1275 return (KERN_INVALID_POLICY
);
1278 rr_info
->depressed
= (thread
->sched_mode
& TH_MODE_ISDEPRESSED
) != 0;
1279 if (rr_info
->depressed
) {
1280 rr_info
->base_priority
= DEPRESSPRI
;
1281 rr_info
->depress_priority
= thread
->priority
;
1284 rr_info
->base_priority
= thread
->priority
;
1285 rr_info
->depress_priority
= -1;
1288 rr_info
->max_priority
= thread
->max_priority
;
1289 rr_info
->quantum
= std_quantum_us
/ 1000;
1291 thread_unlock(thread
);
1294 *thread_info_count
= POLICY_RR_INFO_COUNT
;
1296 return (KERN_SUCCESS
);
1299 return (KERN_INVALID_ARGUMENT
);
1304 register thread_t thread
)
1306 thread_act_t thr_act
;
1309 thr_act
= thread_lock_act(thread
);
1310 assert(thr_act
&& thr_act
->thread
== thread
);
1312 act_locked_act_reference(thr_act
);
1315 * Replace `act_unlock_thread()' with individual
1316 * calls. (`act_detach()' can change fields used
1317 * to determine which locks are held, confusing
1318 * `act_unlock_thread()'.)
1320 act_unlock(thr_act
);
1322 /* Remove the reference held by a rooted thread */
1323 act_deallocate(thr_act
);
1325 /* Remove the reference held by the thread: */
1326 act_deallocate(thr_act
);
1332 * This kernel thread runs forever looking for terminating
1333 * threads, releasing their "self" references.
1336 reaper_thread_continue(void)
1338 register thread_t thread
;
1341 simple_lock(&reaper_lock
);
1343 while ((thread
= (thread_t
) dequeue_head(&reaper_queue
)) != THREAD_NULL
) {
1344 simple_unlock(&reaper_lock
);
1347 thread_doreap(thread
);
1350 simple_lock(&reaper_lock
);
1353 assert_wait((event_t
)&reaper_queue
, THREAD_UNINT
);
1354 simple_unlock(&reaper_lock
);
1357 thread_block(reaper_thread_continue
);
1364 thread_t self
= current_thread();
1366 stack_privilege(self
);
1368 reaper_thread_continue();
1373 thread_reaper_init(void)
1375 kernel_thread(kernel_task
, reaper_thread
);
1380 thread_act_t thr_act
,
1381 processor_set_t new_pset
)
1383 return(KERN_FAILURE
);
1387 * thread_assign_default:
1389 * Special version of thread_assign for assigning threads to default
1393 thread_assign_default(
1394 thread_act_t thr_act
)
1396 return (thread_assign(thr_act
, &default_pset
));
1400 * thread_get_assignment
1402 * Return current assignment for this thread.
1405 thread_get_assignment(
1406 thread_act_t thr_act
,
1407 processor_set_t
*pset
)
1411 if (thr_act
== THR_ACT_NULL
)
1412 return(KERN_INVALID_ARGUMENT
);
1413 thread
= act_lock_thread(thr_act
);
1414 if (thread
== THREAD_NULL
) {
1415 act_unlock_thread(thr_act
);
1416 return(KERN_INVALID_ARGUMENT
);
1418 *pset
= thread
->processor_set
;
1419 act_unlock_thread(thr_act
);
1420 pset_reference(*pset
);
1421 return(KERN_SUCCESS
);
1427 * Specify that the target thread must always be able
1428 * to run and to allocate memory.
1432 host_priv_t host_priv
,
1433 thread_act_t thr_act
,
1438 extern void vm_page_free_reserve(int pages
);
1440 if (thr_act
== THR_ACT_NULL
|| host_priv
== HOST_PRIV_NULL
)
1441 return (KERN_INVALID_ARGUMENT
);
1443 assert(host_priv
== &realhost
);
1445 thread
= act_lock_thread(thr_act
);
1446 if (thread
==THREAD_NULL
) {
1447 act_unlock_thread(thr_act
);
1448 return(KERN_INVALID_ARGUMENT
);
1452 * This implementation only works for the current thread.
1453 * See stack_privilege.
1455 if (thr_act
!= current_act())
1456 return KERN_INVALID_ARGUMENT
;
1459 thread_lock(thread
);
1462 if (thread
->vm_privilege
== FALSE
)
1463 vm_page_free_reserve(1); /* XXX */
1464 thread
->vm_privilege
= TRUE
;
1466 if (thread
->vm_privilege
== TRUE
)
1467 vm_page_free_reserve(-1); /* XXX */
1468 thread
->vm_privilege
= FALSE
;
1471 thread_unlock(thread
);
1473 act_unlock_thread(thr_act
);
1475 return KERN_SUCCESS
;
1479 * thread_collect_scan:
1481 * Attempt to free resources owned by threads.
1485 thread_collect_scan(void)
1487 /* This code runs very quickly! */
1490 /* Also disabled in vm/vm_pageout.c */
1491 boolean_t thread_collect_allowed
= FALSE
;
1492 unsigned thread_collect_last_tick
= 0;
1493 unsigned thread_collect_max_rate
= 0; /* in ticks */
1496 * consider_thread_collect:
1498 * Called by the pageout daemon when the system needs more free pages.
1502 consider_thread_collect(void)
1505 * By default, don't attempt thread collection more frequently
1506 * than once a second.
1509 if (thread_collect_max_rate
== 0)
1510 thread_collect_max_rate
= (1 << SCHED_TICK_SHIFT
) + 1;
1512 if (thread_collect_allowed
&&
1514 (thread_collect_last_tick
+ thread_collect_max_rate
))) {
1515 thread_collect_last_tick
= sched_tick
;
1516 thread_collect_scan();
1523 vm_size_t
*reservedp
,
1524 unsigned int *totalp
,
1526 vm_size_t
*residentp
,
1527 vm_size_t
*maxusagep
,
1528 vm_offset_t
*maxstackp
)
1531 return KERN_NOT_SUPPORTED
;
1536 if (host
== HOST_NULL
)
1537 return KERN_INVALID_HOST
;
1541 stack_statistics(&total
, &maxusage
);
1545 *spacep
= *residentp
= total
* round_page(KERNEL_STACK_SIZE
);
1546 *maxusagep
= maxusage
;
1548 return KERN_SUCCESS
;
1550 #endif /* MACH_DEBUG */
1554 * Return info on stack usage for threads in a specific processor set
1557 processor_set_stack_usage(
1558 processor_set_t pset
,
1559 unsigned int *totalp
,
1561 vm_size_t
*residentp
,
1562 vm_size_t
*maxusagep
,
1563 vm_offset_t
*maxstackp
)
1566 return KERN_NOT_SUPPORTED
;
1570 vm_offset_t maxstack
;
1572 register thread_t
*threads
;
1573 register thread_t thread
;
1575 unsigned int actual
; /* this many things */
1578 vm_size_t size
, size_needed
;
1583 if (pset
== PROCESSOR_SET_NULL
)
1584 return KERN_INVALID_ARGUMENT
;
1590 if (!pset
->active
) {
1592 return KERN_INVALID_ARGUMENT
;
1595 actual
= pset
->thread_count
;
1597 /* do we have the memory we need? */
1599 size_needed
= actual
* sizeof(thread_t
);
1600 if (size_needed
<= size
)
1603 /* unlock the pset and allocate more memory */
1609 assert(size_needed
> 0);
1612 addr
= kalloc(size
);
1614 return KERN_RESOURCE_SHORTAGE
;
1617 /* OK, have memory and the processor_set is locked & active */
1619 threads
= (thread_t
*) addr
;
1620 for (i
= 0, thread
= (thread_t
) queue_first(&pset
->threads
);
1621 !queue_end(&pset
->threads
, (queue_entry_t
) thread
);
1622 thread
= (thread_t
) queue_next(&thread
->pset_threads
)) {
1623 thread_lock(thread
);
1624 if (thread
->ref_count
> 0) {
1625 thread_reference_locked(thread
);
1626 threads
[i
++] = thread
;
1628 thread_unlock(thread
);
1631 assert(i
<= actual
);
1633 /* can unlock processor set now that we have the thread refs */
1636 /* calculate maxusage and free thread references */
1643 thread_t thread
= threads
[--i
];
1644 vm_offset_t stack
= 0;
1647 * thread->kernel_stack is only accurate if the
1648 * thread isn't swapped and is not executing.
1650 * Of course, we don't have the appropriate locks
1651 * for these shenanigans.
1654 stack
= thread
->kernel_stack
;
1656 for (cpu
= 0; cpu
< NCPUS
; cpu
++)
1657 if (cpu_to_processor(cpu
)->cpu_data
->active_thread
== thread
) {
1658 stack
= active_stacks
[cpu
];
1666 thread_deallocate(thread
);
1673 *residentp
= *spacep
= total
* round_page(KERNEL_STACK_SIZE
);
1674 *maxusagep
= maxusage
;
1675 *maxstackp
= maxstack
;
1676 return KERN_SUCCESS
;
1678 #endif /* MACH_DEBUG */
1681 int split_funnel_off
= 0;
1688 if ((fnl
= (funnel_t
*)kalloc(sizeof(funnel_t
))) != 0){
1689 bzero((void *)fnl
, sizeof(funnel_t
));
1690 if ((m
= mutex_alloc(0)) == (mutex_t
*)NULL
) {
1691 kfree((vm_offset_t
)fnl
, sizeof(funnel_t
));
1692 return(THR_FUNNEL_NULL
);
1695 fnl
->fnl_type
= type
;
1704 mutex_free(fnl
->fnl_mutex
);
1705 if (fnl
->fnl_oldmutex
)
1706 mutex_free(fnl
->fnl_oldmutex
);
1707 kfree((vm_offset_t
)fnl
, sizeof(funnel_t
));
1719 fnl
->fnl_mtxholder
= current_thread();
1720 if (split_funnel_off
&& (m
!= fnl
->fnl_mutex
)) {
1731 mutex_unlock(fnl
->fnl_mutex
);
1732 fnl
->fnl_mtxrelease
= current_thread();
1739 thread_t th
= current_thread();
1741 if (th
->funnel_state
& TH_FN_OWNED
) {
1742 return(th
->funnel_lock
);
1744 return(THR_FUNNEL_NULL
);
1752 thread_t cur_thread
;
1753 boolean_t funnel_state_prev
;
1756 cur_thread
= current_thread();
1757 funnel_state_prev
= ((cur_thread
->funnel_state
& TH_FN_OWNED
) == TH_FN_OWNED
);
1759 if (funnel_state_prev
!= funneled
) {
1760 intr
= ml_set_interrupts_enabled(FALSE
);
1762 if (funneled
== TRUE
) {
1763 if (cur_thread
->funnel_lock
)
1764 panic("Funnel lock called when holding one %x", cur_thread
->funnel_lock
);
1765 KERNEL_DEBUG(0x6032428 | DBG_FUNC_NONE
,
1768 KERNEL_DEBUG(0x6032434 | DBG_FUNC_NONE
,
1770 cur_thread
->funnel_state
|= TH_FN_OWNED
;
1771 cur_thread
->funnel_lock
= fnl
;
1773 if(cur_thread
->funnel_lock
->fnl_mutex
!= fnl
->fnl_mutex
)
1774 panic("Funnel unlock when not holding funnel");
1775 cur_thread
->funnel_state
&= ~TH_FN_OWNED
;
1776 KERNEL_DEBUG(0x603242c | DBG_FUNC_NONE
,
1779 cur_thread
->funnel_lock
= THR_FUNNEL_NULL
;
1782 (void)ml_set_interrupts_enabled(intr
);
1784 /* if we are trying to acquire funnel recursively
1785 * check for funnel to be held already
1787 if (funneled
&& (fnl
->fnl_mutex
!= cur_thread
->funnel_lock
->fnl_mutex
)) {
1788 panic("thread_funnel_set: already holding a different funnel");
1791 return(funnel_state_prev
);
1795 thread_funnel_merge(
1797 funnel_t
* otherfnl
)
1802 extern int disable_funnel
;
1804 if ((gfnl
= thread_funnel_get()) == THR_FUNNEL_NULL
)
1805 panic("thread_funnel_merge called with no funnels held");
1807 if (gfnl
->fnl_type
!= 1)
1808 panic("thread_funnel_merge called from non kernel funnel");
1811 panic("thread_funnel_merge incorrect invocation");
1813 if (disable_funnel
|| split_funnel_off
)
1814 return (KERN_FAILURE
);
1817 otherm
= otherfnl
->fnl_mutex
;
1819 /* Acquire other funnel mutex */
1821 split_funnel_off
= 1;
1823 otherfnl
->fnl_mutex
= m
;
1824 otherfnl
->fnl_type
= fnl
->fnl_type
;
1825 otherfnl
->fnl_oldmutex
= otherm
; /* save this for future use */
1827 mutex_unlock(otherm
);
1828 return(KERN_SUCCESS
);
1832 thread_set_cont_arg(
1835 thread_t self
= current_thread();
1837 self
->saved
.misc
= arg
;
1841 thread_get_cont_arg(void)
1843 thread_t self
= current_thread();
1845 return (self
->saved
.misc
);
1849 * Export routines to other components for things that are done as macros
1850 * within the osfmk component.
1852 #undef thread_should_halt
1855 thread_shuttle_t th
)
1857 return(thread_should_halt_fast(th
));