2 * Copyright (c) 2000-2010 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 * @OSF_FREE_COPYRIGHT@
32 * Mach Operating System
33 * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
34 * All Rights Reserved.
36 * Permission to use, copy, modify and distribute this software and its
37 * documentation is hereby granted, provided that both the copyright
38 * notice and this permission notice appear in all copies of the
39 * software, derivative works or modified versions, and any portions
40 * thereof, and that both notices appear in supporting documentation.
42 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
43 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
44 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
46 * Carnegie Mellon requests users of this software to return to
48 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
49 * School of Computer Science
50 * Carnegie Mellon University
51 * Pittsburgh PA 15213-3890
53 * any improvements or extensions that they make and grant Carnegie Mellon
54 * the rights to redistribute these changes.
60 * Author: Avadis Tevanian, Jr.
63 * Scheduling primitives
69 #include <mach/mach_types.h>
70 #include <mach/machine.h>
71 #include <mach/policy.h>
72 #include <mach/sync_policy.h>
73 #include <mach/thread_act.h>
75 #include <machine/machine_routines.h>
76 #include <machine/sched_param.h>
77 #include <machine/machine_cpu.h>
78 #include <machine/machlimits.h>
80 #include <kern/kern_types.h>
81 #include <kern/clock.h>
82 #include <kern/counters.h>
83 #include <kern/cpu_number.h>
84 #include <kern/cpu_data.h>
85 #include <kern/debug.h>
86 #include <kern/lock.h>
87 #include <kern/macro_help.h>
88 #include <kern/machine.h>
89 #include <kern/misc_protos.h>
90 #include <kern/processor.h>
91 #include <kern/queue.h>
92 #include <kern/sched.h>
93 #include <kern/sched_prim.h>
94 #include <kern/syscall_subr.h>
95 #include <kern/task.h>
96 #include <kern/thread.h>
97 #include <kern/wait_queue.h>
98 #include <kern/ledger.h>
101 #include <vm/vm_kern.h>
102 #include <vm/vm_map.h>
104 #include <mach/sdt.h>
106 #include <sys/kdebug.h>
108 #include <kern/pms.h>
110 struct rt_queue rt_runq
;
111 #define RT_RUNQ ((processor_t)-1)
112 decl_simple_lock_data(static,rt_lock
);
114 #if defined(CONFIG_SCHED_TRADITIONAL) || defined(CONFIG_SCHED_PROTO) || defined(CONFIG_SCHED_GRRR) || defined(CONFIG_SCHED_FIXEDPRIORITY)
115 static struct fairshare_queue fs_runq
;
116 #define FS_RUNQ ((processor_t)-2)
117 decl_simple_lock_data(static,fs_lock
);
120 #define DEFAULT_PREEMPTION_RATE 100 /* (1/s) */
121 int default_preemption_rate
= DEFAULT_PREEMPTION_RATE
;
123 #define DEFAULT_BG_PREEMPTION_RATE 400 /* (1/s) */
124 int default_bg_preemption_rate
= DEFAULT_BG_PREEMPTION_RATE
;
126 #define MAX_UNSAFE_QUANTA 800
127 int max_unsafe_quanta
= MAX_UNSAFE_QUANTA
;
129 #define MAX_POLL_QUANTA 2
130 int max_poll_quanta
= MAX_POLL_QUANTA
;
132 #define SCHED_POLL_YIELD_SHIFT 4 /* 1/16 */
133 int sched_poll_yield_shift
= SCHED_POLL_YIELD_SHIFT
;
135 uint64_t max_poll_computation
;
137 uint64_t max_unsafe_computation
;
138 uint64_t sched_safe_duration
;
140 #if defined(CONFIG_SCHED_TRADITIONAL)
142 uint32_t std_quantum
;
143 uint32_t min_std_quantum
;
146 uint32_t std_quantum_us
;
147 uint32_t bg_quantum_us
;
149 #endif /* CONFIG_SCHED_TRADITIONAL */
151 uint32_t thread_depress_time
;
152 uint32_t default_timeshare_computation
;
153 uint32_t default_timeshare_constraint
;
155 uint32_t max_rt_quantum
;
156 uint32_t min_rt_quantum
;
158 #if defined(CONFIG_SCHED_TRADITIONAL)
161 uint32_t sched_tick_interval
;
163 uint32_t sched_pri_shift
= INT8_MAX
;
164 uint32_t sched_fixed_shift
;
166 static boolean_t sched_traditional_use_pset_runqueue
= FALSE
;
168 /* Defaults for timer deadline profiling */
169 #define TIMER_DEADLINE_TRACKING_BIN_1_DEFAULT 2000000 /* Timers with deadlines <=
171 #define TIMER_DEADLINE_TRACKING_BIN_2_DEFAULT 5000000 /* Timers with deadlines
173 uint64_t timer_deadline_tracking_bin_1
;
174 uint64_t timer_deadline_tracking_bin_2
;
176 __attribute__((always_inline
))
177 static inline run_queue_t
runq_for_processor(processor_t processor
)
179 if (sched_traditional_use_pset_runqueue
)
180 return &processor
->processor_set
->pset_runq
;
182 return &processor
->runq
;
185 __attribute__((always_inline
))
186 static inline void runq_consider_incr_bound_count(processor_t processor
, thread_t thread
)
188 if (thread
->bound_processor
== PROCESSOR_NULL
)
191 assert(thread
->bound_processor
== processor
);
193 if (sched_traditional_use_pset_runqueue
)
194 processor
->processor_set
->pset_runq_bound_count
++;
196 processor
->runq_bound_count
++;
199 __attribute__((always_inline
))
200 static inline void runq_consider_decr_bound_count(processor_t processor
, thread_t thread
)
202 if (thread
->bound_processor
== PROCESSOR_NULL
)
205 assert(thread
->bound_processor
== processor
);
207 if (sched_traditional_use_pset_runqueue
)
208 processor
->processor_set
->pset_runq_bound_count
--;
210 processor
->runq_bound_count
--;
213 #endif /* CONFIG_SCHED_TRADITIONAL */
215 uint64_t sched_one_second_interval
;
217 uint32_t sched_run_count
, sched_share_count
;
218 uint32_t sched_load_average
, sched_mach_factor
;
222 #if defined(CONFIG_SCHED_TRADITIONAL)
224 static void load_shift_init(void) __attribute__((section("__TEXT, initcode")));
225 static void preempt_pri_init(void) __attribute__((section("__TEXT, initcode")));
227 #endif /* CONFIG_SCHED_TRADITIONAL */
229 static thread_t
thread_select(
231 processor_t processor
);
233 #if CONFIG_SCHED_IDLE_IN_PLACE
234 static thread_t
thread_select_idle(
236 processor_t processor
);
239 thread_t
processor_idle(
241 processor_t processor
);
243 #if defined(CONFIG_SCHED_TRADITIONAL)
245 static thread_t
steal_thread(
246 processor_set_t pset
);
248 static thread_t
steal_thread_disabled(
249 processor_set_t pset
) __attribute__((unused
));
252 static thread_t
steal_processor_thread(
253 processor_t processor
);
255 static void thread_update_scan(void);
257 static void processor_setrun(
258 processor_t processor
,
264 processor_t processor
,
269 processor_queue_remove(
270 processor_t processor
,
273 static boolean_t
processor_queue_empty(processor_t processor
);
275 static boolean_t
priority_is_urgent(int priority
);
277 static ast_t
processor_csw_check(processor_t processor
);
279 static boolean_t
processor_queue_has_priority(processor_t processor
,
283 static boolean_t
should_current_thread_rechoose_processor(processor_t processor
);
285 static int sched_traditional_processor_runq_count(processor_t processor
);
287 static boolean_t
sched_traditional_with_pset_runqueue_processor_queue_empty(processor_t processor
);
289 static uint64_t sched_traditional_processor_runq_stats_count_sum(processor_t processor
);
291 static uint64_t sched_traditional_with_pset_runqueue_processor_runq_stats_count_sum(processor_t processor
);
295 #if defined(CONFIG_SCHED_TRADITIONAL)
298 sched_traditional_init(void);
301 sched_traditional_timebase_init(void);
304 sched_traditional_processor_init(processor_t processor
);
307 sched_traditional_pset_init(processor_set_t pset
);
310 sched_traditional_with_pset_runqueue_init(void);
315 sched_realtime_init(void) __attribute__((section("__TEXT, initcode")));
318 sched_realtime_timebase_init(void);
321 sched_timer_deadline_tracking_init(void);
323 #if defined(CONFIG_SCHED_TRADITIONAL)
325 sched_traditional_tick_continue(void);
328 sched_traditional_initial_quantum_size(thread_t thread
);
331 sched_traditional_initial_thread_sched_mode(task_t parent_task
);
334 sched_traditional_supports_timeshare_mode(void);
337 sched_traditional_choose_thread(
338 processor_t processor
,
344 extern int debug_task
;
345 #define TLOG(a, fmt, args...) if(debug_task & a) kprintf(fmt, ## args)
347 #define TLOG(a, fmt, args...) do {} while (0)
352 boolean_t
thread_runnable(
360 * states are combinations of:
362 * W waiting (or on wait queue)
363 * N non-interruptible
368 * assert_wait thread_block clear_wait swapout swapin
370 * R RW, RWN R; setrun - -
371 * RN RWN RN; setrun - -
383 #if defined(CONFIG_SCHED_TRADITIONAL)
384 int8_t sched_load_shifts
[NRQS
];
385 int sched_preempt_pri
[NRQBM
];
389 #if defined(CONFIG_SCHED_TRADITIONAL)
391 const struct sched_dispatch_table sched_traditional_dispatch
= {
392 sched_traditional_init
,
393 sched_traditional_timebase_init
,
394 sched_traditional_processor_init
,
395 sched_traditional_pset_init
,
396 sched_traditional_tick_continue
,
397 sched_traditional_choose_thread
,
402 processor_queue_shutdown
,
403 processor_queue_remove
,
404 processor_queue_empty
,
407 processor_queue_has_priority
,
408 sched_traditional_initial_quantum_size
,
409 sched_traditional_initial_thread_sched_mode
,
410 sched_traditional_supports_timeshare_mode
,
413 lightweight_update_priority
,
414 sched_traditional_quantum_expire
,
415 should_current_thread_rechoose_processor
,
416 sched_traditional_processor_runq_count
,
417 sched_traditional_processor_runq_stats_count_sum
,
418 sched_traditional_fairshare_init
,
419 sched_traditional_fairshare_runq_count
,
420 sched_traditional_fairshare_runq_stats_count_sum
,
421 sched_traditional_fairshare_enqueue
,
422 sched_traditional_fairshare_dequeue
,
423 sched_traditional_fairshare_queue_remove
,
424 TRUE
/* direct_dispatch_to_idle_processors */
427 const struct sched_dispatch_table sched_traditional_with_pset_runqueue_dispatch
= {
428 sched_traditional_with_pset_runqueue_init
,
429 sched_traditional_timebase_init
,
430 sched_traditional_processor_init
,
431 sched_traditional_pset_init
,
432 sched_traditional_tick_continue
,
433 sched_traditional_choose_thread
,
438 processor_queue_shutdown
,
439 processor_queue_remove
,
440 sched_traditional_with_pset_runqueue_processor_queue_empty
,
443 processor_queue_has_priority
,
444 sched_traditional_initial_quantum_size
,
445 sched_traditional_initial_thread_sched_mode
,
446 sched_traditional_supports_timeshare_mode
,
449 lightweight_update_priority
,
450 sched_traditional_quantum_expire
,
451 should_current_thread_rechoose_processor
,
452 sched_traditional_processor_runq_count
,
453 sched_traditional_with_pset_runqueue_processor_runq_stats_count_sum
,
454 sched_traditional_fairshare_init
,
455 sched_traditional_fairshare_runq_count
,
456 sched_traditional_fairshare_runq_stats_count_sum
,
457 sched_traditional_fairshare_enqueue
,
458 sched_traditional_fairshare_dequeue
,
459 sched_traditional_fairshare_queue_remove
,
460 FALSE
/* direct_dispatch_to_idle_processors */
465 const struct sched_dispatch_table
*sched_current_dispatch
= NULL
;
468 * Statically allocate a buffer to hold the longest possible
469 * scheduler description string, as currently implemented.
470 * bsd/kern/kern_sysctl.c has a corresponding definition in bsd/
471 * to export to userspace via sysctl(3). If either version
472 * changes, update the other.
474 * Note that in addition to being an upper bound on the strings
475 * in the kernel, it's also an exact parameter to PE_get_default(),
476 * which interrogates the device tree on some platforms. That
477 * API requires the caller know the exact size of the device tree
478 * property, so we need both a legacy size (32) and the current size
479 * (48) to deal with old and new device trees. The device tree property
480 * is similarly padded to a fixed size so that the same kernel image
481 * can run on multiple devices with different schedulers configured
482 * in the device tree.
484 #define SCHED_STRING_MAX_LENGTH (48)
486 char sched_string
[SCHED_STRING_MAX_LENGTH
];
487 static enum sched_enum _sched_enum
= sched_enum_unknown
;
492 char sched_arg
[SCHED_STRING_MAX_LENGTH
] = { '\0' };
494 /* Check for runtime selection of the scheduler algorithm */
495 if (!PE_parse_boot_argn("sched", sched_arg
, sizeof (sched_arg
))) {
496 /* If no boot-args override, look in device tree */
497 if (!PE_get_default("kern.sched", sched_arg
,
498 SCHED_STRING_MAX_LENGTH
)) {
503 if (strlen(sched_arg
) > 0) {
505 /* Allow pattern below */
506 #if defined(CONFIG_SCHED_TRADITIONAL)
507 } else if (0 == strcmp(sched_arg
, kSchedTraditionalString
)) {
508 sched_current_dispatch
= &sched_traditional_dispatch
;
509 _sched_enum
= sched_enum_traditional
;
510 strlcpy(sched_string
, kSchedTraditionalString
, sizeof(sched_string
));
511 kprintf("Scheduler: Runtime selection of %s\n", kSchedTraditionalString
);
512 } else if (0 == strcmp(sched_arg
, kSchedTraditionalWithPsetRunqueueString
)) {
513 sched_current_dispatch
= &sched_traditional_with_pset_runqueue_dispatch
;
514 _sched_enum
= sched_enum_traditional_with_pset_runqueue
;
515 strlcpy(sched_string
, kSchedTraditionalWithPsetRunqueueString
, sizeof(sched_string
));
516 kprintf("Scheduler: Runtime selection of %s\n", kSchedTraditionalWithPsetRunqueueString
);
518 #if defined(CONFIG_SCHED_PROTO)
519 } else if (0 == strcmp(sched_arg
, kSchedProtoString
)) {
520 sched_current_dispatch
= &sched_proto_dispatch
;
521 _sched_enum
= sched_enum_proto
;
522 strlcpy(sched_string
, kSchedProtoString
, sizeof(sched_string
));
523 kprintf("Scheduler: Runtime selection of %s\n", kSchedProtoString
);
525 #if defined(CONFIG_SCHED_GRRR)
526 } else if (0 == strcmp(sched_arg
, kSchedGRRRString
)) {
527 sched_current_dispatch
= &sched_grrr_dispatch
;
528 _sched_enum
= sched_enum_grrr
;
529 strlcpy(sched_string
, kSchedGRRRString
, sizeof(sched_string
));
530 kprintf("Scheduler: Runtime selection of %s\n", kSchedGRRRString
);
532 #if defined(CONFIG_SCHED_FIXEDPRIORITY)
533 } else if (0 == strcmp(sched_arg
, kSchedFixedPriorityString
)) {
534 sched_current_dispatch
= &sched_fixedpriority_dispatch
;
535 _sched_enum
= sched_enum_fixedpriority
;
536 strlcpy(sched_string
, kSchedFixedPriorityString
, sizeof(sched_string
));
537 kprintf("Scheduler: Runtime selection of %s\n", kSchedFixedPriorityString
);
538 } else if (0 == strcmp(sched_arg
, kSchedFixedPriorityWithPsetRunqueueString
)) {
539 sched_current_dispatch
= &sched_fixedpriority_with_pset_runqueue_dispatch
;
540 _sched_enum
= sched_enum_fixedpriority_with_pset_runqueue
;
541 strlcpy(sched_string
, kSchedFixedPriorityWithPsetRunqueueString
, sizeof(sched_string
));
542 kprintf("Scheduler: Runtime selection of %s\n", kSchedFixedPriorityWithPsetRunqueueString
);
545 panic("Unrecognized scheduler algorithm: %s", sched_arg
);
548 #if defined(CONFIG_SCHED_TRADITIONAL)
549 sched_current_dispatch
= &sched_traditional_dispatch
;
550 _sched_enum
= sched_enum_traditional
;
551 strlcpy(sched_string
, kSchedTraditionalString
, sizeof(sched_string
));
552 kprintf("Scheduler: Default of %s\n", kSchedTraditionalString
);
553 #elif defined(CONFIG_SCHED_PROTO)
554 sched_current_dispatch
= &sched_proto_dispatch
;
555 _sched_enum
= sched_enum_proto
;
556 strlcpy(sched_string
, kSchedProtoString
, sizeof(sched_string
));
557 kprintf("Scheduler: Default of %s\n", kSchedProtoString
);
558 #elif defined(CONFIG_SCHED_GRRR)
559 sched_current_dispatch
= &sched_grrr_dispatch
;
560 _sched_enum
= sched_enum_grrr
;
561 strlcpy(sched_string
, kSchedGRRRString
, sizeof(sched_string
));
562 kprintf("Scheduler: Default of %s\n", kSchedGRRRString
);
563 #elif defined(CONFIG_SCHED_FIXEDPRIORITY)
564 sched_current_dispatch
= &sched_fixedpriority_dispatch
;
565 _sched_enum
= sched_enum_fixedpriority
;
566 strlcpy(sched_string
, kSchedFixedPriorityString
, sizeof(sched_string
));
567 kprintf("Scheduler: Default of %s\n", kSchedFixedPriorityString
);
569 #error No default scheduler implementation
574 SCHED(fairshare_init
)();
575 sched_realtime_init();
577 sched_timer_deadline_tracking_init();
579 SCHED(pset_init
)(&pset0
);
580 SCHED(processor_init
)(master_processor
);
584 sched_timebase_init(void)
588 clock_interval_to_absolutetime_interval(1, NSEC_PER_SEC
, &abstime
);
589 sched_one_second_interval
= abstime
;
591 SCHED(timebase_init
)();
592 sched_realtime_timebase_init();
595 #if defined(CONFIG_SCHED_TRADITIONAL)
598 sched_traditional_init(void)
601 * Calculate the timeslicing quantum
604 if (default_preemption_rate
< 1)
605 default_preemption_rate
= DEFAULT_PREEMPTION_RATE
;
606 std_quantum_us
= (1000 * 1000) / default_preemption_rate
;
608 printf("standard timeslicing quantum is %d us\n", std_quantum_us
);
610 if (default_bg_preemption_rate
< 1)
611 default_bg_preemption_rate
= DEFAULT_BG_PREEMPTION_RATE
;
612 bg_quantum_us
= (1000 * 1000) / default_bg_preemption_rate
;
614 printf("standard background quantum is %d us\n", bg_quantum_us
);
622 sched_traditional_timebase_init(void)
627 /* standard timeslicing quantum */
628 clock_interval_to_absolutetime_interval(
629 std_quantum_us
, NSEC_PER_USEC
, &abstime
);
630 assert((abstime
>> 32) == 0 && (uint32_t)abstime
!= 0);
631 std_quantum
= (uint32_t)abstime
;
633 /* smallest remaining quantum (250 us) */
634 clock_interval_to_absolutetime_interval(250, NSEC_PER_USEC
, &abstime
);
635 assert((abstime
>> 32) == 0 && (uint32_t)abstime
!= 0);
636 min_std_quantum
= (uint32_t)abstime
;
638 /* quantum for background tasks */
639 clock_interval_to_absolutetime_interval(
640 bg_quantum_us
, NSEC_PER_USEC
, &abstime
);
641 assert((abstime
>> 32) == 0 && (uint32_t)abstime
!= 0);
642 bg_quantum
= (uint32_t)abstime
;
644 /* scheduler tick interval */
645 clock_interval_to_absolutetime_interval(USEC_PER_SEC
>> SCHED_TICK_SHIFT
,
646 NSEC_PER_USEC
, &abstime
);
647 assert((abstime
>> 32) == 0 && (uint32_t)abstime
!= 0);
648 sched_tick_interval
= (uint32_t)abstime
;
651 * Compute conversion factor from usage to
652 * timesharing priorities with 5/8 ** n aging.
654 abstime
= (abstime
* 5) / 3;
655 for (shift
= 0; abstime
> BASEPRI_DEFAULT
; ++shift
)
657 sched_fixed_shift
= shift
;
659 max_unsafe_computation
= max_unsafe_quanta
* std_quantum
;
660 sched_safe_duration
= 2 * max_unsafe_quanta
* std_quantum
;
662 max_poll_computation
= max_poll_quanta
* std_quantum
;
663 thread_depress_time
= 1 * std_quantum
;
664 default_timeshare_computation
= std_quantum
/ 2;
665 default_timeshare_constraint
= std_quantum
;
670 sched_traditional_processor_init(processor_t processor
)
672 if (!sched_traditional_use_pset_runqueue
) {
673 run_queue_init(&processor
->runq
);
675 processor
->runq_bound_count
= 0;
679 sched_traditional_pset_init(processor_set_t pset
)
681 if (sched_traditional_use_pset_runqueue
) {
682 run_queue_init(&pset
->pset_runq
);
684 pset
->pset_runq_bound_count
= 0;
688 sched_traditional_with_pset_runqueue_init(void)
690 sched_traditional_init();
691 sched_traditional_use_pset_runqueue
= TRUE
;
694 #endif /* CONFIG_SCHED_TRADITIONAL */
696 #if defined(CONFIG_SCHED_TRADITIONAL) || defined(CONFIG_SCHED_PROTO) || defined(CONFIG_SCHED_GRRR) || defined(CONFIG_SCHED_FIXEDPRIORITY)
698 sched_traditional_fairshare_init(void)
700 simple_lock_init(&fs_lock
, 0);
703 queue_init(&fs_runq
.queue
);
708 sched_realtime_init(void)
710 simple_lock_init(&rt_lock
, 0);
713 queue_init(&rt_runq
.queue
);
717 sched_realtime_timebase_init(void)
721 /* smallest rt computaton (50 us) */
722 clock_interval_to_absolutetime_interval(50, NSEC_PER_USEC
, &abstime
);
723 assert((abstime
>> 32) == 0 && (uint32_t)abstime
!= 0);
724 min_rt_quantum
= (uint32_t)abstime
;
726 /* maximum rt computation (50 ms) */
727 clock_interval_to_absolutetime_interval(
728 50, 1000*NSEC_PER_USEC
, &abstime
);
729 assert((abstime
>> 32) == 0 && (uint32_t)abstime
!= 0);
730 max_rt_quantum
= (uint32_t)abstime
;
734 #if defined(CONFIG_SCHED_TRADITIONAL)
737 * Set up values for timeshare
741 load_shift_init(void)
743 int8_t k
, *p
= sched_load_shifts
;
746 *p
++ = INT8_MIN
; *p
++ = 0;
748 for (i
= j
= 2, k
= 1; i
< NRQS
; ++k
) {
749 for (j
<<= 1; i
< j
; ++i
)
755 preempt_pri_init(void)
757 int i
, *p
= sched_preempt_pri
;
759 for (i
= BASEPRI_FOREGROUND
+ 1; i
< MINPRI_KERNEL
; ++i
)
762 for (i
= BASEPRI_PREEMPT
; i
<= MAXPRI
; ++i
)
766 #endif /* CONFIG_SCHED_TRADITIONAL */
769 * Thread wait timer expiration.
776 thread_t thread
= p0
;
781 if (--thread
->wait_timer_active
== 0) {
782 if (thread
->wait_timer_is_set
) {
783 thread
->wait_timer_is_set
= FALSE
;
784 clear_wait_internal(thread
, THREAD_TIMED_OUT
);
787 thread_unlock(thread
);
796 * Set a timer for the current thread, if the thread
797 * is ready to wait. Must be called between assert_wait()
798 * and thread_block().
803 uint32_t scale_factor
)
805 thread_t thread
= current_thread();
811 if ((thread
->state
& TH_WAIT
) != 0) {
812 clock_interval_to_deadline(interval
, scale_factor
, &deadline
);
813 if (!timer_call_enter(&thread
->wait_timer
, deadline
, thread
->sched_pri
>= BASEPRI_RTQUEUES
? TIMER_CALL_CRITICAL
: 0))
814 thread
->wait_timer_active
++;
815 thread
->wait_timer_is_set
= TRUE
;
817 thread_unlock(thread
);
822 thread_set_timer_deadline(
825 thread_t thread
= current_thread();
830 if ((thread
->state
& TH_WAIT
) != 0) {
831 if (!timer_call_enter(&thread
->wait_timer
, deadline
, thread
->sched_pri
>= BASEPRI_RTQUEUES
? TIMER_CALL_CRITICAL
: 0))
832 thread
->wait_timer_active
++;
833 thread
->wait_timer_is_set
= TRUE
;
835 thread_unlock(thread
);
840 thread_cancel_timer(void)
842 thread_t thread
= current_thread();
847 if (thread
->wait_timer_is_set
) {
848 if (timer_call_cancel(&thread
->wait_timer
))
849 thread
->wait_timer_active
--;
850 thread
->wait_timer_is_set
= FALSE
;
852 thread_unlock(thread
);
856 #endif /* __LP64__ */
861 * Unblock thread on wake up.
863 * Returns TRUE if the thread is still running.
865 * Thread must be locked.
870 wait_result_t wresult
)
872 boolean_t result
= FALSE
;
873 thread_t cthread
= current_thread();
878 thread
->wait_result
= wresult
;
881 * Cancel pending wait timer.
883 if (thread
->wait_timer_is_set
) {
884 if (timer_call_cancel(&thread
->wait_timer
))
885 thread
->wait_timer_active
--;
886 thread
->wait_timer_is_set
= FALSE
;
890 * Update scheduling state: not waiting,
893 thread
->state
&= ~(TH_WAIT
|TH_UNINT
);
895 if (!(thread
->state
& TH_RUN
)) {
896 thread
->state
|= TH_RUN
;
898 (*thread
->sched_call
)(SCHED_CALL_UNBLOCK
, thread
);
904 if (thread
->sched_mode
== TH_MODE_TIMESHARE
)
909 * Signal if idling on another processor.
911 #if CONFIG_SCHED_IDLE_IN_PLACE
912 if (thread
->state
& TH_IDLE
) {
913 processor_t processor
= thread
->last_processor
;
915 if (processor
!= current_processor())
916 machine_signal_idle(processor
);
919 assert((thread
->state
& TH_IDLE
) == 0);
926 * Calculate deadline for real-time threads.
928 if (thread
->sched_mode
== TH_MODE_REALTIME
) {
929 thread
->realtime
.deadline
= mach_absolute_time();
930 thread
->realtime
.deadline
+= thread
->realtime
.constraint
;
934 * Clear old quantum, fail-safe computation, etc.
936 thread
->current_quantum
= 0;
937 thread
->computation_metered
= 0;
938 thread
->reason
= AST_NONE
;
940 /* Obtain power-relevant interrupt and "platform-idle exit" statistics.
941 * We also account for "double hop" thread signaling via
942 * the thread callout infrastructure.
943 * DRK: consider removing the callout wakeup counters in the future
944 * they're present for verification at the moment.
946 boolean_t aticontext
, pidle
;
947 ml_get_power_state(&aticontext
, &pidle
);
948 if (__improbable(aticontext
)) {
949 ledger_credit(thread
->t_ledger
, task_ledgers
.interrupt_wakeups
, 1);
950 uint64_t ttd
= PROCESSOR_DATA(current_processor(), timer_call_ttd
);
952 if (ttd
<= timer_deadline_tracking_bin_1
)
953 thread
->thread_timer_wakeups_bin_1
++;
955 if (ttd
<= timer_deadline_tracking_bin_2
)
956 thread
->thread_timer_wakeups_bin_2
++;
959 ledger_credit(thread
->t_ledger
, task_ledgers
.platform_idle_wakeups
, 1);
961 } else if (thread_get_tag_internal(cthread
) & THREAD_TAG_CALLOUT
) {
962 if (cthread
->callout_woken_from_icontext
) {
963 ledger_credit(thread
->t_ledger
, task_ledgers
.interrupt_wakeups
, 1);
964 thread
->thread_callout_interrupt_wakeups
++;
965 if (cthread
->callout_woken_from_platform_idle
) {
966 ledger_credit(thread
->t_ledger
, task_ledgers
.platform_idle_wakeups
, 1);
967 thread
->thread_callout_platform_idle_wakeups
++;
972 if (thread_get_tag_internal(thread
) & THREAD_TAG_CALLOUT
) {
973 thread
->callout_woken_from_icontext
= aticontext
;
974 thread
->callout_woken_from_platform_idle
= pidle
;
977 /* Event should only be triggered if thread is not already running */
978 if (result
== FALSE
) {
979 KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE
,
980 MACHDBG_CODE(DBG_MACH_SCHED
,MACH_MAKE_RUNNABLE
) | DBG_FUNC_NONE
,
981 (uintptr_t)thread_tid(thread
), thread
->sched_pri
, thread
->wait_result
, 0, 0);
984 DTRACE_SCHED2(wakeup
, struct thread
*, thread
, struct proc
*, thread
->task
->bsd_info
);
992 * Unblock and dispatch thread.
994 * thread lock held, IPC locks may be held.
995 * thread must have been pulled from wait queue under same lock hold.
997 * KERN_SUCCESS - Thread was set running
998 * KERN_NOT_WAITING - Thread was not waiting
1003 wait_result_t wresult
)
1005 assert(thread
->at_safe_point
== FALSE
);
1006 assert(thread
->wait_event
== NO_EVENT64
);
1007 assert(thread
->wait_queue
== WAIT_QUEUE_NULL
);
1009 if ((thread
->state
& (TH_WAIT
|TH_TERMINATE
)) == TH_WAIT
) {
1010 if (!thread_unblock(thread
, wresult
))
1011 thread_setrun(thread
, SCHED_PREEMPT
| SCHED_TAILQ
);
1013 return (KERN_SUCCESS
);
1016 return (KERN_NOT_WAITING
);
1020 * Routine: thread_mark_wait_locked
1022 * Mark a thread as waiting. If, given the circumstances,
1023 * it doesn't want to wait (i.e. already aborted), then
1024 * indicate that in the return value.
1026 * at splsched() and thread is locked.
1030 thread_mark_wait_locked(
1032 wait_interrupt_t interruptible
)
1034 boolean_t at_safe_point
;
1036 assert(thread
== current_thread());
1039 * The thread may have certain types of interrupts/aborts masked
1040 * off. Even if the wait location says these types of interrupts
1041 * are OK, we have to honor mask settings (outer-scoped code may
1042 * not be able to handle aborts at the moment).
1044 if (interruptible
> (thread
->options
& TH_OPT_INTMASK
))
1045 interruptible
= thread
->options
& TH_OPT_INTMASK
;
1047 at_safe_point
= (interruptible
== THREAD_ABORTSAFE
);
1049 if ( interruptible
== THREAD_UNINT
||
1050 !(thread
->sched_flags
& TH_SFLAG_ABORT
) ||
1052 (thread
->sched_flags
& TH_SFLAG_ABORTSAFELY
))) {
1054 if ( !(thread
->state
& TH_TERMINATE
))
1055 DTRACE_SCHED(sleep
);
1057 thread
->state
|= (interruptible
) ? TH_WAIT
: (TH_WAIT
| TH_UNINT
);
1058 thread
->at_safe_point
= at_safe_point
;
1059 return (thread
->wait_result
= THREAD_WAITING
);
1062 if (thread
->sched_flags
& TH_SFLAG_ABORTSAFELY
)
1063 thread
->sched_flags
&= ~TH_SFLAG_ABORTED_MASK
;
1065 return (thread
->wait_result
= THREAD_INTERRUPTED
);
1069 * Routine: thread_interrupt_level
1071 * Set the maximum interruptible state for the
1072 * current thread. The effective value of any
1073 * interruptible flag passed into assert_wait
1074 * will never exceed this.
1076 * Useful for code that must not be interrupted,
1077 * but which calls code that doesn't know that.
1079 * The old interrupt level for the thread.
1083 thread_interrupt_level(
1084 wait_interrupt_t new_level
)
1086 thread_t thread
= current_thread();
1087 wait_interrupt_t result
= thread
->options
& TH_OPT_INTMASK
;
1089 thread
->options
= (thread
->options
& ~TH_OPT_INTMASK
) | (new_level
& TH_OPT_INTMASK
);
1095 * Check to see if an assert wait is possible, without actually doing one.
1096 * This is used by debug code in locks and elsewhere to verify that it is
1097 * always OK to block when trying to take a blocking lock (since waiting
1098 * for the actual assert_wait to catch the case may make it hard to detect
1102 assert_wait_possible(void)
1108 if(debug_mode
) return TRUE
; /* Always succeed in debug mode */
1111 thread
= current_thread();
1113 return (thread
== NULL
|| wait_queue_assert_possible(thread
));
1119 * Assert that the current thread is about to go to
1120 * sleep until the specified event occurs.
1125 wait_interrupt_t interruptible
)
1127 register wait_queue_t wq
;
1130 assert(event
!= NO_EVENT
);
1132 KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE
,
1133 MACHDBG_CODE(DBG_MACH_SCHED
, MACH_WAIT
)|DBG_FUNC_NONE
,
1134 VM_KERNEL_UNSLIDE(event
), 0, 0, 0, 0);
1136 index
= wait_hash(event
);
1137 wq
= &wait_queues
[index
];
1138 return wait_queue_assert_wait(wq
, event
, interruptible
, 0);
1142 assert_wait_timeout(
1144 wait_interrupt_t interruptible
,
1146 uint32_t scale_factor
)
1148 thread_t thread
= current_thread();
1149 wait_result_t wresult
;
1150 wait_queue_t wqueue
;
1154 assert(event
!= NO_EVENT
);
1155 wqueue
= &wait_queues
[wait_hash(event
)];
1158 wait_queue_lock(wqueue
);
1159 thread_lock(thread
);
1161 clock_interval_to_deadline(interval
, scale_factor
, &deadline
);
1163 KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE
,
1164 MACHDBG_CODE(DBG_MACH_SCHED
, MACH_WAIT
)|DBG_FUNC_NONE
,
1165 VM_KERNEL_UNSLIDE(event
), interruptible
, deadline
, 0, 0);
1167 wresult
= wait_queue_assert_wait64_locked(wqueue
, CAST_DOWN(event64_t
, event
),
1168 interruptible
, deadline
, thread
);
1170 thread_unlock(thread
);
1171 wait_queue_unlock(wqueue
);
1178 assert_wait_deadline(
1180 wait_interrupt_t interruptible
,
1183 thread_t thread
= current_thread();
1184 wait_result_t wresult
;
1185 wait_queue_t wqueue
;
1188 assert(event
!= NO_EVENT
);
1189 wqueue
= &wait_queues
[wait_hash(event
)];
1192 wait_queue_lock(wqueue
);
1193 thread_lock(thread
);
1195 KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE
,
1196 MACHDBG_CODE(DBG_MACH_SCHED
, MACH_WAIT
)|DBG_FUNC_NONE
,
1197 VM_KERNEL_UNSLIDE(event
), interruptible
, deadline
, 0, 0);
1199 wresult
= wait_queue_assert_wait64_locked(wqueue
, CAST_DOWN(event64_t
,event
),
1200 interruptible
, deadline
, thread
);
1202 thread_unlock(thread
);
1203 wait_queue_unlock(wqueue
);
1210 * thread_sleep_fast_usimple_lock:
1212 * Cause the current thread to wait until the specified event
1213 * occurs. The specified simple_lock is unlocked before releasing
1214 * the cpu and re-acquired as part of waking up.
1216 * This is the simple lock sleep interface for components that use a
1217 * faster version of simple_lock() than is provided by usimple_lock().
1219 __private_extern__ wait_result_t
1220 thread_sleep_fast_usimple_lock(
1223 wait_interrupt_t interruptible
)
1227 res
= assert_wait(event
, interruptible
);
1228 if (res
== THREAD_WAITING
) {
1229 simple_unlock(lock
);
1230 res
= thread_block(THREAD_CONTINUE_NULL
);
1238 * thread_sleep_usimple_lock:
1240 * Cause the current thread to wait until the specified event
1241 * occurs. The specified usimple_lock is unlocked before releasing
1242 * the cpu and re-acquired as part of waking up.
1244 * This is the simple lock sleep interface for components where
1245 * simple_lock() is defined in terms of usimple_lock().
1248 thread_sleep_usimple_lock(
1250 usimple_lock_t lock
,
1251 wait_interrupt_t interruptible
)
1255 res
= assert_wait(event
, interruptible
);
1256 if (res
== THREAD_WAITING
) {
1257 usimple_unlock(lock
);
1258 res
= thread_block(THREAD_CONTINUE_NULL
);
1265 * thread_sleep_lock_write:
1267 * Cause the current thread to wait until the specified event
1268 * occurs. The specified (write) lock is unlocked before releasing
1269 * the cpu. The (write) lock will be re-acquired before returning.
1272 thread_sleep_lock_write(
1275 wait_interrupt_t interruptible
)
1279 res
= assert_wait(event
, interruptible
);
1280 if (res
== THREAD_WAITING
) {
1281 lock_write_done(lock
);
1282 res
= thread_block(THREAD_CONTINUE_NULL
);
1291 * Force a preemption point for a thread and wait
1292 * for it to stop running. Arbitrates access among
1293 * multiple stop requests. (released by unstop)
1295 * The thread must enter a wait state and stop via a
1298 * Returns FALSE if interrupted.
1304 wait_result_t wresult
;
1305 spl_t s
= splsched();
1308 thread_lock(thread
);
1310 while (thread
->state
& TH_SUSP
) {
1311 thread
->wake_active
= TRUE
;
1312 thread_unlock(thread
);
1314 wresult
= assert_wait(&thread
->wake_active
, THREAD_ABORTSAFE
);
1315 wake_unlock(thread
);
1318 if (wresult
== THREAD_WAITING
)
1319 wresult
= thread_block(THREAD_CONTINUE_NULL
);
1321 if (wresult
!= THREAD_AWAKENED
)
1326 thread_lock(thread
);
1329 thread
->state
|= TH_SUSP
;
1331 while (thread
->state
& TH_RUN
) {
1332 processor_t processor
= thread
->last_processor
;
1334 if (processor
!= PROCESSOR_NULL
&& processor
->active_thread
== thread
)
1335 cause_ast_check(processor
);
1337 thread
->wake_active
= TRUE
;
1338 thread_unlock(thread
);
1340 wresult
= assert_wait(&thread
->wake_active
, THREAD_ABORTSAFE
);
1341 wake_unlock(thread
);
1344 if (wresult
== THREAD_WAITING
)
1345 wresult
= thread_block(THREAD_CONTINUE_NULL
);
1347 if (wresult
!= THREAD_AWAKENED
) {
1348 thread_unstop(thread
);
1354 thread_lock(thread
);
1357 thread_unlock(thread
);
1358 wake_unlock(thread
);
1367 * Release a previous stop request and set
1368 * the thread running if appropriate.
1370 * Use only after a successful stop operation.
1376 spl_t s
= splsched();
1379 thread_lock(thread
);
1381 if ((thread
->state
& (TH_RUN
|TH_WAIT
|TH_SUSP
)) == TH_SUSP
) {
1382 thread
->state
&= ~TH_SUSP
;
1383 thread_unblock(thread
, THREAD_AWAKENED
);
1385 thread_setrun(thread
, SCHED_PREEMPT
| SCHED_TAILQ
);
1388 if (thread
->state
& TH_SUSP
) {
1389 thread
->state
&= ~TH_SUSP
;
1391 if (thread
->wake_active
) {
1392 thread
->wake_active
= FALSE
;
1393 thread_unlock(thread
);
1395 thread_wakeup(&thread
->wake_active
);
1396 wake_unlock(thread
);
1403 thread_unlock(thread
);
1404 wake_unlock(thread
);
1409 * Thread locked, returns the same way
1411 static inline boolean_t
1412 thread_isoncpu(thread_t thread
)
1414 processor_t processor
= thread
->last_processor
;
1416 return ((processor
!= PROCESSOR_NULL
) && (processor
->active_thread
== thread
));
1421 * Wait for a thread to stop running. (non-interruptible)
1427 boolean_t until_not_runnable
)
1429 wait_result_t wresult
;
1431 processor_t processor
;
1432 spl_t s
= splsched();
1435 thread_lock(thread
);
1438 * Wait until not running on a CPU. If stronger requirement
1439 * desired, wait until not runnable. Assumption: if thread is
1440 * on CPU, then TH_RUN is set, so we're not waiting in any case
1441 * where the original, pure "TH_RUN" check would have let us
1444 while ((oncpu
= thread_isoncpu(thread
)) ||
1445 (until_not_runnable
&& (thread
->state
& TH_RUN
))) {
1448 assert(thread
->state
& TH_RUN
);
1449 processor
= thread
->last_processor
;
1450 cause_ast_check(processor
);
1453 thread
->wake_active
= TRUE
;
1454 thread_unlock(thread
);
1456 wresult
= assert_wait(&thread
->wake_active
, THREAD_UNINT
);
1457 wake_unlock(thread
);
1460 if (wresult
== THREAD_WAITING
)
1461 thread_block(THREAD_CONTINUE_NULL
);
1465 thread_lock(thread
);
1468 thread_unlock(thread
);
1469 wake_unlock(thread
);
1474 * Routine: clear_wait_internal
1476 * Clear the wait condition for the specified thread.
1477 * Start the thread executing if that is appropriate.
1479 * thread thread to awaken
1480 * result Wakeup result the thread should see
1483 * the thread is locked.
1485 * KERN_SUCCESS thread was rousted out a wait
1486 * KERN_FAILURE thread was waiting but could not be rousted
1487 * KERN_NOT_WAITING thread was not waiting
1489 __private_extern__ kern_return_t
1490 clear_wait_internal(
1492 wait_result_t wresult
)
1494 wait_queue_t wq
= thread
->wait_queue
;
1495 uint32_t i
= LockTimeOut
;
1498 if (wresult
== THREAD_INTERRUPTED
&& (thread
->state
& TH_UNINT
))
1499 return (KERN_FAILURE
);
1501 if (wq
!= WAIT_QUEUE_NULL
) {
1502 if (wait_queue_lock_try(wq
)) {
1503 wait_queue_pull_thread_locked(wq
, thread
, TRUE
);
1504 /* wait queue unlocked, thread still locked */
1507 thread_unlock(thread
);
1510 thread_lock(thread
);
1511 if (wq
!= thread
->wait_queue
)
1512 return (KERN_NOT_WAITING
);
1518 return (thread_go(thread
, wresult
));
1519 } while ((--i
> 0) || machine_timeout_suspended());
1521 panic("clear_wait_internal: deadlock: thread=%p, wq=%p, cpu=%d\n",
1522 thread
, wq
, cpu_number());
1524 return (KERN_FAILURE
);
1531 * Clear the wait condition for the specified thread. Start the thread
1532 * executing if that is appropriate.
1535 * thread thread to awaken
1536 * result Wakeup result the thread should see
1541 wait_result_t result
)
1547 thread_lock(thread
);
1548 ret
= clear_wait_internal(thread
, result
);
1549 thread_unlock(thread
);
1556 * thread_wakeup_prim:
1558 * Common routine for thread_wakeup, thread_wakeup_with_result,
1559 * and thread_wakeup_one.
1565 boolean_t one_thread
,
1566 wait_result_t result
)
1568 return (thread_wakeup_prim_internal(event
, one_thread
, result
, -1));
1573 thread_wakeup_prim_internal(
1575 boolean_t one_thread
,
1576 wait_result_t result
,
1579 register wait_queue_t wq
;
1582 index
= wait_hash(event
);
1583 wq
= &wait_queues
[index
];
1585 return (wait_queue_wakeup_one(wq
, event
, result
, priority
));
1587 return (wait_queue_wakeup_all(wq
, event
, result
));
1593 * Force the current thread to execute on the specified processor.
1595 * Returns the previous binding. PROCESSOR_NULL means
1598 * XXX - DO NOT export this to users - XXX
1602 processor_t processor
)
1604 thread_t self
= current_thread();
1611 prev
= self
->bound_processor
;
1612 self
->bound_processor
= processor
;
1614 thread_unlock(self
);
1623 * Select a new thread for the current processor to execute.
1625 * May select the current thread, which must be locked.
1630 processor_t processor
)
1632 processor_set_t pset
= processor
->processor_set
;
1633 thread_t new_thread
= THREAD_NULL
;
1634 boolean_t inactive_state
;
1636 assert(processor
== current_processor());
1640 * Update the priority.
1642 if (SCHED(can_update_priority
)(thread
))
1643 SCHED(update_priority
)(thread
);
1645 processor
->current_pri
= thread
->sched_pri
;
1646 processor
->current_thmode
= thread
->sched_mode
;
1650 assert(pset
->low_count
);
1651 assert(pset
->low_pri
);
1653 inactive_state
= processor
->state
!= PROCESSOR_SHUTDOWN
&& machine_processor_is_inactive(processor
);
1655 simple_lock(&rt_lock
);
1658 * Test to see if the current thread should continue
1659 * to run on this processor. Must be runnable, and not
1660 * bound to a different processor, nor be in the wrong
1663 if ( ((thread
->state
& ~TH_SUSP
) == TH_RUN
) &&
1664 (thread
->sched_pri
>= BASEPRI_RTQUEUES
||
1665 processor
->processor_meta
== PROCESSOR_META_NULL
||
1666 processor
->processor_meta
->primary
== processor
) &&
1667 (thread
->bound_processor
== PROCESSOR_NULL
||
1668 thread
->bound_processor
== processor
) &&
1669 (thread
->affinity_set
== AFFINITY_SET_NULL
||
1670 thread
->affinity_set
->aset_pset
== pset
) ) {
1671 if ( thread
->sched_pri
>= BASEPRI_RTQUEUES
&&
1672 first_timeslice(processor
) ) {
1673 if (rt_runq
.count
> 0) {
1677 if (((thread_t
)q
->next
)->realtime
.deadline
<
1678 processor
->deadline
) {
1679 thread
= (thread_t
)dequeue_head(q
);
1680 thread
->runq
= PROCESSOR_NULL
;
1681 SCHED_STATS_RUNQ_CHANGE(&rt_runq
.runq_stats
, rt_runq
.count
);
1686 simple_unlock(&rt_lock
);
1688 processor
->deadline
= thread
->realtime
.deadline
;
1695 if (!inactive_state
&& (thread
->sched_mode
!= TH_MODE_FAIRSHARE
|| SCHED(fairshare_runq_count
)() == 0) && (rt_runq
.count
== 0 || BASEPRI_RTQUEUES
< thread
->sched_pri
) &&
1696 (new_thread
= SCHED(choose_thread
)(processor
, thread
->sched_mode
== TH_MODE_FAIRSHARE
? MINPRI
: thread
->sched_pri
)) == THREAD_NULL
) {
1698 simple_unlock(&rt_lock
);
1700 /* I am the highest priority runnable (non-idle) thread */
1702 pset_pri_hint(pset
, processor
, processor
->current_pri
);
1704 pset_count_hint(pset
, processor
, SCHED(processor_runq_count
)(processor
));
1706 processor
->deadline
= UINT64_MAX
;
1714 if (new_thread
!= THREAD_NULL
||
1715 (SCHED(processor_queue_has_priority
)(processor
, rt_runq
.count
== 0 ? IDLEPRI
: BASEPRI_RTQUEUES
, TRUE
) &&
1716 (new_thread
= SCHED(choose_thread
)(processor
, MINPRI
)) != THREAD_NULL
)) {
1717 simple_unlock(&rt_lock
);
1719 if (!inactive_state
) {
1720 pset_pri_hint(pset
, processor
, new_thread
->sched_pri
);
1722 pset_count_hint(pset
, processor
, SCHED(processor_runq_count
)(processor
));
1725 processor
->deadline
= UINT64_MAX
;
1728 return (new_thread
);
1731 if (rt_runq
.count
> 0) {
1732 thread
= (thread_t
)dequeue_head(&rt_runq
.queue
);
1734 thread
->runq
= PROCESSOR_NULL
;
1735 SCHED_STATS_RUNQ_CHANGE(&rt_runq
.runq_stats
, rt_runq
.count
);
1738 simple_unlock(&rt_lock
);
1740 processor
->deadline
= thread
->realtime
.deadline
;
1746 simple_unlock(&rt_lock
);
1748 /* No realtime threads and no normal threads on the per-processor
1749 * runqueue. Finally check for global fairshare threads.
1751 if ((new_thread
= SCHED(fairshare_dequeue
)()) != THREAD_NULL
) {
1753 processor
->deadline
= UINT64_MAX
;
1756 return (new_thread
);
1759 processor
->deadline
= UINT64_MAX
;
1762 * Set processor inactive based on
1763 * indication from the platform code.
1765 if (inactive_state
) {
1766 if (processor
->state
== PROCESSOR_RUNNING
)
1767 remqueue((queue_entry_t
)processor
);
1769 if (processor
->state
== PROCESSOR_IDLE
)
1770 remqueue((queue_entry_t
)processor
);
1772 processor
->state
= PROCESSOR_INACTIVE
;
1776 return (processor
->idle_thread
);
1780 * No runnable threads, attempt to steal
1781 * from other processors.
1783 new_thread
= SCHED(steal_thread
)(pset
);
1784 if (new_thread
!= THREAD_NULL
) {
1785 return (new_thread
);
1789 * If other threads have appeared, shortcut
1792 if (!SCHED(processor_queue_empty
)(processor
) || rt_runq
.count
> 0 || SCHED(fairshare_runq_count
)() > 0)
1798 * Nothing is runnable, so set this processor idle if it
1801 if (processor
->state
== PROCESSOR_RUNNING
) {
1802 remqueue((queue_entry_t
)processor
);
1803 processor
->state
= PROCESSOR_IDLE
;
1805 if (processor
->processor_meta
== PROCESSOR_META_NULL
|| processor
->processor_meta
->primary
== processor
) {
1806 enqueue_head(&pset
->idle_queue
, (queue_entry_t
)processor
);
1807 pset_pri_init_hint(pset
, processor
);
1808 pset_count_init_hint(pset
, processor
);
1811 enqueue_head(&processor
->processor_meta
->idle_queue
, (queue_entry_t
)processor
);
1813 return (processor
->idle_thread
);
1819 #if CONFIG_SCHED_IDLE_IN_PLACE
1821 * Choose idle thread if fast idle is not possible.
1823 if ((thread
->state
& (TH_IDLE
|TH_TERMINATE
|TH_SUSP
)) || !(thread
->state
& TH_WAIT
) || thread
->wake_active
|| thread
->sched_pri
>= BASEPRI_RTQUEUES
)
1824 return (processor
->idle_thread
);
1827 * Perform idling activities directly without a
1828 * context switch. Return dispatched thread,
1829 * else check again for a runnable thread.
1831 new_thread
= thread_select_idle(thread
, processor
);
1833 #else /* !CONFIG_SCHED_IDLE_IN_PLACE */
1836 * Do a full context switch to idle so that the current
1837 * thread can start running on another processor without
1838 * waiting for the fast-idled processor to wake up.
1840 return (processor
->idle_thread
);
1842 #endif /* !CONFIG_SCHED_IDLE_IN_PLACE */
1844 } while (new_thread
== THREAD_NULL
);
1846 return (new_thread
);
1849 #if CONFIG_SCHED_IDLE_IN_PLACE
1851 * thread_select_idle:
1853 * Idle the processor using the current thread context.
1855 * Called with thread locked, then dropped and relocked.
1860 processor_t processor
)
1862 thread_t new_thread
;
1864 if (thread
->sched_mode
== TH_MODE_TIMESHARE
)
1868 thread
->state
|= TH_IDLE
;
1869 processor
->current_pri
= IDLEPRI
;
1870 processor
->current_thmode
= TH_MODE_NONE
;
1872 /* Reload precise timing global policy to thread-local policy */
1873 thread
->precise_user_kernel_time
= use_precise_user_kernel_time(thread
);
1875 thread_unlock(thread
);
1878 * Switch execution timing to processor idle thread.
1880 processor
->last_dispatch
= mach_absolute_time();
1881 thread
->last_run_time
= processor
->last_dispatch
;
1882 thread_timer_event(processor
->last_dispatch
, &processor
->idle_thread
->system_timer
);
1883 PROCESSOR_DATA(processor
, kernel_timer
) = &processor
->idle_thread
->system_timer
;
1886 * Cancel the quantum timer while idling.
1888 timer_call_cancel(&processor
->quantum_timer
);
1889 processor
->timeslice
= 0;
1891 (*thread
->sched_call
)(SCHED_CALL_BLOCK
, thread
);
1893 thread_tell_urgency(THREAD_URGENCY_NONE
, 0, 0);
1896 * Enable interrupts and perform idling activities. No
1897 * preemption due to TH_IDLE being set.
1899 spllo(); new_thread
= processor_idle(thread
, processor
);
1902 * Return at splsched.
1904 (*thread
->sched_call
)(SCHED_CALL_UNBLOCK
, thread
);
1906 thread_lock(thread
);
1909 * If we idled in place, simulate a context switch back
1910 * to the original priority of the thread so that the
1911 * platform layer cannot distinguish this from a true
1912 * switch to the idle thread.
1914 if (thread
->sched_mode
== TH_MODE_REALTIME
)
1915 thread_tell_urgency(THREAD_URGENCY_REAL_TIME
, thread
->realtime
.period
, thread
->realtime
.deadline
);
1916 /* Identify non-promoted threads which have requested a
1917 * "background" priority.
1919 else if ((thread
->sched_pri
<= MAXPRI_THROTTLE
) &&
1920 (thread
->priority
<= MAXPRI_THROTTLE
))
1921 thread_tell_urgency(THREAD_URGENCY_BACKGROUND
, thread
->sched_pri
, thread
->priority
);
1923 thread_tell_urgency(THREAD_URGENCY_NORMAL
, thread
->sched_pri
, thread
->priority
);
1926 * If awakened, switch to thread timer and start a new quantum.
1927 * Otherwise skip; we will context switch to another thread or return here.
1929 if (!(thread
->state
& TH_WAIT
)) {
1930 processor
->last_dispatch
= mach_absolute_time();
1931 thread_timer_event(processor
->last_dispatch
, &thread
->system_timer
);
1932 PROCESSOR_DATA(processor
, kernel_timer
) = &thread
->system_timer
;
1934 thread_quantum_init(thread
);
1935 thread
->last_quantum_refill_time
= processor
->last_dispatch
;
1937 processor
->quantum_end
= processor
->last_dispatch
+ thread
->current_quantum
;
1938 timer_call_enter1(&processor
->quantum_timer
, thread
, processor
->quantum_end
, TIMER_CALL_CRITICAL
);
1939 processor
->timeslice
= 1;
1941 thread
->computation_epoch
= processor
->last_dispatch
;
1944 thread
->state
&= ~TH_IDLE
;
1947 if (thread
->sched_mode
== TH_MODE_TIMESHARE
)
1950 return (new_thread
);
1952 #endif /* CONFIG_SCHED_IDLE_IN_PLACE */
1954 #if defined(CONFIG_SCHED_TRADITIONAL)
1956 sched_traditional_choose_thread(
1957 processor_t processor
,
1962 thread
= choose_thread(processor
, runq_for_processor(processor
), priority
);
1963 if (thread
!= THREAD_NULL
) {
1964 runq_consider_decr_bound_count(processor
, thread
);
1970 #endif /* defined(CONFIG_SCHED_TRADITIONAL) */
1972 #if defined(CONFIG_SCHED_TRADITIONAL) || defined(CONFIG_SCHED_FIXEDPRIORITY)
1977 * Locate a thread to execute from the processor run queue
1978 * and return it. Only choose a thread with greater or equal
1981 * Associated pset must be locked. Returns THREAD_NULL
1986 processor_t processor
,
1990 queue_t queue
= rq
->queues
+ rq
->highq
;
1991 int pri
= rq
->highq
, count
= rq
->count
;
1994 while (count
> 0 && pri
>= priority
) {
1995 thread
= (thread_t
)queue_first(queue
);
1996 while (!queue_end(queue
, (queue_entry_t
)thread
)) {
1997 if (thread
->bound_processor
== PROCESSOR_NULL
||
1998 thread
->bound_processor
== processor
) {
1999 remqueue((queue_entry_t
)thread
);
2001 thread
->runq
= PROCESSOR_NULL
;
2002 SCHED_STATS_RUNQ_CHANGE(&rq
->runq_stats
, rq
->count
);
2004 if (SCHED(priority_is_urgent
)(pri
)) {
2005 rq
->urgency
--; assert(rq
->urgency
>= 0);
2007 if (queue_empty(queue
)) {
2009 clrbit(MAXPRI
- pri
, rq
->bitmap
);
2010 rq
->highq
= MAXPRI
- ffsbit(rq
->bitmap
);
2017 thread
= (thread_t
)queue_next((queue_entry_t
)thread
);
2023 return (THREAD_NULL
);
2026 #endif /* defined(CONFIG_SCHED_TRADITIONAL) || defined(CONFIG_SCHED_FIXEDPRIORITY) */
2029 * Perform a context switch and start executing the new thread.
2031 * Returns FALSE on failure, and the thread is re-dispatched.
2033 * Called at splsched.
2036 #define funnel_release_check(thread, debug) \
2038 if ((thread)->funnel_state & TH_FN_OWNED) { \
2039 (thread)->funnel_state = TH_FN_REFUNNEL; \
2040 KERNEL_DEBUG(0x603242c | DBG_FUNC_NONE, \
2041 (thread)->funnel_lock, (debug), 0, 0, 0); \
2042 funnel_unlock((thread)->funnel_lock); \
2046 #define funnel_refunnel_check(thread, debug) \
2048 if ((thread)->funnel_state & TH_FN_REFUNNEL) { \
2049 kern_return_t result = (thread)->wait_result; \
2051 (thread)->funnel_state = 0; \
2052 KERNEL_DEBUG(0x6032428 | DBG_FUNC_NONE, \
2053 (thread)->funnel_lock, (debug), 0, 0, 0); \
2054 funnel_lock((thread)->funnel_lock); \
2055 KERNEL_DEBUG(0x6032430 | DBG_FUNC_NONE, \
2056 (thread)->funnel_lock, (debug), 0, 0, 0); \
2057 (thread)->funnel_state = TH_FN_OWNED; \
2058 (thread)->wait_result = result; \
2064 register thread_t self
,
2065 register thread_t thread
,
2068 thread_continue_t continuation
= self
->continuation
;
2069 void *parameter
= self
->parameter
;
2070 processor_t processor
;
2072 if (get_preemption_level() != 0) {
2073 int pl
= get_preemption_level();
2074 panic("thread_invoke: preemption_level %d, possible cause: %s",
2075 pl
, (pl
< 0 ? "unlocking an unlocked mutex or spinlock" :
2076 "blocking while holding a spinlock, or within interrupt context"));
2079 assert(self
== current_thread());
2082 * Mark thread interruptible.
2084 thread_lock(thread
);
2085 thread
->state
&= ~TH_UNINT
;
2088 assert(thread_runnable(thread
));
2091 /* Reload precise timing global policy to thread-local policy */
2092 thread
->precise_user_kernel_time
= use_precise_user_kernel_time(thread
);
2095 * Allow time constraint threads to hang onto
2098 if ((self
->sched_mode
== TH_MODE_REALTIME
) && !self
->reserved_stack
)
2099 self
->reserved_stack
= self
->kernel_stack
;
2101 if (continuation
!= NULL
) {
2102 if (!thread
->kernel_stack
) {
2104 * If we are using a privileged stack,
2105 * check to see whether we can exchange it with
2106 * that of the other thread.
2108 if (self
->kernel_stack
== self
->reserved_stack
&& !thread
->reserved_stack
)
2112 * Context switch by performing a stack handoff.
2114 continuation
= thread
->continuation
;
2115 parameter
= thread
->parameter
;
2117 processor
= current_processor();
2118 processor
->active_thread
= thread
;
2119 processor
->current_pri
= thread
->sched_pri
;
2120 processor
->current_thmode
= thread
->sched_mode
;
2121 if (thread
->last_processor
!= processor
&& thread
->last_processor
!= NULL
) {
2122 if (thread
->last_processor
->processor_set
!= processor
->processor_set
)
2123 thread
->ps_switch
++;
2126 thread
->last_processor
= processor
;
2128 ast_context(thread
);
2129 thread_unlock(thread
);
2131 self
->reason
= reason
;
2133 processor
->last_dispatch
= mach_absolute_time();
2134 self
->last_run_time
= processor
->last_dispatch
;
2135 thread_timer_event(processor
->last_dispatch
, &thread
->system_timer
);
2136 PROCESSOR_DATA(processor
, kernel_timer
) = &thread
->system_timer
;
2139 * Since non-precise user/kernel time doesn't update the state timer
2140 * during privilege transitions, synthesize an event now.
2142 if (!thread
->precise_user_kernel_time
) {
2143 timer_switch(PROCESSOR_DATA(processor
, current_state
),
2144 processor
->last_dispatch
,
2145 PROCESSOR_DATA(processor
, current_state
));
2148 KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE
,
2149 MACHDBG_CODE(DBG_MACH_SCHED
, MACH_STACK_HANDOFF
)|DBG_FUNC_NONE
,
2150 self
->reason
, (uintptr_t)thread_tid(thread
), self
->sched_pri
, thread
->sched_pri
, 0);
2152 if ((thread
->chosen_processor
!= processor
) && (thread
->chosen_processor
!= NULL
)) {
2153 KERNEL_DEBUG_CONSTANT(MACHDBG_CODE(DBG_MACH_SCHED
, MACH_MOVED
)|DBG_FUNC_NONE
,
2154 (uintptr_t)thread_tid(thread
), (uintptr_t)thread
->chosen_processor
->cpu_id
, 0, 0, 0);
2157 DTRACE_SCHED2(off__cpu
, struct thread
*, thread
, struct proc
*, thread
->task
->bsd_info
);
2159 SCHED_STATS_CSW(processor
, self
->reason
, self
->sched_pri
, thread
->sched_pri
);
2161 TLOG(1, "thread_invoke: calling stack_handoff\n");
2162 stack_handoff(self
, thread
);
2164 DTRACE_SCHED(on__cpu
);
2166 thread_dispatch(self
, thread
);
2168 thread
->continuation
= thread
->parameter
= NULL
;
2170 counter(c_thread_invoke_hits
++);
2172 funnel_refunnel_check(thread
, 2);
2175 assert(continuation
);
2176 call_continuation(continuation
, parameter
, thread
->wait_result
);
2179 else if (thread
== self
) {
2180 /* same thread but with continuation */
2182 counter(++c_thread_invoke_same
);
2183 thread_unlock(self
);
2185 KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE
,
2186 MACHDBG_CODE(DBG_MACH_SCHED
,MACH_SCHED
) | DBG_FUNC_NONE
,
2187 self
->reason
, (uintptr_t)thread_tid(thread
), self
->sched_pri
, thread
->sched_pri
, 0);
2189 self
->continuation
= self
->parameter
= NULL
;
2191 funnel_refunnel_check(self
, 3);
2194 call_continuation(continuation
, parameter
, self
->wait_result
);
2200 * Check that the other thread has a stack
2202 if (!thread
->kernel_stack
) {
2204 if (!stack_alloc_try(thread
)) {
2205 counter(c_thread_invoke_misses
++);
2206 thread_unlock(thread
);
2207 thread_stack_enqueue(thread
);
2211 else if (thread
== self
) {
2213 counter(++c_thread_invoke_same
);
2214 thread_unlock(self
);
2216 KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE
,
2217 MACHDBG_CODE(DBG_MACH_SCHED
,MACH_SCHED
) | DBG_FUNC_NONE
,
2218 self
->reason
, (uintptr_t)thread_tid(thread
), self
->sched_pri
, thread
->sched_pri
, 0);
2225 * Context switch by full context save.
2227 processor
= current_processor();
2228 processor
->active_thread
= thread
;
2229 processor
->current_pri
= thread
->sched_pri
;
2230 processor
->current_thmode
= thread
->sched_mode
;
2231 if (thread
->last_processor
!= processor
&& thread
->last_processor
!= NULL
) {
2232 if (thread
->last_processor
->processor_set
!= processor
->processor_set
)
2233 thread
->ps_switch
++;
2236 thread
->last_processor
= processor
;
2238 ast_context(thread
);
2239 thread_unlock(thread
);
2241 counter(c_thread_invoke_csw
++);
2243 assert(self
->runq
== PROCESSOR_NULL
);
2244 self
->reason
= reason
;
2246 processor
->last_dispatch
= mach_absolute_time();
2247 self
->last_run_time
= processor
->last_dispatch
;
2248 thread_timer_event(processor
->last_dispatch
, &thread
->system_timer
);
2249 PROCESSOR_DATA(processor
, kernel_timer
) = &thread
->system_timer
;
2252 * Since non-precise user/kernel time doesn't update the state timer
2253 * during privilege transitions, synthesize an event now.
2255 if (!thread
->precise_user_kernel_time
) {
2256 timer_switch(PROCESSOR_DATA(processor
, current_state
),
2257 processor
->last_dispatch
,
2258 PROCESSOR_DATA(processor
, current_state
));
2262 KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE
,
2263 MACHDBG_CODE(DBG_MACH_SCHED
,MACH_SCHED
) | DBG_FUNC_NONE
,
2264 self
->reason
, (uintptr_t)thread_tid(thread
), self
->sched_pri
, thread
->sched_pri
, 0);
2266 if ((thread
->chosen_processor
!= processor
) && (thread
->chosen_processor
!= NULL
)) {
2267 KERNEL_DEBUG_CONSTANT(MACHDBG_CODE(DBG_MACH_SCHED
, MACH_MOVED
)|DBG_FUNC_NONE
,
2268 (uintptr_t)thread_tid(thread
), (uintptr_t)thread
->chosen_processor
->cpu_id
, 0, 0, 0);
2271 DTRACE_SCHED2(off__cpu
, struct thread
*, thread
, struct proc
*, thread
->task
->bsd_info
);
2273 SCHED_STATS_CSW(processor
, self
->reason
, self
->sched_pri
, thread
->sched_pri
);
2276 * This is where we actually switch register context,
2277 * and address space if required. We will next run
2278 * as a result of a subsequent context switch.
2280 assert(continuation
== self
->continuation
);
2281 thread
= machine_switch_context(self
, continuation
, thread
);
2282 assert(self
== current_thread());
2283 TLOG(1,"thread_invoke: returning machine_switch_context: self %p continuation %p thread %p\n", self
, continuation
, thread
);
2285 DTRACE_SCHED(on__cpu
);
2288 * We have been resumed and are set to run.
2290 thread_dispatch(thread
, self
);
2293 self
->continuation
= self
->parameter
= NULL
;
2295 funnel_refunnel_check(self
, 3);
2298 call_continuation(continuation
, parameter
, self
->wait_result
);
2308 * Handle threads at context switch. Re-dispatch other thread
2309 * if still running, otherwise update run state and perform
2310 * special actions. Update quantum for other thread and begin
2311 * the quantum for ourselves.
2313 * Called at splsched.
2320 processor_t processor
= self
->last_processor
;
2322 if (thread
!= THREAD_NULL
) {
2324 * If blocked at a continuation, discard
2327 if (thread
->continuation
!= NULL
&& thread
->kernel_stack
!= 0)
2330 if (!(thread
->state
& TH_IDLE
)) {
2332 int64_t remainder
= 0;
2334 if (processor
->quantum_end
> processor
->last_dispatch
)
2335 remainder
= processor
->quantum_end
-
2336 processor
->last_dispatch
;
2338 consumed
= thread
->current_quantum
- remainder
;
2340 if ((thread
->reason
& AST_LEDGER
) == 0)
2342 * Bill CPU time to both the individual thread
2345 ledger_credit(thread
->t_ledger
,
2346 task_ledgers
.cpu_time
, consumed
);
2347 ledger_credit(thread
->t_threadledger
,
2348 thread_ledgers
.cpu_time
, consumed
);
2351 thread_lock(thread
);
2354 * Compute remainder of current quantum.
2356 if (first_timeslice(processor
) &&
2357 processor
->quantum_end
> processor
->last_dispatch
)
2358 thread
->current_quantum
= (uint32_t)remainder
;
2360 thread
->current_quantum
= 0;
2362 if (thread
->sched_mode
== TH_MODE_REALTIME
) {
2364 * Cancel the deadline if the thread has
2365 * consumed the entire quantum.
2367 if (thread
->current_quantum
== 0) {
2368 thread
->realtime
.deadline
= UINT64_MAX
;
2369 thread
->reason
|= AST_QUANTUM
;
2372 #if defined(CONFIG_SCHED_TRADITIONAL)
2374 * For non-realtime threads treat a tiny
2375 * remaining quantum as an expired quantum
2376 * but include what's left next time.
2378 if (thread
->current_quantum
< min_std_quantum
) {
2379 thread
->reason
|= AST_QUANTUM
;
2380 thread
->current_quantum
+= SCHED(initial_quantum_size
)(thread
);
2386 * If we are doing a direct handoff then
2387 * take the remainder of the quantum.
2389 if ((thread
->reason
& (AST_HANDOFF
|AST_QUANTUM
)) == AST_HANDOFF
) {
2390 self
->current_quantum
= thread
->current_quantum
;
2391 thread
->reason
|= AST_QUANTUM
;
2392 thread
->current_quantum
= 0;
2395 thread
->computation_metered
+= (processor
->last_dispatch
- thread
->computation_epoch
);
2397 if (!(thread
->state
& TH_WAIT
)) {
2401 if (thread
->reason
& AST_QUANTUM
)
2402 thread_setrun(thread
, SCHED_TAILQ
);
2404 if (thread
->reason
& AST_PREEMPT
)
2405 thread_setrun(thread
, SCHED_HEADQ
);
2407 thread_setrun(thread
, SCHED_PREEMPT
| SCHED_TAILQ
);
2409 thread
->reason
= AST_NONE
;
2411 if (thread
->wake_active
) {
2412 thread
->wake_active
= FALSE
;
2413 thread_unlock(thread
);
2415 thread_wakeup(&thread
->wake_active
);
2418 thread_unlock(thread
);
2420 wake_unlock(thread
);
2426 boolean_t should_terminate
= FALSE
;
2428 /* Only the first call to thread_dispatch
2429 * after explicit termination should add
2430 * the thread to the termination queue
2432 if ((thread
->state
& (TH_TERMINATE
|TH_TERMINATE2
)) == TH_TERMINATE
) {
2433 should_terminate
= TRUE
;
2434 thread
->state
|= TH_TERMINATE2
;
2437 thread
->state
&= ~TH_RUN
;
2439 if (thread
->sched_mode
== TH_MODE_TIMESHARE
)
2443 (*thread
->sched_call
)(SCHED_CALL_BLOCK
, thread
);
2445 if (thread
->wake_active
) {
2446 thread
->wake_active
= FALSE
;
2447 thread_unlock(thread
);
2449 thread_wakeup(&thread
->wake_active
);
2452 thread_unlock(thread
);
2454 wake_unlock(thread
);
2456 if (should_terminate
)
2457 thread_terminate_enqueue(thread
);
2462 if (!(self
->state
& TH_IDLE
)) {
2464 if (self
->sched_mode
== TH_MODE_REALTIME
)
2465 thread_tell_urgency(THREAD_URGENCY_REAL_TIME
, self
->realtime
.period
, self
->realtime
.deadline
);
2466 /* Identify non-promoted threads which have requested a
2467 * "background" priority.
2469 else if ((self
->sched_pri
<= MAXPRI_THROTTLE
) &&
2470 (self
->priority
<= MAXPRI_THROTTLE
))
2471 thread_tell_urgency(THREAD_URGENCY_BACKGROUND
, self
->sched_pri
, self
->priority
);
2473 thread_tell_urgency(THREAD_URGENCY_NORMAL
, self
->sched_pri
, self
->priority
);
2475 * Get a new quantum if none remaining.
2477 if (self
->current_quantum
== 0) {
2478 thread_quantum_init(self
);
2479 self
->last_quantum_refill_time
= processor
->last_dispatch
;
2483 * Set up quantum timer and timeslice.
2485 processor
->quantum_end
= (processor
->last_dispatch
+ self
->current_quantum
);
2486 timer_call_enter1(&processor
->quantum_timer
, self
, processor
->quantum_end
, TIMER_CALL_CRITICAL
);
2488 processor
->timeslice
= 1;
2490 self
->computation_epoch
= processor
->last_dispatch
;
2493 timer_call_cancel(&processor
->quantum_timer
);
2494 processor
->timeslice
= 0;
2496 thread_tell_urgency(THREAD_URGENCY_NONE
, 0, 0);
2500 #include <libkern/OSDebug.h>
2502 uint32_t kdebug_thread_block
= 0;
2506 * thread_block_reason:
2508 * Forces a reschedule, blocking the caller if a wait
2509 * has been asserted.
2511 * If a continuation is specified, then thread_invoke will
2512 * attempt to discard the thread's kernel stack. When the
2513 * thread resumes, it will execute the continuation function
2514 * on a new kernel stack.
2516 counter(mach_counter_t c_thread_block_calls
= 0;)
2519 thread_block_reason(
2520 thread_continue_t continuation
,
2524 register thread_t self
= current_thread();
2525 register processor_t processor
;
2526 register thread_t new_thread
;
2529 counter(++c_thread_block_calls
);
2533 if (!(reason
& AST_PREEMPT
))
2534 funnel_release_check(self
, 2);
2536 processor
= current_processor();
2538 /* If we're explicitly yielding, force a subsequent quantum */
2539 if (reason
& AST_YIELD
)
2540 processor
->timeslice
= 0;
2542 /* We're handling all scheduling AST's */
2543 ast_off(AST_SCHEDULING
);
2545 self
->continuation
= continuation
;
2546 self
->parameter
= parameter
;
2548 if (__improbable(kdebug_thread_block
&& kdebug_enable
&& self
->state
!= TH_RUN
)) {
2549 KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE
,
2550 MACHDBG_CODE(DBG_MACH_SCHED
,MACH_BLOCK
),
2551 reason
, VM_KERNEL_UNSLIDE(continuation
), 0, 0, 0);
2556 new_thread
= thread_select(self
, processor
);
2557 thread_unlock(self
);
2558 } while (!thread_invoke(self
, new_thread
, reason
));
2560 funnel_refunnel_check(self
, 5);
2563 return (self
->wait_result
);
2569 * Block the current thread if a wait has been asserted.
2573 thread_continue_t continuation
)
2575 return thread_block_reason(continuation
, NULL
, AST_NONE
);
2579 thread_block_parameter(
2580 thread_continue_t continuation
,
2583 return thread_block_reason(continuation
, parameter
, AST_NONE
);
2589 * Switch directly from the current thread to the
2590 * new thread, handing off our quantum if appropriate.
2592 * New thread must be runnable, and not on a run queue.
2594 * Called at splsched.
2599 thread_continue_t continuation
,
2601 thread_t new_thread
)
2603 ast_t handoff
= AST_HANDOFF
;
2605 funnel_release_check(self
, 3);
2607 self
->continuation
= continuation
;
2608 self
->parameter
= parameter
;
2610 while (!thread_invoke(self
, new_thread
, handoff
)) {
2611 processor_t processor
= current_processor();
2614 new_thread
= thread_select(self
, processor
);
2615 thread_unlock(self
);
2619 funnel_refunnel_check(self
, 6);
2621 return (self
->wait_result
);
2627 * Called at splsched when a thread first receives
2628 * a new stack after a continuation.
2632 register thread_t thread
)
2634 register thread_t self
= current_thread();
2635 register thread_continue_t continuation
;
2636 register void *parameter
;
2638 DTRACE_SCHED(on__cpu
);
2640 continuation
= self
->continuation
;
2641 parameter
= self
->parameter
;
2643 thread_dispatch(thread
, self
);
2645 self
->continuation
= self
->parameter
= NULL
;
2647 funnel_refunnel_check(self
, 4);
2649 if (thread
!= THREAD_NULL
)
2652 TLOG(1, "thread_continue: calling call_continuation \n");
2653 call_continuation(continuation
, parameter
, self
->wait_result
);
2658 thread_quantum_init(thread_t thread
)
2660 if (thread
->sched_mode
== TH_MODE_REALTIME
) {
2661 thread
->current_quantum
= thread
->realtime
.computation
;
2663 thread
->current_quantum
= SCHED(initial_quantum_size
)(thread
);
2667 #if defined(CONFIG_SCHED_TRADITIONAL)
2669 sched_traditional_initial_quantum_size(thread_t thread
)
2671 if ((thread
== THREAD_NULL
) || thread
->priority
> MAXPRI_THROTTLE
)
2678 sched_traditional_initial_thread_sched_mode(task_t parent_task
)
2680 if (parent_task
== kernel_task
)
2681 return TH_MODE_FIXED
;
2683 return TH_MODE_TIMESHARE
;
2687 sched_traditional_supports_timeshare_mode(void)
2692 #endif /* CONFIG_SCHED_TRADITIONAL */
2697 * Initialize a run queue before first use.
2705 rq
->highq
= IDLEPRI
;
2706 for (i
= 0; i
< NRQBM
; i
++)
2708 setbit(MAXPRI
- IDLEPRI
, rq
->bitmap
);
2709 rq
->urgency
= rq
->count
= 0;
2710 for (i
= 0; i
< NRQS
; i
++)
2711 queue_init(&rq
->queues
[i
]);
2714 #if defined(CONFIG_SCHED_TRADITIONAL) || defined(CONFIG_SCHED_PROTO) || defined(CONFIG_SCHED_GRRR) || defined(CONFIG_SCHED_FIXEDPRIORITY)
2716 sched_traditional_fairshare_runq_count(void)
2718 return fs_runq
.count
;
2722 sched_traditional_fairshare_runq_stats_count_sum(void)
2724 return fs_runq
.runq_stats
.count_sum
;
2728 sched_traditional_fairshare_enqueue(thread_t thread
)
2730 queue_t queue
= &fs_runq
.queue
;
2732 simple_lock(&fs_lock
);
2734 enqueue_tail(queue
, (queue_entry_t
)thread
);
2736 thread
->runq
= FS_RUNQ
;
2737 SCHED_STATS_RUNQ_CHANGE(&fs_runq
.runq_stats
, fs_runq
.count
);
2740 simple_unlock(&fs_lock
);
2744 sched_traditional_fairshare_dequeue(void)
2748 simple_lock(&fs_lock
);
2749 if (fs_runq
.count
> 0) {
2750 thread
= (thread_t
)dequeue_head(&fs_runq
.queue
);
2752 thread
->runq
= PROCESSOR_NULL
;
2753 SCHED_STATS_RUNQ_CHANGE(&fs_runq
.runq_stats
, fs_runq
.count
);
2756 simple_unlock(&fs_lock
);
2760 simple_unlock(&fs_lock
);
2766 sched_traditional_fairshare_queue_remove(thread_t thread
)
2770 simple_lock(&fs_lock
);
2773 if (FS_RUNQ
== thread
->runq
) {
2774 remqueue((queue_entry_t
)thread
);
2775 SCHED_STATS_RUNQ_CHANGE(&fs_runq
.runq_stats
, fs_runq
.count
);
2778 thread
->runq
= PROCESSOR_NULL
;
2779 simple_unlock(&fs_lock
);
2784 * The thread left the run queue before we could
2785 * lock the run queue.
2787 assert(thread
->runq
== PROCESSOR_NULL
);
2788 simple_unlock(&fs_lock
);
2793 #endif /* defined(CONFIG_SCHED_TRADITIONAL) || defined(CONFIG_SCHED_PROTO) || defined(CONFIG_SCHED_GRRR) || defined(CONFIG_SCHED_FIXEDPRIORITY) */
2796 * run_queue_dequeue:
2798 * Perform a dequeue operation on a run queue,
2799 * and return the resulting thread.
2801 * The run queue must be locked (see thread_run_queue_remove()
2802 * for more info), and not empty.
2810 queue_t queue
= rq
->queues
+ rq
->highq
;
2812 if (options
& SCHED_HEADQ
) {
2813 thread
= (thread_t
)dequeue_head(queue
);
2816 thread
= (thread_t
)dequeue_tail(queue
);
2819 thread
->runq
= PROCESSOR_NULL
;
2820 SCHED_STATS_RUNQ_CHANGE(&rq
->runq_stats
, rq
->count
);
2822 if (SCHED(priority_is_urgent
)(rq
->highq
)) {
2823 rq
->urgency
--; assert(rq
->urgency
>= 0);
2825 if (queue_empty(queue
)) {
2826 if (rq
->highq
!= IDLEPRI
)
2827 clrbit(MAXPRI
- rq
->highq
, rq
->bitmap
);
2828 rq
->highq
= MAXPRI
- ffsbit(rq
->bitmap
);
2835 * run_queue_enqueue:
2837 * Perform a enqueue operation on a run queue.
2839 * The run queue must be locked (see thread_run_queue_remove()
2848 queue_t queue
= rq
->queues
+ thread
->sched_pri
;
2849 boolean_t result
= FALSE
;
2851 if (queue_empty(queue
)) {
2852 enqueue_tail(queue
, (queue_entry_t
)thread
);
2854 setbit(MAXPRI
- thread
->sched_pri
, rq
->bitmap
);
2855 if (thread
->sched_pri
> rq
->highq
) {
2856 rq
->highq
= thread
->sched_pri
;
2861 if (options
& SCHED_TAILQ
)
2862 enqueue_tail(queue
, (queue_entry_t
)thread
);
2864 enqueue_head(queue
, (queue_entry_t
)thread
);
2866 if (SCHED(priority_is_urgent
)(thread
->sched_pri
))
2868 SCHED_STATS_RUNQ_CHANGE(&rq
->runq_stats
, rq
->count
);
2878 * Remove a specific thread from a runqueue.
2880 * The run queue must be locked.
2888 remqueue((queue_entry_t
)thread
);
2889 SCHED_STATS_RUNQ_CHANGE(&rq
->runq_stats
, rq
->count
);
2891 if (SCHED(priority_is_urgent
)(thread
->sched_pri
)) {
2892 rq
->urgency
--; assert(rq
->urgency
>= 0);
2895 if (queue_empty(rq
->queues
+ thread
->sched_pri
)) {
2896 /* update run queue status */
2897 if (thread
->sched_pri
!= IDLEPRI
)
2898 clrbit(MAXPRI
- thread
->sched_pri
, rq
->bitmap
);
2899 rq
->highq
= MAXPRI
- ffsbit(rq
->bitmap
);
2902 thread
->runq
= PROCESSOR_NULL
;
2908 * Dispatch a thread for round-robin execution.
2910 * Thread must be locked. Associated pset must
2911 * be locked, and is returned unlocked.
2915 processor_t processor
,
2918 processor_set_t pset
= processor
->processor_set
;
2920 thread
->chosen_processor
= processor
;
2922 SCHED(fairshare_enqueue
)(thread
);
2924 if (processor
!= current_processor())
2925 machine_signal_idle(processor
);
2932 * realtime_queue_insert:
2934 * Enqueue a thread for realtime execution.
2937 realtime_queue_insert(
2940 queue_t queue
= &rt_runq
.queue
;
2941 uint64_t deadline
= thread
->realtime
.deadline
;
2942 boolean_t preempt
= FALSE
;
2944 simple_lock(&rt_lock
);
2946 if (queue_empty(queue
)) {
2947 enqueue_tail(queue
, (queue_entry_t
)thread
);
2951 register thread_t entry
= (thread_t
)queue_first(queue
);
2954 if ( queue_end(queue
, (queue_entry_t
)entry
) ||
2955 deadline
< entry
->realtime
.deadline
) {
2956 entry
= (thread_t
)queue_prev((queue_entry_t
)entry
);
2960 entry
= (thread_t
)queue_next((queue_entry_t
)entry
);
2963 if ((queue_entry_t
)entry
== queue
)
2966 insque((queue_entry_t
)thread
, (queue_entry_t
)entry
);
2969 thread
->runq
= RT_RUNQ
;
2970 SCHED_STATS_RUNQ_CHANGE(&rt_runq
.runq_stats
, rt_runq
.count
);
2973 simple_unlock(&rt_lock
);
2981 * Dispatch a thread for realtime execution.
2983 * Thread must be locked. Associated pset must
2984 * be locked, and is returned unlocked.
2988 processor_t processor
,
2991 processor_set_t pset
= processor
->processor_set
;
2993 thread
->chosen_processor
= processor
;
2996 * Dispatch directly onto idle processor.
2998 if ( (thread
->bound_processor
== processor
)
2999 && processor
->state
== PROCESSOR_IDLE
) {
3000 remqueue((queue_entry_t
)processor
);
3001 enqueue_tail(&pset
->active_queue
, (queue_entry_t
)processor
);
3003 processor
->next_thread
= thread
;
3004 processor
->deadline
= thread
->realtime
.deadline
;
3005 processor
->state
= PROCESSOR_DISPATCHING
;
3008 if (processor
!= current_processor())
3009 machine_signal_idle(processor
);
3013 if (realtime_queue_insert(thread
)) {
3014 int prstate
= processor
->state
;
3015 if (processor
== current_processor())
3016 ast_on(AST_PREEMPT
| AST_URGENT
);
3017 else if ((prstate
== PROCESSOR_IDLE
) || (prstate
== PROCESSOR_DISPATCHING
))
3018 machine_signal_idle(processor
);
3020 cause_ast_check(processor
);
3026 #if defined(CONFIG_SCHED_TRADITIONAL)
3029 priority_is_urgent(int priority
)
3031 return testbit(priority
, sched_preempt_pri
) ? TRUE
: FALSE
;
3035 * processor_enqueue:
3037 * Enqueue thread on a processor run queue. Thread must be locked,
3038 * and not already be on a run queue.
3040 * Returns TRUE if a preemption is indicated based on the state
3043 * The run queue must be locked (see thread_run_queue_remove()
3048 processor_t processor
,
3052 run_queue_t rq
= runq_for_processor(processor
);
3055 result
= run_queue_enqueue(rq
, thread
, options
);
3056 thread
->runq
= processor
;
3057 runq_consider_incr_bound_count(processor
, thread
);
3062 #endif /* CONFIG_SCHED_TRADITIONAL */
3067 * Dispatch a thread for execution on a
3070 * Thread must be locked. Associated pset must
3071 * be locked, and is returned unlocked.
3075 processor_t processor
,
3079 processor_set_t pset
= processor
->processor_set
;
3082 thread
->chosen_processor
= processor
;
3085 * Dispatch directly onto idle processor.
3087 if ( (SCHED(direct_dispatch_to_idle_processors
) ||
3088 thread
->bound_processor
== processor
)
3089 && processor
->state
== PROCESSOR_IDLE
) {
3090 remqueue((queue_entry_t
)processor
);
3091 enqueue_tail(&pset
->active_queue
, (queue_entry_t
)processor
);
3093 processor
->next_thread
= thread
;
3094 processor
->deadline
= UINT64_MAX
;
3095 processor
->state
= PROCESSOR_DISPATCHING
;
3098 if (processor
!= current_processor())
3099 machine_signal_idle(processor
);
3104 * Set preemption mode.
3106 if (SCHED(priority_is_urgent
)(thread
->sched_pri
) && thread
->sched_pri
> processor
->current_pri
)
3107 preempt
= (AST_PREEMPT
| AST_URGENT
);
3108 else if(processor
->active_thread
&& thread_eager_preemption(processor
->active_thread
))
3109 preempt
= (AST_PREEMPT
| AST_URGENT
);
3111 if ((thread
->sched_mode
== TH_MODE_TIMESHARE
) && thread
->sched_pri
< thread
->priority
)
3114 preempt
= (options
& SCHED_PREEMPT
)? AST_PREEMPT
: AST_NONE
;
3116 if (!SCHED(processor_enqueue
)(processor
, thread
, options
))
3119 if (preempt
!= AST_NONE
) {
3120 if (processor
== current_processor()) {
3121 if (csw_check(processor
) != AST_NONE
)
3125 if ( processor
->state
== PROCESSOR_IDLE
|| processor
->state
== PROCESSOR_DISPATCHING
) {
3126 machine_signal_idle(processor
);
3129 if ( (processor
->state
== PROCESSOR_RUNNING
||
3130 processor
->state
== PROCESSOR_SHUTDOWN
) &&
3131 (thread
->sched_pri
>= processor
->current_pri
||
3132 processor
->current_thmode
== TH_MODE_FAIRSHARE
)) {
3133 cause_ast_check(processor
);
3137 if ( processor
->state
== PROCESSOR_SHUTDOWN
&&
3138 thread
->sched_pri
>= processor
->current_pri
) {
3139 cause_ast_check(processor
);
3142 if ( processor
->state
== PROCESSOR_IDLE
&&
3143 processor
!= current_processor() ) {
3144 machine_signal_idle(processor
);
3150 #if defined(CONFIG_SCHED_TRADITIONAL)
3153 processor_queue_empty(processor_t processor
)
3155 return runq_for_processor(processor
)->count
== 0;
3160 sched_traditional_with_pset_runqueue_processor_queue_empty(processor_t processor
)
3162 processor_set_t pset
= processor
->processor_set
;
3163 int count
= runq_for_processor(processor
)->count
;
3166 * The pset runq contains the count of all runnable threads
3167 * for all processors in the pset. However, for threads that
3168 * are bound to another processor, the current "processor"
3169 * is not eligible to execute the thread. So we only
3170 * include bound threads that our bound to the current
3171 * "processor". This allows the processor to idle when the
3172 * count of eligible threads drops to 0, even if there's
3173 * a runnable thread bound to a different processor in the
3177 count
-= pset
->pset_runq_bound_count
;
3178 count
+= processor
->runq_bound_count
;
3184 processor_csw_check(processor_t processor
)
3187 boolean_t has_higher
;
3189 assert(processor
->active_thread
!= NULL
);
3191 runq
= runq_for_processor(processor
);
3192 if (first_timeslice(processor
)) {
3193 has_higher
= (runq
->highq
> processor
->current_pri
);
3195 has_higher
= (runq
->highq
>= processor
->current_pri
);
3198 if (runq
->urgency
> 0)
3199 return (AST_PREEMPT
| AST_URGENT
);
3201 if (processor
->active_thread
&& thread_eager_preemption(processor
->active_thread
))
3202 return (AST_PREEMPT
| AST_URGENT
);
3211 processor_queue_has_priority(processor_t processor
,
3216 return runq_for_processor(processor
)->highq
>= priority
;
3218 return runq_for_processor(processor
)->highq
> priority
;
3222 should_current_thread_rechoose_processor(processor_t processor
)
3224 return (processor
->current_pri
< BASEPRI_RTQUEUES
3225 && processor
->processor_meta
!= PROCESSOR_META_NULL
3226 && processor
->processor_meta
->primary
!= processor
);
3230 sched_traditional_processor_runq_count(processor_t processor
)
3232 return runq_for_processor(processor
)->count
;
3237 sched_traditional_processor_runq_stats_count_sum(processor_t processor
)
3239 return runq_for_processor(processor
)->runq_stats
.count_sum
;
3243 sched_traditional_with_pset_runqueue_processor_runq_stats_count_sum(processor_t processor
)
3245 if (processor
->cpu_id
== processor
->processor_set
->cpu_set_low
)
3246 return runq_for_processor(processor
)->runq_stats
.count_sum
;
3251 #endif /* CONFIG_SCHED_TRADITIONAL */
3253 #define next_pset(p) (((p)->pset_list != PROCESSOR_SET_NULL)? (p)->pset_list: (p)->node->psets)
3258 * Return the next sibling pset containing
3259 * available processors.
3261 * Returns the original pset if none other is
3264 static processor_set_t
3266 processor_set_t pset
)
3268 processor_set_t nset
= pset
;
3271 nset
= next_pset(nset
);
3272 } while (nset
->online_processor_count
< 1 && nset
!= pset
);
3280 * Choose a processor for the thread, beginning at
3281 * the pset. Accepts an optional processor hint in
3284 * Returns a processor, possibly from a different pset.
3286 * The thread must be locked. The pset must be locked,
3287 * and the resulting pset is locked on return.
3291 processor_set_t pset
,
3292 processor_t processor
,
3295 processor_set_t nset
, cset
= pset
;
3296 processor_meta_t pmeta
= PROCESSOR_META_NULL
;
3297 processor_t mprocessor
;
3300 * Prefer the hinted processor, when appropriate.
3303 if (processor
!= PROCESSOR_NULL
) {
3304 if (processor
->processor_meta
!= PROCESSOR_META_NULL
)
3305 processor
= processor
->processor_meta
->primary
;
3308 mprocessor
= machine_choose_processor(pset
, processor
);
3309 if (mprocessor
!= PROCESSOR_NULL
)
3310 processor
= mprocessor
;
3312 if (processor
!= PROCESSOR_NULL
) {
3313 if (processor
->processor_set
!= pset
||
3314 processor
->state
== PROCESSOR_INACTIVE
||
3315 processor
->state
== PROCESSOR_SHUTDOWN
||
3316 processor
->state
== PROCESSOR_OFF_LINE
)
3317 processor
= PROCESSOR_NULL
;
3319 if (processor
->state
== PROCESSOR_IDLE
||
3320 ((thread
->sched_pri
>= BASEPRI_RTQUEUES
) &&
3321 (processor
->current_pri
< BASEPRI_RTQUEUES
)))
3326 * Iterate through the processor sets to locate
3327 * an appropriate processor.
3331 * Choose an idle processor.
3333 if (!queue_empty(&cset
->idle_queue
))
3334 return ((processor_t
)queue_first(&cset
->idle_queue
));
3336 if (thread
->sched_pri
>= BASEPRI_RTQUEUES
) {
3337 integer_t lowest_priority
= MAXPRI
+ 1;
3338 integer_t lowest_unpaired
= MAXPRI
+ 1;
3339 uint64_t furthest_deadline
= 1;
3340 processor_t lp_processor
= PROCESSOR_NULL
;
3341 processor_t lp_unpaired
= PROCESSOR_NULL
;
3342 processor_t fd_processor
= PROCESSOR_NULL
;
3344 lp_processor
= cset
->low_pri
;
3345 /* Consider hinted processor */
3346 if (lp_processor
!= PROCESSOR_NULL
&&
3347 ((lp_processor
->processor_meta
== PROCESSOR_META_NULL
) ||
3348 ((lp_processor
== lp_processor
->processor_meta
->primary
) &&
3349 !queue_empty(&lp_processor
->processor_meta
->idle_queue
))) &&
3350 lp_processor
->state
!= PROCESSOR_INACTIVE
&&
3351 lp_processor
->state
!= PROCESSOR_SHUTDOWN
&&
3352 lp_processor
->state
!= PROCESSOR_OFF_LINE
&&
3353 (lp_processor
->current_pri
< thread
->sched_pri
))
3354 return lp_processor
;
3356 processor
= (processor_t
)queue_first(&cset
->active_queue
);
3357 while (!queue_end(&cset
->active_queue
, (queue_entry_t
)processor
)) {
3358 /* Discover the processor executing the
3359 * thread with the lowest priority within
3360 * this pset, or the one with the furthest
3363 integer_t cpri
= processor
->current_pri
;
3364 if (cpri
< lowest_priority
) {
3365 lowest_priority
= cpri
;
3366 lp_processor
= processor
;
3369 if ((cpri
>= BASEPRI_RTQUEUES
) && (processor
->deadline
> furthest_deadline
)) {
3370 furthest_deadline
= processor
->deadline
;
3371 fd_processor
= processor
;
3375 if (processor
->processor_meta
!= PROCESSOR_META_NULL
&&
3376 !queue_empty(&processor
->processor_meta
->idle_queue
)) {
3377 if (cpri
< lowest_unpaired
) {
3378 lowest_unpaired
= cpri
;
3379 lp_unpaired
= processor
;
3380 pmeta
= processor
->processor_meta
;
3383 if (pmeta
== PROCESSOR_META_NULL
)
3384 pmeta
= processor
->processor_meta
;
3386 processor
= (processor_t
)queue_next((queue_entry_t
)processor
);
3389 if (thread
->sched_pri
> lowest_unpaired
)
3392 if (pmeta
!= PROCESSOR_META_NULL
)
3393 return ((processor_t
)queue_first(&pmeta
->idle_queue
));
3394 if (thread
->sched_pri
> lowest_priority
)
3395 return lp_processor
;
3396 if (thread
->realtime
.deadline
< furthest_deadline
)
3397 return fd_processor
;
3399 processor
= PROCESSOR_NULL
;
3403 * Check any hinted processors in the processor set if available.
3405 if (cset
->low_pri
!= PROCESSOR_NULL
&& cset
->low_pri
->state
!= PROCESSOR_INACTIVE
&&
3406 cset
->low_pri
->state
!= PROCESSOR_SHUTDOWN
&& cset
->low_pri
->state
!= PROCESSOR_OFF_LINE
&&
3407 (processor
== PROCESSOR_NULL
||
3408 (thread
->sched_pri
> BASEPRI_DEFAULT
&& cset
->low_pri
->current_pri
< thread
->sched_pri
))) {
3409 processor
= cset
->low_pri
;
3412 if (cset
->low_count
!= PROCESSOR_NULL
&& cset
->low_count
->state
!= PROCESSOR_INACTIVE
&&
3413 cset
->low_count
->state
!= PROCESSOR_SHUTDOWN
&& cset
->low_count
->state
!= PROCESSOR_OFF_LINE
&&
3414 (processor
== PROCESSOR_NULL
|| (thread
->sched_pri
<= BASEPRI_DEFAULT
&&
3415 SCHED(processor_runq_count
)(cset
->low_count
) < SCHED(processor_runq_count
)(processor
)))) {
3416 processor
= cset
->low_count
;
3420 * Otherwise, choose an available processor in the set.
3422 if (processor
== PROCESSOR_NULL
) {
3423 processor
= (processor_t
)dequeue_head(&cset
->active_queue
);
3424 if (processor
!= PROCESSOR_NULL
)
3425 enqueue_tail(&cset
->active_queue
, (queue_entry_t
)processor
);
3428 if (processor
!= PROCESSOR_NULL
&& pmeta
== PROCESSOR_META_NULL
) {
3429 if (processor
->processor_meta
!= PROCESSOR_META_NULL
&&
3430 !queue_empty(&processor
->processor_meta
->idle_queue
))
3431 pmeta
= processor
->processor_meta
;
3436 * Move onto the next processor set.
3438 nset
= next_pset(cset
);
3446 } while (nset
!= pset
);
3449 * Make sure that we pick a running processor,
3450 * and that the correct processor set is locked.
3453 if (pmeta
!= PROCESSOR_META_NULL
) {
3454 if (cset
!= pmeta
->primary
->processor_set
) {
3457 cset
= pmeta
->primary
->processor_set
;
3461 if (!queue_empty(&pmeta
->idle_queue
))
3462 return ((processor_t
)queue_first(&pmeta
->idle_queue
));
3464 pmeta
= PROCESSOR_META_NULL
;
3468 * If we haven't been able to choose a processor,
3469 * pick the boot processor and return it.
3471 if (processor
== PROCESSOR_NULL
) {
3472 processor
= master_processor
;
3475 * Check that the correct processor set is
3478 if (cset
!= processor
->processor_set
) {
3481 cset
= processor
->processor_set
;
3489 * Check that the processor set for the chosen
3490 * processor is locked.
3492 if (cset
!= processor
->processor_set
) {
3495 cset
= processor
->processor_set
;
3500 * We must verify that the chosen processor is still available.
3502 if (processor
->state
== PROCESSOR_INACTIVE
||
3503 processor
->state
== PROCESSOR_SHUTDOWN
|| processor
->state
== PROCESSOR_OFF_LINE
)
3504 processor
= PROCESSOR_NULL
;
3505 } while (processor
== PROCESSOR_NULL
);
3513 * Dispatch thread for execution, onto an idle
3514 * processor or run queue, and signal a preemption
3517 * Thread must be locked.
3524 processor_t processor
;
3525 processor_set_t pset
;
3528 assert(thread_runnable(thread
));
3532 * Update priority if needed.
3534 if (SCHED(can_update_priority
)(thread
))
3535 SCHED(update_priority
)(thread
);
3537 assert(thread
->runq
== PROCESSOR_NULL
);
3539 if (thread
->bound_processor
== PROCESSOR_NULL
) {
3543 if (thread
->affinity_set
!= AFFINITY_SET_NULL
) {
3545 * Use affinity set policy hint.
3547 pset
= thread
->affinity_set
->aset_pset
;
3550 processor
= SCHED(choose_processor
)(pset
, PROCESSOR_NULL
, thread
);
3553 if (thread
->last_processor
!= PROCESSOR_NULL
) {
3555 * Simple (last processor) affinity case.
3557 processor
= thread
->last_processor
;
3558 pset
= processor
->processor_set
;
3560 processor
= SCHED(choose_processor
)(pset
, processor
, thread
);
3562 if ((thread
->last_processor
!= processor
) && (thread
->last_processor
!= PROCESSOR_NULL
)) {
3563 KERNEL_DEBUG_CONSTANT(MACHDBG_CODE(DBG_MACH_SCHED
, MACH_SCHED_LPA_BROKEN
)|DBG_FUNC_NONE
,
3564 (uintptr_t)thread_tid(thread
), (uintptr_t)thread
->last_processor
->cpu_id
, (uintptr_t)processor
->cpu_id
, thread
->last_processor
->state
, 0);
3572 * Utilitize a per task hint to spread threads
3573 * among the available processor sets.
3575 task_t task
= thread
->task
;
3577 pset
= task
->pset_hint
;
3578 if (pset
== PROCESSOR_SET_NULL
)
3579 pset
= current_processor()->processor_set
;
3581 pset
= choose_next_pset(pset
);
3584 processor
= SCHED(choose_processor
)(pset
, PROCESSOR_NULL
, thread
);
3585 task
->pset_hint
= processor
->processor_set
;
3592 * Unconditionally dispatch on the processor.
3594 processor
= thread
->bound_processor
;
3595 pset
= processor
->processor_set
;
3600 * Dispatch the thread on the choosen processor.
3602 if (thread
->sched_pri
>= BASEPRI_RTQUEUES
)
3603 realtime_setrun(processor
, thread
);
3604 else if (thread
->sched_mode
== TH_MODE_FAIRSHARE
)
3605 fairshare_setrun(processor
, thread
);
3607 processor_setrun(processor
, thread
, options
);
3614 processor_set_t pset
= task
->pset_hint
;
3616 if (pset
!= PROCESSOR_SET_NULL
)
3617 pset
= choose_next_pset(pset
);
3622 #if defined(CONFIG_SCHED_TRADITIONAL)
3625 * processor_queue_shutdown:
3627 * Shutdown a processor run queue by
3628 * re-dispatching non-bound threads.
3630 * Associated pset must be locked, and is
3631 * returned unlocked.
3634 processor_queue_shutdown(
3635 processor_t processor
)
3637 processor_set_t pset
= processor
->processor_set
;
3638 run_queue_t rq
= runq_for_processor(processor
);
3639 queue_t queue
= rq
->queues
+ rq
->highq
;
3640 int pri
= rq
->highq
, count
= rq
->count
;
3641 thread_t next
, thread
;
3642 queue_head_t tqueue
;
3644 queue_init(&tqueue
);
3647 thread
= (thread_t
)queue_first(queue
);
3648 while (!queue_end(queue
, (queue_entry_t
)thread
)) {
3649 next
= (thread_t
)queue_next((queue_entry_t
)thread
);
3651 if (thread
->bound_processor
== PROCESSOR_NULL
) {
3652 remqueue((queue_entry_t
)thread
);
3654 thread
->runq
= PROCESSOR_NULL
;
3655 SCHED_STATS_RUNQ_CHANGE(&rq
->runq_stats
, rq
->count
);
3656 runq_consider_decr_bound_count(processor
, thread
);
3658 if (SCHED(priority_is_urgent
)(pri
)) {
3659 rq
->urgency
--; assert(rq
->urgency
>= 0);
3661 if (queue_empty(queue
)) {
3663 clrbit(MAXPRI
- pri
, rq
->bitmap
);
3664 rq
->highq
= MAXPRI
- ffsbit(rq
->bitmap
);
3667 enqueue_tail(&tqueue
, (queue_entry_t
)thread
);
3679 while ((thread
= (thread_t
)dequeue_head(&tqueue
)) != THREAD_NULL
) {
3680 thread_lock(thread
);
3682 thread_setrun(thread
, SCHED_TAILQ
);
3684 thread_unlock(thread
);
3688 #endif /* CONFIG_SCHED_TRADITIONAL */
3691 * Check for a preemption point in
3692 * the current context.
3694 * Called at splsched.
3698 processor_t processor
)
3700 ast_t result
= AST_NONE
;
3701 thread_t thread
= processor
->active_thread
;
3703 if (first_timeslice(processor
)) {
3704 if (rt_runq
.count
> 0)
3705 return (AST_PREEMPT
| AST_URGENT
);
3708 if (rt_runq
.count
> 0 && BASEPRI_RTQUEUES
>= processor
->current_pri
)
3709 return (AST_PREEMPT
| AST_URGENT
);
3712 result
= SCHED(processor_csw_check
)(processor
);
3713 if (result
!= AST_NONE
)
3716 if (SCHED(should_current_thread_rechoose_processor
)(processor
))
3717 return (AST_PREEMPT
);
3719 if (machine_processor_is_inactive(processor
))
3720 return (AST_PREEMPT
);
3722 if (thread
->state
& TH_SUSP
)
3723 return (AST_PREEMPT
);
3731 * Set the scheduled priority of the specified thread.
3733 * This may cause the thread to change queues.
3735 * Thread must be locked.
3742 boolean_t removed
= thread_run_queue_remove(thread
);
3744 thread
->sched_pri
= priority
;
3746 thread_setrun(thread
, SCHED_PREEMPT
| SCHED_TAILQ
);
3748 if (thread
->state
& TH_RUN
) {
3749 processor_t processor
= thread
->last_processor
;
3751 if (thread
== current_thread()) {
3754 processor
->current_pri
= priority
;
3755 processor
->current_thmode
= thread
->sched_mode
;
3756 if ((preempt
= csw_check(processor
)) != AST_NONE
)
3760 if ( processor
!= PROCESSOR_NULL
&&
3761 processor
->active_thread
== thread
)
3762 cause_ast_check(processor
);
3776 if (rq
!= thread
->runq
)
3777 panic("run_queue_check: thread runq");
3779 if (thread
->sched_pri
> MAXPRI
|| thread
->sched_pri
< MINPRI
)
3780 panic("run_queue_check: thread sched_pri");
3782 q
= &rq
->queues
[thread
->sched_pri
];
3783 qe
= queue_first(q
);
3784 while (!queue_end(q
, qe
)) {
3785 if (qe
== (queue_entry_t
)thread
)
3788 qe
= queue_next(qe
);
3791 panic("run_queue_check: end");
3796 #if defined(CONFIG_SCHED_TRADITIONAL)
3798 /* locks the runqueue itself */
3801 processor_queue_remove(
3802 processor_t processor
,
3808 rqlock
= &processor
->processor_set
->sched_lock
;
3809 rq
= runq_for_processor(processor
);
3811 simple_lock(rqlock
);
3812 if (processor
== thread
->runq
) {
3814 * Thread is on a run queue and we have a lock on
3817 runq_consider_decr_bound_count(processor
, thread
);
3818 run_queue_remove(rq
, thread
);
3822 * The thread left the run queue before we could
3823 * lock the run queue.
3825 assert(thread
->runq
== PROCESSOR_NULL
);
3826 processor
= PROCESSOR_NULL
;
3829 simple_unlock(rqlock
);
3831 return (processor
!= PROCESSOR_NULL
);
3834 #endif /* CONFIG_SCHED_TRADITIONAL */
3837 * thread_run_queue_remove:
3839 * Remove a thread from a current run queue and
3840 * return TRUE if successful.
3842 * Thread must be locked.
3845 thread_run_queue_remove(
3848 processor_t processor
= thread
->runq
;
3851 * If processor is PROCESSOR_NULL, the thread will stay out of the
3852 * run queues because the caller locked the thread. Otherwise
3853 * the thread is on a run queue, but could be chosen for dispatch
3856 if (processor
!= PROCESSOR_NULL
) {
3860 * The processor run queues are locked by the
3861 * processor set. Real-time priorities use a
3862 * global queue with a dedicated lock.
3864 if (thread
->sched_mode
== TH_MODE_FAIRSHARE
) {
3865 return SCHED(fairshare_queue_remove
)(thread
);
3868 if (thread
->sched_pri
< BASEPRI_RTQUEUES
) {
3869 return SCHED(processor_queue_remove
)(processor
, thread
);
3872 simple_lock(&rt_lock
);
3875 if (processor
== thread
->runq
) {
3877 * Thread is on a run queue and we have a lock on
3880 remqueue((queue_entry_t
)thread
);
3881 SCHED_STATS_RUNQ_CHANGE(&rt_runq
.runq_stats
, rt_runq
.count
);
3884 thread
->runq
= PROCESSOR_NULL
;
3888 * The thread left the run queue before we could
3889 * lock the run queue.
3891 assert(thread
->runq
== PROCESSOR_NULL
);
3892 processor
= PROCESSOR_NULL
;
3895 simple_unlock(&rt_lock
);
3898 return (processor
!= PROCESSOR_NULL
);
3901 #if defined(CONFIG_SCHED_TRADITIONAL)
3904 * steal_processor_thread:
3906 * Locate a thread to steal from the processor and
3909 * Associated pset must be locked. Returns THREAD_NULL
3913 steal_processor_thread(
3914 processor_t processor
)
3916 run_queue_t rq
= runq_for_processor(processor
);
3917 queue_t queue
= rq
->queues
+ rq
->highq
;
3918 int pri
= rq
->highq
, count
= rq
->count
;
3922 thread
= (thread_t
)queue_first(queue
);
3923 while (!queue_end(queue
, (queue_entry_t
)thread
)) {
3924 if (thread
->bound_processor
== PROCESSOR_NULL
) {
3925 remqueue((queue_entry_t
)thread
);
3927 thread
->runq
= PROCESSOR_NULL
;
3928 SCHED_STATS_RUNQ_CHANGE(&rq
->runq_stats
, rq
->count
);
3929 runq_consider_decr_bound_count(processor
, thread
);
3931 if (SCHED(priority_is_urgent
)(pri
)) {
3932 rq
->urgency
--; assert(rq
->urgency
>= 0);
3934 if (queue_empty(queue
)) {
3936 clrbit(MAXPRI
- pri
, rq
->bitmap
);
3937 rq
->highq
= MAXPRI
- ffsbit(rq
->bitmap
);
3944 thread
= (thread_t
)queue_next((queue_entry_t
)thread
);
3950 return (THREAD_NULL
);
3954 * Locate and steal a thread, beginning
3957 * The pset must be locked, and is returned
3960 * Returns the stolen thread, or THREAD_NULL on
3965 processor_set_t pset
)
3967 processor_set_t nset
, cset
= pset
;
3968 processor_t processor
;
3972 processor
= (processor_t
)queue_first(&cset
->active_queue
);
3973 while (!queue_end(&cset
->active_queue
, (queue_entry_t
)processor
)) {
3974 if (runq_for_processor(processor
)->count
> 0) {
3975 thread
= steal_processor_thread(processor
);
3976 if (thread
!= THREAD_NULL
) {
3977 remqueue((queue_entry_t
)processor
);
3978 enqueue_tail(&cset
->active_queue
, (queue_entry_t
)processor
);
3986 processor
= (processor_t
)queue_next((queue_entry_t
)processor
);
3989 nset
= next_pset(cset
);
3997 } while (nset
!= pset
);
4001 return (THREAD_NULL
);
4004 static thread_t
steal_thread_disabled(
4005 processor_set_t pset
)
4009 return (THREAD_NULL
);
4012 #endif /* CONFIG_SCHED_TRADITIONAL */
4016 thread_get_urgency(uint64_t *rt_period
, uint64_t *rt_deadline
)
4018 processor_t processor
;
4021 processor
= current_processor();
4023 thread
= processor
->next_thread
;
4025 if (thread
!= NULL
) {
4026 if (thread
->sched_mode
== TH_MODE_REALTIME
) {
4028 if (rt_period
!= NULL
)
4029 *rt_period
= thread
->realtime
.period
;
4030 if (rt_deadline
!= NULL
)
4031 *rt_deadline
= thread
->realtime
.deadline
;
4033 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_SCHED
, MACH_SCHED_GET_URGENCY
), THREAD_URGENCY_REAL_TIME
, thread
->realtime
.period
,
4034 (thread
->realtime
.deadline
>> 32), thread
->realtime
.deadline
, 0);
4036 return (THREAD_URGENCY_REAL_TIME
);
4037 } else if ((thread
->sched_pri
<= MAXPRI_THROTTLE
) &&
4038 (thread
->priority
<= MAXPRI_THROTTLE
)) {
4039 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_SCHED
, MACH_SCHED_GET_URGENCY
), THREAD_URGENCY_BACKGROUND
, thread
->sched_pri
, thread
->priority
, 0, 0);
4040 return (THREAD_URGENCY_BACKGROUND
);
4043 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_SCHED
, MACH_SCHED_GET_URGENCY
), THREAD_URGENCY_NORMAL
, 0, 0, 0, 0);
4045 return (THREAD_URGENCY_NORMAL
);
4048 KERNEL_DEBUG(MACHDBG_CODE(DBG_MACH_SCHED
, MACH_SCHED_GET_URGENCY
), THREAD_URGENCY_NONE
, 0, 0, 0, 0);
4049 return (THREAD_URGENCY_NONE
);
4054 * This is the processor idle loop, which just looks for other threads
4055 * to execute. Processor idle threads invoke this without supplying a
4056 * current thread to idle without an asserted wait state.
4058 * Returns a the next thread to execute if dispatched directly.
4062 #define IDLE_KERNEL_DEBUG_CONSTANT(...) KERNEL_DEBUG_CONSTANT(__VA_ARGS__)
4064 #define IDLE_KERNEL_DEBUG_CONSTANT(...) do { } while(0)
4070 processor_t processor
)
4072 processor_set_t pset
= processor
->processor_set
;
4073 thread_t new_thread
;
4077 KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE
,
4078 MACHDBG_CODE(DBG_MACH_SCHED
,MACH_IDLE
) | DBG_FUNC_START
,
4079 (uintptr_t)thread_tid(thread
), 0, 0, 0, 0);
4081 SCHED_STATS_CPU_IDLE_START(processor
);
4083 timer_switch(&PROCESSOR_DATA(processor
, system_state
),
4084 mach_absolute_time(), &PROCESSOR_DATA(processor
, idle_state
));
4085 PROCESSOR_DATA(processor
, current_state
) = &PROCESSOR_DATA(processor
, idle_state
);
4087 while (processor
->next_thread
== THREAD_NULL
&& SCHED(processor_queue_empty
)(processor
) && rt_runq
.count
== 0 && SCHED(fairshare_runq_count
)() == 0 &&
4088 (thread
== THREAD_NULL
|| ((thread
->state
& (TH_WAIT
|TH_SUSP
)) == TH_WAIT
&& !thread
->wake_active
))) {
4089 IDLE_KERNEL_DEBUG_CONSTANT(
4090 MACHDBG_CODE(DBG_MACH_SCHED
,MACH_IDLE
) | DBG_FUNC_NONE
, (uintptr_t)thread_tid(thread
), rt_runq
.count
, SCHED(processor_runq_count
)(processor
), -1, 0);
4092 machine_track_platform_idle(TRUE
);
4096 machine_track_platform_idle(FALSE
);
4100 IDLE_KERNEL_DEBUG_CONSTANT(
4101 MACHDBG_CODE(DBG_MACH_SCHED
,MACH_IDLE
) | DBG_FUNC_NONE
, (uintptr_t)thread_tid(thread
), rt_runq
.count
, SCHED(processor_runq_count
)(processor
), -2, 0);
4103 if (processor
->state
== PROCESSOR_INACTIVE
&& !machine_processor_is_inactive(processor
))
4107 timer_switch(&PROCESSOR_DATA(processor
, idle_state
),
4108 mach_absolute_time(), &PROCESSOR_DATA(processor
, system_state
));
4109 PROCESSOR_DATA(processor
, current_state
) = &PROCESSOR_DATA(processor
, system_state
);
4113 state
= processor
->state
;
4114 if (state
== PROCESSOR_DISPATCHING
) {
4116 * Commmon case -- cpu dispatched.
4118 new_thread
= processor
->next_thread
;
4119 processor
->next_thread
= THREAD_NULL
;
4120 processor
->state
= PROCESSOR_RUNNING
;
4122 if (SCHED(processor_queue_has_priority
)(processor
, new_thread
->sched_pri
, FALSE
) ||
4123 (rt_runq
.count
> 0 && BASEPRI_RTQUEUES
>= new_thread
->sched_pri
) ) {
4124 processor
->deadline
= UINT64_MAX
;
4128 thread_lock(new_thread
);
4129 KERNEL_DEBUG_CONSTANT(MACHDBG_CODE(DBG_MACH_SCHED
, MACH_REDISPATCH
), (uintptr_t)thread_tid(new_thread
), new_thread
->sched_pri
, rt_runq
.count
, 0, 0);
4130 thread_setrun(new_thread
, SCHED_HEADQ
);
4131 thread_unlock(new_thread
);
4133 KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE
,
4134 MACHDBG_CODE(DBG_MACH_SCHED
,MACH_IDLE
) | DBG_FUNC_END
,
4135 (uintptr_t)thread_tid(thread
), state
, 0, 0, 0);
4137 return (THREAD_NULL
);
4142 KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE
,
4143 MACHDBG_CODE(DBG_MACH_SCHED
,MACH_IDLE
) | DBG_FUNC_END
,
4144 (uintptr_t)thread_tid(thread
), state
, (uintptr_t)thread_tid(new_thread
), 0, 0);
4146 return (new_thread
);
4149 if (state
== PROCESSOR_IDLE
) {
4150 remqueue((queue_entry_t
)processor
);
4152 processor
->state
= PROCESSOR_RUNNING
;
4153 enqueue_tail(&pset
->active_queue
, (queue_entry_t
)processor
);
4156 if (state
== PROCESSOR_INACTIVE
) {
4157 processor
->state
= PROCESSOR_RUNNING
;
4158 enqueue_tail(&pset
->active_queue
, (queue_entry_t
)processor
);
4161 if (state
== PROCESSOR_SHUTDOWN
) {
4163 * Going off-line. Force a
4166 if ((new_thread
= processor
->next_thread
) != THREAD_NULL
) {
4167 processor
->next_thread
= THREAD_NULL
;
4168 processor
->deadline
= UINT64_MAX
;
4172 thread_lock(new_thread
);
4173 thread_setrun(new_thread
, SCHED_HEADQ
);
4174 thread_unlock(new_thread
);
4176 KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE
,
4177 MACHDBG_CODE(DBG_MACH_SCHED
,MACH_IDLE
) | DBG_FUNC_END
,
4178 (uintptr_t)thread_tid(thread
), state
, 0, 0, 0);
4180 return (THREAD_NULL
);
4186 KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE
,
4187 MACHDBG_CODE(DBG_MACH_SCHED
,MACH_IDLE
) | DBG_FUNC_END
,
4188 (uintptr_t)thread_tid(thread
), state
, 0, 0, 0);
4190 return (THREAD_NULL
);
4194 * Each processor has a dedicated thread which
4195 * executes the idle loop when there is no suitable
4201 processor_t processor
= current_processor();
4202 thread_t new_thread
;
4204 new_thread
= processor_idle(THREAD_NULL
, processor
);
4205 if (new_thread
!= THREAD_NULL
) {
4206 thread_run(processor
->idle_thread
, (thread_continue_t
)idle_thread
, NULL
, new_thread
);
4210 thread_block((thread_continue_t
)idle_thread
);
4216 processor_t processor
)
4218 kern_return_t result
;
4222 result
= kernel_thread_create((thread_continue_t
)idle_thread
, NULL
, MAXPRI_KERNEL
, &thread
);
4223 if (result
!= KERN_SUCCESS
)
4227 thread_lock(thread
);
4228 thread
->bound_processor
= processor
;
4229 processor
->idle_thread
= thread
;
4230 thread
->sched_pri
= thread
->priority
= IDLEPRI
;
4231 thread
->state
= (TH_RUN
| TH_IDLE
);
4232 thread_unlock(thread
);
4235 thread_deallocate(thread
);
4237 return (KERN_SUCCESS
);
4243 * Kicks off scheduler services.
4245 * Called at splsched.
4250 kern_return_t result
;
4253 result
= kernel_thread_start_priority((thread_continue_t
)sched_init_thread
,
4254 (void *)SCHED(maintenance_continuation
),
4255 MAXPRI_KERNEL
, &thread
);
4256 if (result
!= KERN_SUCCESS
)
4257 panic("sched_startup");
4259 thread_deallocate(thread
);
4262 * Yield to the sched_init_thread once, to
4263 * initialize our own thread after being switched
4266 * The current thread is the only other thread
4267 * active at this point.
4269 thread_block(THREAD_CONTINUE_NULL
);
4272 #if defined(CONFIG_SCHED_TRADITIONAL)
4274 static uint64_t sched_tick_deadline
= 0;
4277 * sched_init_thread:
4279 * Perform periodic bookkeeping functions about ten
4283 sched_traditional_tick_continue(void)
4285 uint64_t abstime
= mach_absolute_time();
4290 * Compute various averages.
4295 * Scan the run queues for threads which
4296 * may need to be updated.
4298 thread_update_scan();
4300 if (sched_tick_deadline
== 0)
4301 sched_tick_deadline
= abstime
;
4303 clock_deadline_for_periodic_event(sched_tick_interval
, abstime
,
4304 &sched_tick_deadline
);
4306 assert_wait_deadline((event_t
)sched_traditional_tick_continue
, THREAD_UNINT
, sched_tick_deadline
);
4307 thread_block((thread_continue_t
)sched_traditional_tick_continue
);
4311 #endif /* CONFIG_SCHED_TRADITIONAL */
4314 sched_init_thread(void (*continuation
)(void))
4316 thread_block(THREAD_CONTINUE_NULL
);
4323 #if defined(CONFIG_SCHED_TRADITIONAL)
4326 * thread_update_scan / runq_scan:
4328 * Scan the run queues to account for timesharing threads
4329 * which need to be updated.
4331 * Scanner runs in two passes. Pass one squirrels likely
4332 * threads away in an array, pass two does the update.
4334 * This is necessary because the run queue is locked for
4335 * the candidate scan, but the thread is locked for the update.
4337 * Array should be sized to make forward progress, without
4338 * disabling preemption for long periods.
4341 #define THREAD_UPDATE_SIZE 128
4343 static thread_t thread_update_array
[THREAD_UPDATE_SIZE
];
4344 static int thread_update_count
= 0;
4347 * Scan a runq for candidate threads.
4349 * Returns TRUE if retry is needed.
4357 register thread_t thread
;
4359 if ((count
= runq
->count
) > 0) {
4360 q
= runq
->queues
+ runq
->highq
;
4362 queue_iterate(q
, thread
, thread_t
, links
) {
4363 if ( thread
->sched_stamp
!= sched_tick
&&
4364 (thread
->sched_mode
== TH_MODE_TIMESHARE
) ) {
4365 if (thread_update_count
== THREAD_UPDATE_SIZE
)
4368 thread_update_array
[thread_update_count
++] = thread
;
4369 thread_reference_internal(thread
);
4383 thread_update_scan(void)
4385 boolean_t restart_needed
= FALSE
;
4386 processor_t processor
= processor_list
;
4387 processor_set_t pset
;
4393 pset
= processor
->processor_set
;
4398 restart_needed
= runq_scan(runq_for_processor(processor
));
4406 thread
= processor
->idle_thread
;
4407 if (thread
!= THREAD_NULL
&& thread
->sched_stamp
!= sched_tick
) {
4408 if (thread_update_count
== THREAD_UPDATE_SIZE
) {
4409 restart_needed
= TRUE
;
4413 thread_update_array
[thread_update_count
++] = thread
;
4414 thread_reference_internal(thread
);
4416 } while ((processor
= processor
->processor_list
) != NULL
);
4419 * Ok, we now have a collection of candidates -- fix them.
4421 while (thread_update_count
> 0) {
4422 thread
= thread_update_array
[--thread_update_count
];
4423 thread_update_array
[thread_update_count
] = THREAD_NULL
;
4426 thread_lock(thread
);
4427 if ( !(thread
->state
& (TH_WAIT
)) ) {
4428 if (SCHED(can_update_priority
)(thread
))
4429 SCHED(update_priority
)(thread
);
4431 thread_unlock(thread
);
4434 thread_deallocate(thread
);
4436 } while (restart_needed
);
4439 #endif /* CONFIG_SCHED_TRADITIONAL */
4442 thread_eager_preemption(thread_t thread
)
4444 return ((thread
->sched_flags
& TH_SFLAG_EAGERPREEMPT
) != 0);
4448 thread_set_eager_preempt(thread_t thread
)
4452 ast_t ast
= AST_NONE
;
4455 p
= current_processor();
4457 thread_lock(thread
);
4458 thread
->sched_flags
|= TH_SFLAG_EAGERPREEMPT
;
4460 if (thread
== current_thread()) {
4461 thread_unlock(thread
);
4464 if (ast
!= AST_NONE
) {
4465 (void) thread_block_reason(THREAD_CONTINUE_NULL
, NULL
, ast
);
4468 p
= thread
->last_processor
;
4470 if (p
!= PROCESSOR_NULL
&& p
->state
== PROCESSOR_RUNNING
&&
4471 p
->active_thread
== thread
) {
4475 thread_unlock(thread
);
4482 thread_clear_eager_preempt(thread_t thread
)
4487 thread_lock(thread
);
4489 thread
->sched_flags
&= ~TH_SFLAG_EAGERPREEMPT
;
4491 thread_unlock(thread
);
4495 * Scheduling statistics
4498 sched_stats_handle_csw(processor_t processor
, int reasons
, int selfpri
, int otherpri
)
4500 struct processor_sched_statistics
*stats
;
4501 boolean_t to_realtime
= FALSE
;
4503 stats
= &processor
->processor_data
.sched_stats
;
4506 if (otherpri
>= BASEPRI_REALTIME
) {
4507 stats
->rt_sched_count
++;
4511 if ((reasons
& AST_PREEMPT
) != 0) {
4512 stats
->preempt_count
++;
4514 if (selfpri
>= BASEPRI_REALTIME
) {
4515 stats
->preempted_rt_count
++;
4519 stats
->preempted_by_rt_count
++;
4526 sched_stats_handle_runq_change(struct runq_stats
*stats
, int old_count
)
4528 uint64_t timestamp
= mach_absolute_time();
4530 stats
->count_sum
+= (timestamp
- stats
->last_change_timestamp
) * old_count
;
4531 stats
->last_change_timestamp
= timestamp
;
4535 * For calls from assembly code
4537 #undef thread_wakeup
4546 thread_wakeup_with_result(x
, THREAD_AWAKENED
);
4550 preemption_enabled(void)
4552 return (get_preemption_level() == 0 && ml_get_interrupts_enabled());
4560 return ((thread
->state
& (TH_RUN
|TH_WAIT
)) == TH_RUN
);
4565 sched_timer_deadline_tracking_init(void) {
4566 nanoseconds_to_absolutetime(TIMER_DEADLINE_TRACKING_BIN_1_DEFAULT
, &timer_deadline_tracking_bin_1
);
4567 nanoseconds_to_absolutetime(TIMER_DEADLINE_TRACKING_BIN_2_DEFAULT
, &timer_deadline_tracking_bin_2
);