]> git.saurik.com Git - apple/xnu.git/blob - osfmk/kern/sched_prim.c
xnu-1228.7.58.tar.gz
[apple/xnu.git] / osfmk / kern / sched_prim.c
1 /*
2 * Copyright (c) 2000-2008 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
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.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
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.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28 /*
29 * @OSF_FREE_COPYRIGHT@
30 */
31 /*
32 * Mach Operating System
33 * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
34 * All Rights Reserved.
35 *
36 * Permission to use, copy, modify and distribute this software and its
37 * documentation is hereby granted, provided that both the copyright
38 * notice and this permission notice appear in all copies of the
39 * software, derivative works or modified versions, and any portions
40 * thereof, and that both notices appear in supporting documentation.
41 *
42 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
43 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
44 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
45 *
46 * Carnegie Mellon requests users of this software to return to
47 *
48 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
49 * School of Computer Science
50 * Carnegie Mellon University
51 * Pittsburgh PA 15213-3890
52 *
53 * any improvements or extensions that they make and grant Carnegie Mellon
54 * the rights to redistribute these changes.
55 */
56 /*
57 */
58 /*
59 * File: sched_prim.c
60 * Author: Avadis Tevanian, Jr.
61 * Date: 1986
62 *
63 * Scheduling primitives
64 *
65 */
66
67 #include <debug.h>
68 #include <mach_kdb.h>
69
70 #include <ddb/db_output.h>
71
72 #include <mach/mach_types.h>
73 #include <mach/machine.h>
74 #include <mach/policy.h>
75 #include <mach/sync_policy.h>
76
77 #include <machine/machine_routines.h>
78 #include <machine/sched_param.h>
79 #include <machine/machine_cpu.h>
80
81 #include <kern/kern_types.h>
82 #include <kern/clock.h>
83 #include <kern/counters.h>
84 #include <kern/cpu_number.h>
85 #include <kern/cpu_data.h>
86 #include <kern/debug.h>
87 #include <kern/lock.h>
88 #include <kern/macro_help.h>
89 #include <kern/machine.h>
90 #include <kern/misc_protos.h>
91 #include <kern/processor.h>
92 #include <kern/queue.h>
93 #include <kern/sched.h>
94 #include <kern/sched_prim.h>
95 #include <kern/syscall_subr.h>
96 #include <kern/task.h>
97 #include <kern/thread.h>
98 #include <kern/wait_queue.h>
99
100 #include <vm/pmap.h>
101 #include <vm/vm_kern.h>
102 #include <vm/vm_map.h>
103
104 #include <sys/kdebug.h>
105
106 #include <kern/pms.h>
107
108 struct run_queue rt_runq;
109 #define RT_RUNQ ((processor_t)-1)
110 decl_simple_lock_data(static,rt_lock);
111
112 #define DEFAULT_PREEMPTION_RATE 100 /* (1/s) */
113 int default_preemption_rate = DEFAULT_PREEMPTION_RATE;
114
115 #define MAX_UNSAFE_QUANTA 800
116 int max_unsafe_quanta = MAX_UNSAFE_QUANTA;
117
118 #define MAX_POLL_QUANTA 2
119 int max_poll_quanta = MAX_POLL_QUANTA;
120
121 #define SCHED_POLL_YIELD_SHIFT 4 /* 1/16 */
122 int sched_poll_yield_shift = SCHED_POLL_YIELD_SHIFT;
123
124 uint64_t max_unsafe_computation;
125 uint32_t sched_safe_duration;
126 uint64_t max_poll_computation;
127
128 uint32_t std_quantum;
129 uint32_t min_std_quantum;
130
131 uint32_t std_quantum_us;
132
133 uint32_t max_rt_quantum;
134 uint32_t min_rt_quantum;
135
136 uint32_t sched_cswtime;
137
138 unsigned sched_tick;
139 uint32_t sched_tick_interval;
140
141 uint32_t sched_pri_shift = INT8_MAX;
142 uint32_t sched_fixed_shift;
143
144 uint32_t sched_run_count, sched_share_count;
145 uint32_t sched_load_average, sched_mach_factor;
146
147 /* Forwards */
148 void wait_queues_init(void) __attribute__((section("__TEXT, initcode")));
149
150 static void load_shift_init(void) __attribute__((section("__TEXT, initcode")));
151 static void preempt_pri_init(void) __attribute__((section("__TEXT, initcode")));
152
153 static thread_t thread_select_idle(
154 thread_t thread,
155 processor_t processor);
156
157 static thread_t processor_idle(
158 thread_t thread,
159 processor_t processor);
160
161 static thread_t choose_thread(
162 processor_t processor);
163
164 static thread_t steal_thread(
165 processor_set_t pset);
166
167 static thread_t steal_processor_thread(
168 processor_t processor);
169
170 static void thread_update_scan(void);
171
172 #if DEBUG
173 extern int debug_task;
174 #define TLOG(a, fmt, args...) if(debug_task & a) kprintf(fmt, ## args)
175 #else
176 #define TLOG(a, fmt, args...) do {} while (0)
177 #endif
178
179 #if DEBUG
180 static
181 boolean_t thread_runnable(
182 thread_t thread);
183
184 #endif /*DEBUG*/
185
186 /*
187 * State machine
188 *
189 * states are combinations of:
190 * R running
191 * W waiting (or on wait queue)
192 * N non-interruptible
193 * O swapped out
194 * I being swapped in
195 *
196 * init action
197 * assert_wait thread_block clear_wait swapout swapin
198 *
199 * R RW, RWN R; setrun - -
200 * RN RWN RN; setrun - -
201 *
202 * RW W R -
203 * RWN WN RN -
204 *
205 * W R; setrun WO
206 * WN RN; setrun -
207 *
208 * RO - - R
209 *
210 */
211
212 /*
213 * Waiting protocols and implementation:
214 *
215 * Each thread may be waiting for exactly one event; this event
216 * is set using assert_wait(). That thread may be awakened either
217 * by performing a thread_wakeup_prim() on its event,
218 * or by directly waking that thread up with clear_wait().
219 *
220 * The implementation of wait events uses a hash table. Each
221 * bucket is queue of threads having the same hash function
222 * value; the chain for the queue (linked list) is the run queue
223 * field. [It is not possible to be waiting and runnable at the
224 * same time.]
225 *
226 * Locks on both the thread and on the hash buckets govern the
227 * wait event field and the queue chain field. Because wakeup
228 * operations only have the event as an argument, the event hash
229 * bucket must be locked before any thread.
230 *
231 * Scheduling operations may also occur at interrupt level; therefore,
232 * interrupts below splsched() must be prevented when holding
233 * thread or hash bucket locks.
234 *
235 * The wait event hash table declarations are as follows:
236 */
237
238 #define NUMQUEUES 59
239
240 struct wait_queue wait_queues[NUMQUEUES];
241
242 #define wait_hash(event) \
243 ((((int)(event) < 0)? ~(int)(event): (int)(event)) % NUMQUEUES)
244
245 int8_t sched_load_shifts[NRQS];
246 int sched_preempt_pri[NRQBM];
247
248 void
249 sched_init(void)
250 {
251 /*
252 * Calculate the timeslicing quantum
253 * in us.
254 */
255 if (default_preemption_rate < 1)
256 default_preemption_rate = DEFAULT_PREEMPTION_RATE;
257 std_quantum_us = (1000 * 1000) / default_preemption_rate;
258
259 printf("standard timeslicing quantum is %d us\n", std_quantum_us);
260
261 sched_safe_duration = (2 * max_unsafe_quanta / default_preemption_rate) *
262 (1 << SCHED_TICK_SHIFT);
263
264 wait_queues_init();
265 load_shift_init();
266 preempt_pri_init();
267 simple_lock_init(&rt_lock, 0);
268 run_queue_init(&rt_runq);
269 sched_tick = 0;
270 ast_init();
271 }
272
273 void
274 sched_timebase_init(void)
275 {
276 uint64_t abstime;
277 uint32_t shift;
278
279 /* standard timeslicing quantum */
280 clock_interval_to_absolutetime_interval(
281 std_quantum_us, NSEC_PER_USEC, &abstime);
282 assert((abstime >> 32) == 0 && (uint32_t)abstime != 0);
283 std_quantum = abstime;
284
285 /* smallest remaining quantum (250 us) */
286 clock_interval_to_absolutetime_interval(250, NSEC_PER_USEC, &abstime);
287 assert((abstime >> 32) == 0 && (uint32_t)abstime != 0);
288 min_std_quantum = abstime;
289
290 /* smallest rt computaton (50 us) */
291 clock_interval_to_absolutetime_interval(50, NSEC_PER_USEC, &abstime);
292 assert((abstime >> 32) == 0 && (uint32_t)abstime != 0);
293 min_rt_quantum = abstime;
294
295 /* maximum rt computation (50 ms) */
296 clock_interval_to_absolutetime_interval(
297 50, 1000*NSEC_PER_USEC, &abstime);
298 assert((abstime >> 32) == 0 && (uint32_t)abstime != 0);
299 max_rt_quantum = abstime;
300
301 /* scheduler tick interval */
302 clock_interval_to_absolutetime_interval(USEC_PER_SEC >> SCHED_TICK_SHIFT,
303 NSEC_PER_USEC, &abstime);
304 assert((abstime >> 32) == 0 && (uint32_t)abstime != 0);
305 sched_tick_interval = abstime;
306
307 /*
308 * Compute conversion factor from usage to
309 * timesharing priorities with 5/8 ** n aging.
310 */
311 abstime = (abstime * 5) / 3;
312 for (shift = 0; abstime > BASEPRI_DEFAULT; ++shift)
313 abstime >>= 1;
314 sched_fixed_shift = shift;
315
316 max_unsafe_computation = max_unsafe_quanta * std_quantum;
317 max_poll_computation = max_poll_quanta * std_quantum;
318 }
319
320 void
321 wait_queues_init(void)
322 {
323 register int i;
324
325 for (i = 0; i < NUMQUEUES; i++) {
326 wait_queue_init(&wait_queues[i], SYNC_POLICY_FIFO);
327 }
328 }
329
330 /*
331 * Set up values for timeshare
332 * loading factors.
333 */
334 static void
335 load_shift_init(void)
336 {
337 int8_t k, *p = sched_load_shifts;
338 uint32_t i, j;
339
340 *p++ = INT8_MIN; *p++ = 0;
341
342 for (i = j = 2, k = 1; i < NRQS; ++k) {
343 for (j <<= 1; i < j; ++i)
344 *p++ = k;
345 }
346 }
347
348 static void
349 preempt_pri_init(void)
350 {
351 int i, *p = sched_preempt_pri;
352
353 for (i = BASEPRI_FOREGROUND + 1; i < MINPRI_KERNEL; ++i)
354 setbit(i, p);
355
356 for (i = BASEPRI_PREEMPT; i <= MAXPRI; ++i)
357 setbit(i, p);
358 }
359
360 /*
361 * Thread wait timer expiration.
362 */
363 void
364 thread_timer_expire(
365 void *p0,
366 __unused void *p1)
367 {
368 thread_t thread = p0;
369 spl_t s;
370
371 s = splsched();
372 thread_lock(thread);
373 if (--thread->wait_timer_active == 0) {
374 if (thread->wait_timer_is_set) {
375 thread->wait_timer_is_set = FALSE;
376 clear_wait_internal(thread, THREAD_TIMED_OUT);
377 }
378 }
379 thread_unlock(thread);
380 splx(s);
381 }
382
383 /*
384 * thread_set_timer:
385 *
386 * Set a timer for the current thread, if the thread
387 * is ready to wait. Must be called between assert_wait()
388 * and thread_block().
389 */
390 void
391 thread_set_timer(
392 uint32_t interval,
393 uint32_t scale_factor)
394 {
395 thread_t thread = current_thread();
396 uint64_t deadline;
397 spl_t s;
398
399 s = splsched();
400 thread_lock(thread);
401 if ((thread->state & TH_WAIT) != 0) {
402 clock_interval_to_deadline(interval, scale_factor, &deadline);
403 if (!timer_call_enter(&thread->wait_timer, deadline))
404 thread->wait_timer_active++;
405 thread->wait_timer_is_set = TRUE;
406 }
407 thread_unlock(thread);
408 splx(s);
409 }
410
411 void
412 thread_set_timer_deadline(
413 uint64_t deadline)
414 {
415 thread_t thread = current_thread();
416 spl_t s;
417
418 s = splsched();
419 thread_lock(thread);
420 if ((thread->state & TH_WAIT) != 0) {
421 if (!timer_call_enter(&thread->wait_timer, deadline))
422 thread->wait_timer_active++;
423 thread->wait_timer_is_set = TRUE;
424 }
425 thread_unlock(thread);
426 splx(s);
427 }
428
429 void
430 thread_cancel_timer(void)
431 {
432 thread_t thread = current_thread();
433 spl_t s;
434
435 s = splsched();
436 thread_lock(thread);
437 if (thread->wait_timer_is_set) {
438 if (timer_call_cancel(&thread->wait_timer))
439 thread->wait_timer_active--;
440 thread->wait_timer_is_set = FALSE;
441 }
442 thread_unlock(thread);
443 splx(s);
444 }
445
446 /*
447 * thread_unblock:
448 *
449 * Unblock thread on wake up.
450 *
451 * Returns TRUE if the thread is still running.
452 *
453 * Thread must be locked.
454 */
455 boolean_t
456 thread_unblock(
457 thread_t thread,
458 wait_result_t wresult)
459 {
460 boolean_t result = FALSE;
461
462 /*
463 * Set wait_result.
464 */
465 thread->wait_result = wresult;
466
467 /*
468 * Cancel pending wait timer.
469 */
470 if (thread->wait_timer_is_set) {
471 if (timer_call_cancel(&thread->wait_timer))
472 thread->wait_timer_active--;
473 thread->wait_timer_is_set = FALSE;
474 }
475
476 /*
477 * Update scheduling state: not waiting,
478 * set running.
479 */
480 thread->state &= ~(TH_WAIT|TH_UNINT);
481
482 if (!(thread->state & TH_RUN)) {
483 thread->state |= TH_RUN;
484
485 (*thread->sched_call)(SCHED_CALL_UNBLOCK, thread);
486
487 /*
488 * Update run counts.
489 */
490 sched_run_incr();
491 if (thread->sched_mode & TH_MODE_TIMESHARE)
492 sched_share_incr();
493 }
494 else {
495 /*
496 * Signal if idling on another processor.
497 */
498 if (thread->state & TH_IDLE) {
499 processor_t processor = thread->last_processor;
500
501 if (processor != current_processor())
502 machine_signal_idle(processor);
503 }
504
505 result = TRUE;
506 }
507
508 /*
509 * Calculate deadline for real-time threads.
510 */
511 if (thread->sched_mode & TH_MODE_REALTIME) {
512 thread->realtime.deadline = mach_absolute_time();
513 thread->realtime.deadline += thread->realtime.constraint;
514 }
515
516 /*
517 * Clear old quantum, fail-safe computation, etc.
518 */
519 thread->current_quantum = 0;
520 thread->computation_metered = 0;
521 thread->reason = AST_NONE;
522
523 KERNEL_DEBUG_CONSTANT(
524 MACHDBG_CODE(DBG_MACH_SCHED,MACH_MAKE_RUNNABLE) | DBG_FUNC_NONE,
525 (int)thread, (int)thread->sched_pri, 0, 0, 0);
526
527 return (result);
528 }
529
530 /*
531 * Routine: thread_go
532 * Purpose:
533 * Unblock and dispatch thread.
534 * Conditions:
535 * thread lock held, IPC locks may be held.
536 * thread must have been pulled from wait queue under same lock hold.
537 * Returns:
538 * KERN_SUCCESS - Thread was set running
539 * KERN_NOT_WAITING - Thread was not waiting
540 */
541 kern_return_t
542 thread_go(
543 thread_t thread,
544 wait_result_t wresult)
545 {
546 assert(thread->at_safe_point == FALSE);
547 assert(thread->wait_event == NO_EVENT64);
548 assert(thread->wait_queue == WAIT_QUEUE_NULL);
549
550 if ((thread->state & (TH_WAIT|TH_TERMINATE)) == TH_WAIT) {
551 if (!thread_unblock(thread, wresult))
552 thread_setrun(thread, SCHED_PREEMPT | SCHED_TAILQ);
553
554 return (KERN_SUCCESS);
555 }
556
557 return (KERN_NOT_WAITING);
558 }
559
560 /*
561 * Routine: thread_mark_wait_locked
562 * Purpose:
563 * Mark a thread as waiting. If, given the circumstances,
564 * it doesn't want to wait (i.e. already aborted), then
565 * indicate that in the return value.
566 * Conditions:
567 * at splsched() and thread is locked.
568 */
569 __private_extern__
570 wait_result_t
571 thread_mark_wait_locked(
572 thread_t thread,
573 wait_interrupt_t interruptible)
574 {
575 boolean_t at_safe_point;
576
577 /*
578 * The thread may have certain types of interrupts/aborts masked
579 * off. Even if the wait location says these types of interrupts
580 * are OK, we have to honor mask settings (outer-scoped code may
581 * not be able to handle aborts at the moment).
582 */
583 if (interruptible > (thread->options & TH_OPT_INTMASK))
584 interruptible = thread->options & TH_OPT_INTMASK;
585
586 at_safe_point = (interruptible == THREAD_ABORTSAFE);
587
588 if ( interruptible == THREAD_UNINT ||
589 !(thread->sched_mode & TH_MODE_ABORT) ||
590 (!at_safe_point &&
591 (thread->sched_mode & TH_MODE_ABORTSAFELY))) {
592 thread->state |= (interruptible) ? TH_WAIT : (TH_WAIT | TH_UNINT);
593 thread->at_safe_point = at_safe_point;
594 return (thread->wait_result = THREAD_WAITING);
595 }
596 else
597 if (thread->sched_mode & TH_MODE_ABORTSAFELY)
598 thread->sched_mode &= ~TH_MODE_ISABORTED;
599
600 return (thread->wait_result = THREAD_INTERRUPTED);
601 }
602
603 /*
604 * Routine: thread_interrupt_level
605 * Purpose:
606 * Set the maximum interruptible state for the
607 * current thread. The effective value of any
608 * interruptible flag passed into assert_wait
609 * will never exceed this.
610 *
611 * Useful for code that must not be interrupted,
612 * but which calls code that doesn't know that.
613 * Returns:
614 * The old interrupt level for the thread.
615 */
616 __private_extern__
617 wait_interrupt_t
618 thread_interrupt_level(
619 wait_interrupt_t new_level)
620 {
621 thread_t thread = current_thread();
622 wait_interrupt_t result = thread->options & TH_OPT_INTMASK;
623
624 thread->options = (thread->options & ~TH_OPT_INTMASK) | (new_level & TH_OPT_INTMASK);
625
626 return result;
627 }
628
629 /*
630 * Check to see if an assert wait is possible, without actually doing one.
631 * This is used by debug code in locks and elsewhere to verify that it is
632 * always OK to block when trying to take a blocking lock (since waiting
633 * for the actual assert_wait to catch the case may make it hard to detect
634 * this case.
635 */
636 boolean_t
637 assert_wait_possible(void)
638 {
639
640 thread_t thread;
641
642 #if DEBUG
643 if(debug_mode) return TRUE; /* Always succeed in debug mode */
644 #endif
645
646 thread = current_thread();
647
648 return (thread == NULL || wait_queue_assert_possible(thread));
649 }
650
651 /*
652 * assert_wait:
653 *
654 * Assert that the current thread is about to go to
655 * sleep until the specified event occurs.
656 */
657 wait_result_t
658 assert_wait(
659 event_t event,
660 wait_interrupt_t interruptible)
661 {
662 register wait_queue_t wq;
663 register int index;
664
665 assert(event != NO_EVENT);
666
667 index = wait_hash(event);
668 wq = &wait_queues[index];
669 return wait_queue_assert_wait(wq, event, interruptible, 0);
670 }
671
672 wait_result_t
673 assert_wait_timeout(
674 event_t event,
675 wait_interrupt_t interruptible,
676 uint32_t interval,
677 uint32_t scale_factor)
678 {
679 thread_t thread = current_thread();
680 wait_result_t wresult;
681 wait_queue_t wqueue;
682 uint64_t deadline;
683 spl_t s;
684
685 assert(event != NO_EVENT);
686 wqueue = &wait_queues[wait_hash(event)];
687
688 s = splsched();
689 wait_queue_lock(wqueue);
690 thread_lock(thread);
691
692 clock_interval_to_deadline(interval, scale_factor, &deadline);
693 wresult = wait_queue_assert_wait64_locked(wqueue, (uint32_t)event,
694 interruptible, deadline, thread);
695
696 thread_unlock(thread);
697 wait_queue_unlock(wqueue);
698 splx(s);
699
700 return (wresult);
701 }
702
703 wait_result_t
704 assert_wait_deadline(
705 event_t event,
706 wait_interrupt_t interruptible,
707 uint64_t deadline)
708 {
709 thread_t thread = current_thread();
710 wait_result_t wresult;
711 wait_queue_t wqueue;
712 spl_t s;
713
714 assert(event != NO_EVENT);
715 wqueue = &wait_queues[wait_hash(event)];
716
717 s = splsched();
718 wait_queue_lock(wqueue);
719 thread_lock(thread);
720
721 wresult = wait_queue_assert_wait64_locked(wqueue, (uint32_t)event,
722 interruptible, deadline, thread);
723
724 thread_unlock(thread);
725 wait_queue_unlock(wqueue);
726 splx(s);
727
728 return (wresult);
729 }
730
731 /*
732 * thread_sleep_fast_usimple_lock:
733 *
734 * Cause the current thread to wait until the specified event
735 * occurs. The specified simple_lock is unlocked before releasing
736 * the cpu and re-acquired as part of waking up.
737 *
738 * This is the simple lock sleep interface for components that use a
739 * faster version of simple_lock() than is provided by usimple_lock().
740 */
741 __private_extern__ wait_result_t
742 thread_sleep_fast_usimple_lock(
743 event_t event,
744 simple_lock_t lock,
745 wait_interrupt_t interruptible)
746 {
747 wait_result_t res;
748
749 res = assert_wait(event, interruptible);
750 if (res == THREAD_WAITING) {
751 simple_unlock(lock);
752 res = thread_block(THREAD_CONTINUE_NULL);
753 simple_lock(lock);
754 }
755 return res;
756 }
757
758
759 /*
760 * thread_sleep_usimple_lock:
761 *
762 * Cause the current thread to wait until the specified event
763 * occurs. The specified usimple_lock is unlocked before releasing
764 * the cpu and re-acquired as part of waking up.
765 *
766 * This is the simple lock sleep interface for components where
767 * simple_lock() is defined in terms of usimple_lock().
768 */
769 wait_result_t
770 thread_sleep_usimple_lock(
771 event_t event,
772 usimple_lock_t lock,
773 wait_interrupt_t interruptible)
774 {
775 wait_result_t res;
776
777 res = assert_wait(event, interruptible);
778 if (res == THREAD_WAITING) {
779 usimple_unlock(lock);
780 res = thread_block(THREAD_CONTINUE_NULL);
781 usimple_lock(lock);
782 }
783 return res;
784 }
785
786 /*
787 * thread_sleep_mutex:
788 *
789 * Cause the current thread to wait until the specified event
790 * occurs. The specified mutex is unlocked before releasing
791 * the cpu. The mutex will be re-acquired before returning.
792 *
793 * JMM - Add hint to make sure mutex is available before rousting
794 */
795 wait_result_t
796 thread_sleep_mutex(
797 event_t event,
798 mutex_t *mutex,
799 wait_interrupt_t interruptible)
800 {
801 wait_result_t res;
802
803 res = assert_wait(event, interruptible);
804 if (res == THREAD_WAITING) {
805 mutex_unlock(mutex);
806 res = thread_block(THREAD_CONTINUE_NULL);
807 mutex_lock(mutex);
808 }
809 return res;
810 }
811
812 /*
813 * thread_sleep_mutex_deadline:
814 *
815 * Cause the current thread to wait until the specified event
816 * (or deadline) occurs. The specified mutex is unlocked before
817 * releasing the cpu. The mutex will be re-acquired before returning.
818 */
819 wait_result_t
820 thread_sleep_mutex_deadline(
821 event_t event,
822 mutex_t *mutex,
823 uint64_t deadline,
824 wait_interrupt_t interruptible)
825 {
826 wait_result_t res;
827
828 res = assert_wait_deadline(event, interruptible, deadline);
829 if (res == THREAD_WAITING) {
830 mutex_unlock(mutex);
831 res = thread_block(THREAD_CONTINUE_NULL);
832 mutex_lock(mutex);
833 }
834 return res;
835 }
836
837 /*
838 * thread_sleep_lock_write:
839 *
840 * Cause the current thread to wait until the specified event
841 * occurs. The specified (write) lock is unlocked before releasing
842 * the cpu. The (write) lock will be re-acquired before returning.
843 */
844 wait_result_t
845 thread_sleep_lock_write(
846 event_t event,
847 lock_t *lock,
848 wait_interrupt_t interruptible)
849 {
850 wait_result_t res;
851
852 res = assert_wait(event, interruptible);
853 if (res == THREAD_WAITING) {
854 lock_write_done(lock);
855 res = thread_block(THREAD_CONTINUE_NULL);
856 lock_write(lock);
857 }
858 return res;
859 }
860
861 /*
862 * thread_stop:
863 *
864 * Force a preemption point for a thread and wait
865 * for it to stop running. Arbitrates access among
866 * multiple stop requests. (released by unstop)
867 *
868 * The thread must enter a wait state and stop via a
869 * separate means.
870 *
871 * Returns FALSE if interrupted.
872 */
873 boolean_t
874 thread_stop(
875 thread_t thread)
876 {
877 wait_result_t wresult;
878 spl_t s = splsched();
879
880 wake_lock(thread);
881 thread_lock(thread);
882
883 while (thread->state & TH_SUSP) {
884 thread->wake_active = TRUE;
885 thread_unlock(thread);
886
887 wresult = assert_wait(&thread->wake_active, THREAD_ABORTSAFE);
888 wake_unlock(thread);
889 splx(s);
890
891 if (wresult == THREAD_WAITING)
892 wresult = thread_block(THREAD_CONTINUE_NULL);
893
894 if (wresult != THREAD_AWAKENED)
895 return (FALSE);
896
897 s = splsched();
898 wake_lock(thread);
899 thread_lock(thread);
900 }
901
902 thread->state |= TH_SUSP;
903
904 while (thread->state & TH_RUN) {
905 processor_t processor = thread->last_processor;
906
907 if (processor != PROCESSOR_NULL && processor->active_thread == thread)
908 cause_ast_check(processor);
909
910 thread->wake_active = TRUE;
911 thread_unlock(thread);
912
913 wresult = assert_wait(&thread->wake_active, THREAD_ABORTSAFE);
914 wake_unlock(thread);
915 splx(s);
916
917 if (wresult == THREAD_WAITING)
918 wresult = thread_block(THREAD_CONTINUE_NULL);
919
920 if (wresult != THREAD_AWAKENED) {
921 thread_unstop(thread);
922 return (FALSE);
923 }
924
925 s = splsched();
926 wake_lock(thread);
927 thread_lock(thread);
928 }
929
930 thread_unlock(thread);
931 wake_unlock(thread);
932 splx(s);
933
934 return (TRUE);
935 }
936
937 /*
938 * thread_unstop:
939 *
940 * Release a previous stop request and set
941 * the thread running if appropriate.
942 *
943 * Use only after a successful stop operation.
944 */
945 void
946 thread_unstop(
947 thread_t thread)
948 {
949 spl_t s = splsched();
950
951 wake_lock(thread);
952 thread_lock(thread);
953
954 if ((thread->state & (TH_RUN|TH_WAIT|TH_SUSP)) == TH_SUSP) {
955 thread->state &= ~TH_SUSP;
956 thread_unblock(thread, THREAD_AWAKENED);
957
958 thread_setrun(thread, SCHED_PREEMPT | SCHED_TAILQ);
959 }
960 else
961 if (thread->state & TH_SUSP) {
962 thread->state &= ~TH_SUSP;
963
964 if (thread->wake_active) {
965 thread->wake_active = FALSE;
966 thread_unlock(thread);
967
968 thread_wakeup(&thread->wake_active);
969 wake_unlock(thread);
970 splx(s);
971
972 return;
973 }
974 }
975
976 thread_unlock(thread);
977 wake_unlock(thread);
978 splx(s);
979 }
980
981 /*
982 * thread_wait:
983 *
984 * Wait for a thread to stop running. (non-interruptible)
985 *
986 */
987 void
988 thread_wait(
989 thread_t thread)
990 {
991 wait_result_t wresult;
992 spl_t s = splsched();
993
994 wake_lock(thread);
995 thread_lock(thread);
996
997 while (thread->state & TH_RUN) {
998 processor_t processor = thread->last_processor;
999
1000 if (processor != PROCESSOR_NULL && processor->active_thread == thread)
1001 cause_ast_check(processor);
1002
1003 thread->wake_active = TRUE;
1004 thread_unlock(thread);
1005
1006 wresult = assert_wait(&thread->wake_active, THREAD_UNINT);
1007 wake_unlock(thread);
1008 splx(s);
1009
1010 if (wresult == THREAD_WAITING)
1011 thread_block(THREAD_CONTINUE_NULL);
1012
1013 s = splsched();
1014 wake_lock(thread);
1015 thread_lock(thread);
1016 }
1017
1018 thread_unlock(thread);
1019 wake_unlock(thread);
1020 splx(s);
1021 }
1022
1023 /*
1024 * Routine: clear_wait_internal
1025 *
1026 * Clear the wait condition for the specified thread.
1027 * Start the thread executing if that is appropriate.
1028 * Arguments:
1029 * thread thread to awaken
1030 * result Wakeup result the thread should see
1031 * Conditions:
1032 * At splsched
1033 * the thread is locked.
1034 * Returns:
1035 * KERN_SUCCESS thread was rousted out a wait
1036 * KERN_FAILURE thread was waiting but could not be rousted
1037 * KERN_NOT_WAITING thread was not waiting
1038 */
1039 __private_extern__ kern_return_t
1040 clear_wait_internal(
1041 thread_t thread,
1042 wait_result_t wresult)
1043 {
1044 wait_queue_t wq = thread->wait_queue;
1045 int i = LockTimeOut;
1046
1047 do {
1048 if (wresult == THREAD_INTERRUPTED && (thread->state & TH_UNINT))
1049 return (KERN_FAILURE);
1050
1051 if (wq != WAIT_QUEUE_NULL) {
1052 if (wait_queue_lock_try(wq)) {
1053 wait_queue_pull_thread_locked(wq, thread, TRUE);
1054 /* wait queue unlocked, thread still locked */
1055 }
1056 else {
1057 thread_unlock(thread);
1058 delay(1);
1059
1060 thread_lock(thread);
1061 if (wq != thread->wait_queue)
1062 return (KERN_NOT_WAITING);
1063
1064 continue;
1065 }
1066 }
1067
1068 return (thread_go(thread, wresult));
1069 } while (--i > 0);
1070
1071 panic("clear_wait_internal: deadlock: thread=%p, wq=%p, cpu=%d\n",
1072 thread, wq, cpu_number());
1073
1074 return (KERN_FAILURE);
1075 }
1076
1077
1078 /*
1079 * clear_wait:
1080 *
1081 * Clear the wait condition for the specified thread. Start the thread
1082 * executing if that is appropriate.
1083 *
1084 * parameters:
1085 * thread thread to awaken
1086 * result Wakeup result the thread should see
1087 */
1088 kern_return_t
1089 clear_wait(
1090 thread_t thread,
1091 wait_result_t result)
1092 {
1093 kern_return_t ret;
1094 spl_t s;
1095
1096 s = splsched();
1097 thread_lock(thread);
1098 ret = clear_wait_internal(thread, result);
1099 thread_unlock(thread);
1100 splx(s);
1101 return ret;
1102 }
1103
1104
1105 /*
1106 * thread_wakeup_prim:
1107 *
1108 * Common routine for thread_wakeup, thread_wakeup_with_result,
1109 * and thread_wakeup_one.
1110 *
1111 */
1112 kern_return_t
1113 thread_wakeup_prim(
1114 event_t event,
1115 boolean_t one_thread,
1116 wait_result_t result)
1117 {
1118 register wait_queue_t wq;
1119 register int index;
1120
1121 index = wait_hash(event);
1122 wq = &wait_queues[index];
1123 if (one_thread)
1124 return (wait_queue_wakeup_one(wq, event, result));
1125 else
1126 return (wait_queue_wakeup_all(wq, event, result));
1127 }
1128
1129 /*
1130 * thread_bind:
1131 *
1132 * Force the current thread to execute on the specified processor.
1133 *
1134 * Returns the previous binding. PROCESSOR_NULL means
1135 * not bound.
1136 *
1137 * XXX - DO NOT export this to users - XXX
1138 */
1139 processor_t
1140 thread_bind(
1141 processor_t processor)
1142 {
1143 thread_t self = current_thread();
1144 processor_t prev;
1145 spl_t s;
1146
1147 s = splsched();
1148 thread_lock(self);
1149
1150 prev = self->bound_processor;
1151 self->bound_processor = processor;
1152
1153 thread_unlock(self);
1154 splx(s);
1155
1156 return (prev);
1157 }
1158
1159 /*
1160 * thread_select:
1161 *
1162 * Select a new thread for the current processor to execute.
1163 *
1164 * May select the current thread, which must be locked.
1165 */
1166 static thread_t
1167 thread_select(
1168 thread_t thread,
1169 processor_t processor)
1170 {
1171 processor_set_t pset = processor->processor_set;
1172 thread_t new_thread = THREAD_NULL;
1173 boolean_t other_runnable;
1174
1175 do {
1176 /*
1177 * Update the priority.
1178 */
1179 if (thread->sched_stamp != sched_tick)
1180 update_priority(thread);
1181
1182 processor->current_pri = thread->sched_pri;
1183
1184 pset_lock(pset);
1185
1186 simple_lock(&rt_lock);
1187
1188 /*
1189 * Check for other runnable threads.
1190 */
1191 other_runnable = processor->runq.count > 0 || rt_runq.count > 0;
1192
1193 /*
1194 * Test to see if the current thread should continue
1195 * to run on this processor. Must be runnable, and not
1196 * bound to a different processor, nor be in the wrong
1197 * processor set.
1198 */
1199 if ( thread->state == TH_RUN &&
1200 (thread->bound_processor == PROCESSOR_NULL ||
1201 thread->bound_processor == processor) &&
1202 (thread->affinity_set == AFFINITY_SET_NULL ||
1203 thread->affinity_set->aset_pset == pset) ) {
1204 if ( thread->sched_pri >= BASEPRI_RTQUEUES &&
1205 first_timeslice(processor) ) {
1206 if (rt_runq.highq >= BASEPRI_RTQUEUES) {
1207 register run_queue_t runq = &rt_runq;
1208 register queue_t q;
1209
1210 q = runq->queues + runq->highq;
1211 if (((thread_t)q->next)->realtime.deadline <
1212 processor->deadline) {
1213 thread = (thread_t)q->next;
1214 ((queue_entry_t)thread)->next->prev = q;
1215 q->next = ((queue_entry_t)thread)->next;
1216 thread->runq = PROCESSOR_NULL;
1217 runq->count--; runq->urgency--;
1218 assert(runq->urgency >= 0);
1219 if (queue_empty(q)) {
1220 if (runq->highq != IDLEPRI)
1221 clrbit(MAXPRI - runq->highq, runq->bitmap);
1222 runq->highq = MAXPRI - ffsbit(runq->bitmap);
1223 }
1224 }
1225 }
1226
1227 simple_unlock(&rt_lock);
1228
1229 processor->deadline = thread->realtime.deadline;
1230
1231 pset_unlock(pset);
1232
1233 return (thread);
1234 }
1235
1236 if ( (!other_runnable ||
1237 (processor->runq.highq < thread->sched_pri &&
1238 rt_runq.highq < thread->sched_pri)) ) {
1239
1240 simple_unlock(&rt_lock);
1241
1242 /* I am the highest priority runnable (non-idle) thread */
1243
1244 pset_pri_hint(pset, processor, processor->current_pri);
1245
1246 processor->deadline = UINT64_MAX;
1247
1248 pset_unlock(pset);
1249
1250 return (thread);
1251 }
1252 }
1253
1254 if (other_runnable)
1255 return choose_thread(processor);
1256
1257 simple_unlock(&rt_lock);
1258
1259 /*
1260 * No runnable threads, attempt to steal
1261 * from other processors.
1262 */
1263 new_thread = steal_thread(pset);
1264 if (new_thread != THREAD_NULL)
1265 return (new_thread);
1266
1267 /*
1268 * If other threads have appeared, shortcut
1269 * around again.
1270 */
1271 if (processor->runq.count > 0 || rt_runq.count > 0)
1272 continue;
1273
1274 pset_lock(pset);
1275
1276 /*
1277 * Nothing is runnable, so set this processor idle if it
1278 * was running.
1279 */
1280 if (processor->state == PROCESSOR_RUNNING) {
1281 remqueue(&pset->active_queue, (queue_entry_t)processor);
1282 processor->state = PROCESSOR_IDLE;
1283
1284 enqueue_head(&pset->idle_queue, (queue_entry_t)processor);
1285 pset->low_pri = processor;
1286 pset->idle_count++;
1287 }
1288
1289 processor->deadline = UINT64_MAX;
1290
1291 pset_unlock(pset);
1292
1293 /*
1294 * Choose idle thread if fast idle is not possible.
1295 */
1296 if ((thread->state & (TH_IDLE|TH_TERMINATE|TH_SUSP)) || !(thread->state & TH_WAIT) || thread->wake_active)
1297 return (processor->idle_thread);
1298
1299 /*
1300 * Perform idling activities directly without a
1301 * context switch. Return dispatched thread,
1302 * else check again for a runnable thread.
1303 */
1304 new_thread = thread_select_idle(thread, processor);
1305
1306 } while (new_thread == THREAD_NULL);
1307
1308 return (new_thread);
1309 }
1310
1311 /*
1312 * thread_select_idle:
1313 *
1314 * Idle the processor using the current thread context.
1315 *
1316 * Called with thread locked, then dropped and relocked.
1317 */
1318 static thread_t
1319 thread_select_idle(
1320 thread_t thread,
1321 processor_t processor)
1322 {
1323 thread_t new_thread;
1324
1325 if (thread->sched_mode & TH_MODE_TIMESHARE)
1326 sched_share_decr();
1327 sched_run_decr();
1328
1329 thread->state |= TH_IDLE;
1330 processor->current_pri = IDLEPRI;
1331
1332 thread_unlock(thread);
1333
1334 /*
1335 * Switch execution timing to processor idle thread.
1336 */
1337 processor->last_dispatch = mach_absolute_time();
1338 thread_timer_event(processor->last_dispatch, &processor->idle_thread->system_timer);
1339 PROCESSOR_DATA(processor, kernel_timer) = &processor->idle_thread->system_timer;
1340
1341 /*
1342 * Cancel the quantum timer while idling.
1343 */
1344 timer_call_cancel(&processor->quantum_timer);
1345 processor->timeslice = 0;
1346
1347 (*thread->sched_call)(SCHED_CALL_BLOCK, thread);
1348
1349 /*
1350 * Enable interrupts and perform idling activities. No
1351 * preemption due to TH_IDLE being set.
1352 */
1353 spllo(); new_thread = processor_idle(thread, processor);
1354
1355 /*
1356 * Return at splsched.
1357 */
1358 (*thread->sched_call)(SCHED_CALL_UNBLOCK, thread);
1359
1360 thread_lock(thread);
1361
1362 /*
1363 * If awakened, switch to thread timer and start a new quantum.
1364 * Otherwise skip; we will context switch to another thread or return here.
1365 */
1366 if (!(thread->state & TH_WAIT)) {
1367 processor->last_dispatch = mach_absolute_time();
1368 thread_timer_event(processor->last_dispatch, &thread->system_timer);
1369 PROCESSOR_DATA(processor, kernel_timer) = &thread->system_timer;
1370
1371 thread_quantum_init(thread);
1372
1373 processor->quantum_end = processor->last_dispatch + thread->current_quantum;
1374 timer_call_enter1(&processor->quantum_timer, thread, processor->quantum_end);
1375 processor->timeslice = 1;
1376
1377 thread->computation_epoch = processor->last_dispatch;
1378 }
1379
1380 thread->state &= ~TH_IDLE;
1381
1382 sched_run_incr();
1383 if (thread->sched_mode & TH_MODE_TIMESHARE)
1384 sched_share_incr();
1385
1386 return (new_thread);
1387 }
1388
1389 /*
1390 * Perform a context switch and start executing the new thread.
1391 *
1392 * Returns FALSE on failure, and the thread is re-dispatched.
1393 *
1394 * Called at splsched.
1395 */
1396
1397 #define funnel_release_check(thread, debug) \
1398 MACRO_BEGIN \
1399 if ((thread)->funnel_state & TH_FN_OWNED) { \
1400 (thread)->funnel_state = TH_FN_REFUNNEL; \
1401 KERNEL_DEBUG(0x603242c | DBG_FUNC_NONE, \
1402 (thread)->funnel_lock, (debug), 0, 0, 0); \
1403 funnel_unlock((thread)->funnel_lock); \
1404 } \
1405 MACRO_END
1406
1407 #define funnel_refunnel_check(thread, debug) \
1408 MACRO_BEGIN \
1409 if ((thread)->funnel_state & TH_FN_REFUNNEL) { \
1410 kern_return_t result = (thread)->wait_result; \
1411 \
1412 (thread)->funnel_state = 0; \
1413 KERNEL_DEBUG(0x6032428 | DBG_FUNC_NONE, \
1414 (thread)->funnel_lock, (debug), 0, 0, 0); \
1415 funnel_lock((thread)->funnel_lock); \
1416 KERNEL_DEBUG(0x6032430 | DBG_FUNC_NONE, \
1417 (thread)->funnel_lock, (debug), 0, 0, 0); \
1418 (thread)->funnel_state = TH_FN_OWNED; \
1419 (thread)->wait_result = result; \
1420 } \
1421 MACRO_END
1422
1423 static boolean_t
1424 thread_invoke(
1425 register thread_t self,
1426 register thread_t thread,
1427 ast_t reason)
1428 {
1429 thread_continue_t continuation = self->continuation;
1430 void *parameter = self->parameter;
1431 processor_t processor;
1432
1433 if (get_preemption_level() != 0)
1434 panic("thread_invoke: preemption_level %d\n",
1435 get_preemption_level());
1436
1437 assert(self == current_thread());
1438
1439 /*
1440 * Mark thread interruptible.
1441 */
1442 thread_lock(thread);
1443 thread->state &= ~TH_UNINT;
1444
1445 #if DEBUG
1446 assert(thread_runnable(thread));
1447 #endif
1448
1449 /*
1450 * Allow time constraint threads to hang onto
1451 * a stack.
1452 */
1453 if ((self->sched_mode & TH_MODE_REALTIME) && !self->reserved_stack)
1454 self->reserved_stack = self->kernel_stack;
1455
1456 if (continuation != NULL) {
1457 if (!thread->kernel_stack) {
1458 /*
1459 * If we are using a privileged stack,
1460 * check to see whether we can exchange it with
1461 * that of the other thread.
1462 */
1463 if (self->kernel_stack == self->reserved_stack && !thread->reserved_stack)
1464 goto need_stack;
1465
1466 /*
1467 * Context switch by performing a stack handoff.
1468 */
1469 continuation = thread->continuation;
1470 parameter = thread->parameter;
1471
1472 processor = current_processor();
1473 processor->active_thread = thread;
1474 processor->current_pri = thread->sched_pri;
1475 if (thread->last_processor != processor && thread->last_processor != NULL) {
1476 if (thread->last_processor->processor_set != processor->processor_set)
1477 thread->ps_switch++;
1478 thread->p_switch++;
1479 }
1480 thread->last_processor = processor;
1481 thread->c_switch++;
1482 ast_context(thread);
1483 thread_unlock(thread);
1484
1485 self->reason = reason;
1486
1487 processor->last_dispatch = mach_absolute_time();
1488 thread_timer_event(processor->last_dispatch, &thread->system_timer);
1489 PROCESSOR_DATA(processor, kernel_timer) = &thread->system_timer;
1490
1491 KERNEL_DEBUG_CONSTANT(MACHDBG_CODE(DBG_MACH_SCHED, MACH_STACK_HANDOFF)|DBG_FUNC_NONE,
1492 self->reason, (int)thread, self->sched_pri, thread->sched_pri, 0);
1493
1494 TLOG(1, "thread_invoke: calling machine_stack_handoff\n");
1495 machine_stack_handoff(self, thread);
1496
1497 thread_dispatch(self, thread);
1498
1499 thread->continuation = thread->parameter = NULL;
1500
1501 counter(c_thread_invoke_hits++);
1502
1503 funnel_refunnel_check(thread, 2);
1504 (void) spllo();
1505
1506 assert(continuation);
1507 call_continuation(continuation, parameter, thread->wait_result);
1508 /*NOTREACHED*/
1509 }
1510 else if (thread == self) {
1511 /* same thread but with continuation */
1512 ast_context(self);
1513 counter(++c_thread_invoke_same);
1514 thread_unlock(self);
1515
1516 self->continuation = self->parameter = NULL;
1517
1518 funnel_refunnel_check(self, 3);
1519 (void) spllo();
1520
1521 call_continuation(continuation, parameter, self->wait_result);
1522 /*NOTREACHED*/
1523 }
1524 }
1525 else {
1526 /*
1527 * Check that the other thread has a stack
1528 */
1529 if (!thread->kernel_stack) {
1530 need_stack:
1531 if (!stack_alloc_try(thread)) {
1532 counter(c_thread_invoke_misses++);
1533 thread_unlock(thread);
1534 thread_stack_enqueue(thread);
1535 return (FALSE);
1536 }
1537 }
1538 else if (thread == self) {
1539 ast_context(self);
1540 counter(++c_thread_invoke_same);
1541 thread_unlock(self);
1542 return (TRUE);
1543 }
1544 }
1545
1546 /*
1547 * Context switch by full context save.
1548 */
1549 processor = current_processor();
1550 processor->active_thread = thread;
1551 processor->current_pri = thread->sched_pri;
1552 if (thread->last_processor != processor && thread->last_processor != NULL) {
1553 if (thread->last_processor->processor_set != processor->processor_set)
1554 thread->ps_switch++;
1555 thread->p_switch++;
1556 }
1557 thread->last_processor = processor;
1558 thread->c_switch++;
1559 ast_context(thread);
1560 thread_unlock(thread);
1561
1562 counter(c_thread_invoke_csw++);
1563
1564 assert(self->runq == PROCESSOR_NULL);
1565 self->reason = reason;
1566
1567 processor->last_dispatch = mach_absolute_time();
1568 thread_timer_event(processor->last_dispatch, &thread->system_timer);
1569 PROCESSOR_DATA(processor, kernel_timer) = &thread->system_timer;
1570
1571 KERNEL_DEBUG_CONSTANT(MACHDBG_CODE(DBG_MACH_SCHED,MACH_SCHED) | DBG_FUNC_NONE,
1572 (int)self->reason, (int)thread, self->sched_pri, thread->sched_pri, 0);
1573
1574 /*
1575 * This is where we actually switch register context,
1576 * and address space if required. We will next run
1577 * as a result of a subsequent context switch.
1578 */
1579 thread = machine_switch_context(self, continuation, thread);
1580 TLOG(1,"thread_invoke: returning machine_switch_context: self %p continuation %p thread %p\n", self, continuation, thread);
1581
1582 /*
1583 * We have been resumed and are set to run.
1584 */
1585 thread_dispatch(thread, self);
1586
1587 if (continuation) {
1588 self->continuation = self->parameter = NULL;
1589
1590 funnel_refunnel_check(self, 3);
1591 (void) spllo();
1592
1593 call_continuation(continuation, parameter, self->wait_result);
1594 /*NOTREACHED*/
1595 }
1596
1597 return (TRUE);
1598 }
1599
1600 /*
1601 * thread_dispatch:
1602 *
1603 * Handle threads at context switch. Re-dispatch other thread
1604 * if still running, otherwise update run state and perform
1605 * special actions. Update quantum for other thread and begin
1606 * the quantum for ourselves.
1607 *
1608 * Called at splsched.
1609 */
1610 void
1611 thread_dispatch(
1612 thread_t thread,
1613 thread_t self)
1614 {
1615 processor_t processor = self->last_processor;
1616
1617 if (thread != THREAD_NULL) {
1618 /*
1619 * If blocked at a continuation, discard
1620 * the stack.
1621 */
1622 if (thread->continuation != NULL && thread->kernel_stack != 0)
1623 stack_free(thread);
1624
1625 if (!(thread->state & TH_IDLE)) {
1626 wake_lock(thread);
1627 thread_lock(thread);
1628
1629 /*
1630 * Compute remainder of current quantum.
1631 */
1632 if ( first_timeslice(processor) &&
1633 processor->quantum_end > processor->last_dispatch )
1634 thread->current_quantum = (processor->quantum_end - processor->last_dispatch);
1635 else
1636 thread->current_quantum = 0;
1637
1638 if (thread->sched_mode & TH_MODE_REALTIME) {
1639 /*
1640 * Cancel the deadline if the thread has
1641 * consumed the entire quantum.
1642 */
1643 if (thread->current_quantum == 0) {
1644 thread->realtime.deadline = UINT64_MAX;
1645 thread->reason |= AST_QUANTUM;
1646 }
1647 }
1648 else {
1649 /*
1650 * For non-realtime threads treat a tiny
1651 * remaining quantum as an expired quantum
1652 * but include what's left next time.
1653 */
1654 if (thread->current_quantum < min_std_quantum) {
1655 thread->reason |= AST_QUANTUM;
1656 thread->current_quantum += std_quantum;
1657 }
1658 }
1659
1660 /*
1661 * If we are doing a direct handoff then
1662 * take the remainder of the quantum.
1663 */
1664 if ((thread->reason & (AST_HANDOFF|AST_QUANTUM)) == AST_HANDOFF) {
1665 self->current_quantum = thread->current_quantum;
1666 thread->reason |= AST_QUANTUM;
1667 thread->current_quantum = 0;
1668 }
1669
1670 thread->last_switch = processor->last_dispatch;
1671
1672 thread->computation_metered += (thread->last_switch - thread->computation_epoch);
1673
1674 if (!(thread->state & TH_WAIT)) {
1675 /*
1676 * Still running.
1677 */
1678 if (thread->reason & AST_QUANTUM)
1679 thread_setrun(thread, SCHED_TAILQ);
1680 else
1681 if (thread->reason & AST_PREEMPT)
1682 thread_setrun(thread, SCHED_HEADQ);
1683 else
1684 thread_setrun(thread, SCHED_PREEMPT | SCHED_TAILQ);
1685
1686 thread->reason = AST_NONE;
1687
1688 thread_unlock(thread);
1689 wake_unlock(thread);
1690 }
1691 else {
1692 /*
1693 * Waiting.
1694 */
1695 thread->state &= ~TH_RUN;
1696
1697 if (thread->sched_mode & TH_MODE_TIMESHARE)
1698 sched_share_decr();
1699 sched_run_decr();
1700
1701 if (thread->wake_active) {
1702 thread->wake_active = FALSE;
1703 thread_unlock(thread);
1704
1705 thread_wakeup(&thread->wake_active);
1706 }
1707 else
1708 thread_unlock(thread);
1709
1710 wake_unlock(thread);
1711
1712 (*thread->sched_call)(SCHED_CALL_BLOCK, thread);
1713
1714 if (thread->state & TH_TERMINATE)
1715 thread_terminate_enqueue(thread);
1716 }
1717 }
1718 }
1719
1720 if (!(self->state & TH_IDLE)) {
1721 /*
1722 * Get a new quantum if none remaining.
1723 */
1724 if (self->current_quantum == 0)
1725 thread_quantum_init(self);
1726
1727 /*
1728 * Set up quantum timer and timeslice.
1729 */
1730 processor->quantum_end = (processor->last_dispatch + self->current_quantum);
1731 timer_call_enter1(&processor->quantum_timer, self, processor->quantum_end);
1732
1733 processor->timeslice = 1;
1734
1735 self->last_switch = processor->last_dispatch;
1736
1737 self->computation_epoch = self->last_switch;
1738 }
1739 else {
1740 timer_call_cancel(&processor->quantum_timer);
1741 processor->timeslice = 0;
1742 }
1743 }
1744
1745 /*
1746 * thread_block_reason:
1747 *
1748 * Forces a reschedule, blocking the caller if a wait
1749 * has been asserted.
1750 *
1751 * If a continuation is specified, then thread_invoke will
1752 * attempt to discard the thread's kernel stack. When the
1753 * thread resumes, it will execute the continuation function
1754 * on a new kernel stack.
1755 */
1756 counter(mach_counter_t c_thread_block_calls = 0;)
1757
1758 wait_result_t
1759 thread_block_reason(
1760 thread_continue_t continuation,
1761 void *parameter,
1762 ast_t reason)
1763 {
1764 register thread_t self = current_thread();
1765 register processor_t processor;
1766 register thread_t new_thread;
1767 spl_t s;
1768
1769 counter(++c_thread_block_calls);
1770
1771 s = splsched();
1772
1773 if (!(reason & AST_PREEMPT))
1774 funnel_release_check(self, 2);
1775
1776 processor = current_processor();
1777
1778 /* If we're explicitly yielding, force a subsequent quantum */
1779 if (reason & AST_YIELD)
1780 processor->timeslice = 0;
1781
1782 /* We're handling all scheduling AST's */
1783 ast_off(AST_SCHEDULING);
1784
1785 self->continuation = continuation;
1786 self->parameter = parameter;
1787
1788 do {
1789 thread_lock(self);
1790 new_thread = thread_select(self, processor);
1791 thread_unlock(self);
1792 } while (!thread_invoke(self, new_thread, reason));
1793
1794 funnel_refunnel_check(self, 5);
1795 splx(s);
1796
1797 return (self->wait_result);
1798 }
1799
1800 /*
1801 * thread_block:
1802 *
1803 * Block the current thread if a wait has been asserted.
1804 */
1805 wait_result_t
1806 thread_block(
1807 thread_continue_t continuation)
1808 {
1809 return thread_block_reason(continuation, NULL, AST_NONE);
1810 }
1811
1812 wait_result_t
1813 thread_block_parameter(
1814 thread_continue_t continuation,
1815 void *parameter)
1816 {
1817 return thread_block_reason(continuation, parameter, AST_NONE);
1818 }
1819
1820 /*
1821 * thread_run:
1822 *
1823 * Switch directly from the current thread to the
1824 * new thread, handing off our quantum if appropriate.
1825 *
1826 * New thread must be runnable, and not on a run queue.
1827 *
1828 * Called at splsched.
1829 */
1830 int
1831 thread_run(
1832 thread_t self,
1833 thread_continue_t continuation,
1834 void *parameter,
1835 thread_t new_thread)
1836 {
1837 ast_t handoff = AST_HANDOFF;
1838
1839 funnel_release_check(self, 3);
1840
1841 self->continuation = continuation;
1842 self->parameter = parameter;
1843
1844 while (!thread_invoke(self, new_thread, handoff)) {
1845 processor_t processor = current_processor();
1846
1847 thread_lock(self);
1848 new_thread = thread_select(self, processor);
1849 thread_unlock(self);
1850 handoff = AST_NONE;
1851 }
1852
1853 funnel_refunnel_check(self, 6);
1854
1855 return (self->wait_result);
1856 }
1857
1858 /*
1859 * thread_continue:
1860 *
1861 * Called at splsched when a thread first receives
1862 * a new stack after a continuation.
1863 */
1864 void
1865 thread_continue(
1866 register thread_t thread)
1867 {
1868 register thread_t self = current_thread();
1869 register thread_continue_t continuation;
1870 register void *parameter;
1871
1872 continuation = self->continuation;
1873 parameter = self->parameter;
1874
1875 thread_dispatch(thread, self);
1876
1877 self->continuation = self->parameter = NULL;
1878
1879 funnel_refunnel_check(self, 4);
1880
1881 if (thread != THREAD_NULL)
1882 (void)spllo();
1883
1884 TLOG(1, "thread_continue: calling call_continuation \n");
1885 call_continuation(continuation, parameter, self->wait_result);
1886 /*NOTREACHED*/
1887 }
1888
1889 /*
1890 * run_queue_init:
1891 *
1892 * Initialize a run queue before first use.
1893 */
1894 void
1895 run_queue_init(
1896 run_queue_t rq)
1897 {
1898 int i;
1899
1900 rq->highq = IDLEPRI;
1901 for (i = 0; i < NRQBM; i++)
1902 rq->bitmap[i] = 0;
1903 setbit(MAXPRI - IDLEPRI, rq->bitmap);
1904 rq->urgency = rq->count = 0;
1905 for (i = 0; i < NRQS; i++)
1906 queue_init(&rq->queues[i]);
1907 }
1908
1909 /*
1910 * run_queue_dequeue:
1911 *
1912 * Perform a dequeue operation on a run queue,
1913 * and return the resulting thread.
1914 *
1915 * The run queue must be locked (see run_queue_remove()
1916 * for more info), and not empty.
1917 */
1918 static thread_t
1919 run_queue_dequeue(
1920 run_queue_t rq,
1921 integer_t options)
1922 {
1923 thread_t thread;
1924 queue_t queue = rq->queues + rq->highq;
1925
1926 if (options & SCHED_HEADQ) {
1927 thread = (thread_t)queue->next;
1928 ((queue_entry_t)thread)->next->prev = queue;
1929 queue->next = ((queue_entry_t)thread)->next;
1930 }
1931 else {
1932 thread = (thread_t)queue->prev;
1933 ((queue_entry_t)thread)->prev->next = queue;
1934 queue->prev = ((queue_entry_t)thread)->prev;
1935 }
1936
1937 thread->runq = PROCESSOR_NULL;
1938 rq->count--;
1939 if (testbit(rq->highq, sched_preempt_pri)) {
1940 rq->urgency--; assert(rq->urgency >= 0);
1941 }
1942 if (queue_empty(queue)) {
1943 if (rq->highq != IDLEPRI)
1944 clrbit(MAXPRI - rq->highq, rq->bitmap);
1945 rq->highq = MAXPRI - ffsbit(rq->bitmap);
1946 }
1947
1948 return (thread);
1949 }
1950
1951 /*
1952 * realtime_queue_insert:
1953 *
1954 * Enqueue a thread for realtime execution.
1955 */
1956 static boolean_t
1957 realtime_queue_insert(
1958 thread_t thread)
1959 {
1960 run_queue_t rq = &rt_runq;
1961 queue_t queue = rq->queues + thread->sched_pri;
1962 uint64_t deadline = thread->realtime.deadline;
1963 boolean_t preempt = FALSE;
1964
1965 simple_lock(&rt_lock);
1966
1967 if (queue_empty(queue)) {
1968 enqueue_tail(queue, (queue_entry_t)thread);
1969
1970 setbit(MAXPRI - thread->sched_pri, rq->bitmap);
1971 if (thread->sched_pri > rq->highq)
1972 rq->highq = thread->sched_pri;
1973 preempt = TRUE;
1974 }
1975 else {
1976 register thread_t entry = (thread_t)queue_first(queue);
1977
1978 while (TRUE) {
1979 if ( queue_end(queue, (queue_entry_t)entry) ||
1980 deadline < entry->realtime.deadline ) {
1981 entry = (thread_t)queue_prev((queue_entry_t)entry);
1982 break;
1983 }
1984
1985 entry = (thread_t)queue_next((queue_entry_t)entry);
1986 }
1987
1988 if ((queue_entry_t)entry == queue)
1989 preempt = TRUE;
1990
1991 insque((queue_entry_t)thread, (queue_entry_t)entry);
1992 }
1993
1994 thread->runq = RT_RUNQ;
1995 rq->count++; rq->urgency++;
1996
1997 simple_unlock(&rt_lock);
1998
1999 return (preempt);
2000 }
2001
2002 /*
2003 * realtime_setrun:
2004 *
2005 * Dispatch a thread for realtime execution.
2006 *
2007 * Thread must be locked. Associated pset must
2008 * be locked, and is returned unlocked.
2009 */
2010 static void
2011 realtime_setrun(
2012 processor_t processor,
2013 thread_t thread)
2014 {
2015 processor_set_t pset = processor->processor_set;
2016
2017 /*
2018 * Dispatch directly onto idle processor.
2019 */
2020 if (processor->state == PROCESSOR_IDLE) {
2021 remqueue(&pset->idle_queue, (queue_entry_t)processor);
2022 pset->idle_count--;
2023 enqueue_tail(&pset->active_queue, (queue_entry_t)processor);
2024
2025 processor->next_thread = thread;
2026 processor->deadline = thread->realtime.deadline;
2027 processor->state = PROCESSOR_DISPATCHING;
2028 pset_unlock(pset);
2029
2030 if (processor != current_processor())
2031 machine_signal_idle(processor);
2032 return;
2033 }
2034
2035 if (realtime_queue_insert(thread)) {
2036 if (processor == current_processor())
2037 ast_on(AST_PREEMPT | AST_URGENT);
2038 else
2039 cause_ast_check(processor);
2040 }
2041
2042 pset_unlock(pset);
2043 }
2044
2045 /*
2046 * processor_enqueue:
2047 *
2048 * Enqueue thread on a processor run queue. Thread must be locked,
2049 * and not already be on a run queue.
2050 *
2051 * Returns TRUE if a preemption is indicated based on the state
2052 * of the run queue.
2053 *
2054 * The run queue must be locked (see run_queue_remove()
2055 * for more info).
2056 */
2057 static boolean_t
2058 processor_enqueue(
2059 processor_t processor,
2060 thread_t thread,
2061 integer_t options)
2062 {
2063 run_queue_t rq = &processor->runq;
2064 queue_t queue = rq->queues + thread->sched_pri;
2065 boolean_t result = FALSE;
2066
2067 if (queue_empty(queue)) {
2068 enqueue_tail(queue, (queue_entry_t)thread);
2069
2070 setbit(MAXPRI - thread->sched_pri, rq->bitmap);
2071 if (thread->sched_pri > rq->highq) {
2072 rq->highq = thread->sched_pri;
2073 result = TRUE;
2074 }
2075 }
2076 else
2077 if (options & SCHED_TAILQ)
2078 enqueue_tail(queue, (queue_entry_t)thread);
2079 else
2080 enqueue_head(queue, (queue_entry_t)thread);
2081
2082 thread->runq = processor;
2083 if (testbit(thread->sched_pri, sched_preempt_pri))
2084 rq->urgency++;
2085 rq->count++;
2086
2087 return (result);
2088 }
2089
2090 /*
2091 * processor_setrun:
2092 *
2093 * Dispatch a thread for execution on a
2094 * processor.
2095 *
2096 * Thread must be locked. Associated pset must
2097 * be locked, and is returned unlocked.
2098 */
2099 static void
2100 processor_setrun(
2101 processor_t processor,
2102 thread_t thread,
2103 integer_t options)
2104 {
2105 processor_set_t pset = processor->processor_set;
2106 ast_t preempt;
2107
2108 /*
2109 * Dispatch directly onto idle processor.
2110 */
2111 if (processor->state == PROCESSOR_IDLE) {
2112 remqueue(&pset->idle_queue, (queue_entry_t)processor);
2113 pset->idle_count--;
2114 enqueue_tail(&pset->active_queue, (queue_entry_t)processor);
2115
2116 processor->next_thread = thread;
2117 processor->deadline = UINT64_MAX;
2118 processor->state = PROCESSOR_DISPATCHING;
2119 pset_unlock(pset);
2120
2121 if (processor != current_processor())
2122 machine_signal_idle(processor);
2123 return;
2124 }
2125
2126 /*
2127 * Set preemption mode.
2128 */
2129 if (testbit(thread->sched_pri, sched_preempt_pri))
2130 preempt = (AST_PREEMPT | AST_URGENT);
2131 else
2132 if (thread->sched_mode & TH_MODE_TIMESHARE && thread->priority < BASEPRI_BACKGROUND)
2133 preempt = AST_NONE;
2134 else
2135 preempt = (options & SCHED_PREEMPT)? AST_PREEMPT: AST_NONE;
2136
2137 if (!processor_enqueue(processor, thread, options))
2138 preempt = AST_NONE;
2139
2140 if (preempt != AST_NONE) {
2141 if (processor == current_processor()) {
2142 thread_t self = processor->active_thread;
2143
2144 if (csw_needed(self, processor))
2145 ast_on(preempt);
2146 }
2147 else
2148 if ( (processor->state == PROCESSOR_RUNNING ||
2149 processor->state == PROCESSOR_SHUTDOWN) &&
2150 thread->sched_pri >= processor->current_pri ) {
2151 cause_ast_check(processor);
2152 }
2153 }
2154 else
2155 if ( processor->state == PROCESSOR_SHUTDOWN &&
2156 thread->sched_pri >= processor->current_pri ) {
2157 cause_ast_check(processor);
2158 }
2159
2160 pset_unlock(pset);
2161 }
2162
2163 #define next_pset(p) (((p)->pset_list != PROCESSOR_SET_NULL)? (p)->pset_list: (p)->node->psets)
2164
2165 /*
2166 * choose_next_pset:
2167 *
2168 * Return the next sibling pset containing
2169 * available processors.
2170 *
2171 * Returns the original pset if none other is
2172 * suitable.
2173 */
2174 static processor_set_t
2175 choose_next_pset(
2176 processor_set_t pset)
2177 {
2178 processor_set_t nset = pset;
2179
2180 do {
2181 nset = next_pset(nset);
2182 } while (nset->processor_count < 1 && nset != pset);
2183
2184 return (nset);
2185 }
2186
2187 /*
2188 * choose_processor:
2189 *
2190 * Choose a processor for the thread, beginning at
2191 * the pset.
2192 *
2193 * Returns a processor, possibly from a different pset.
2194 *
2195 * The thread must be locked. The pset must be locked,
2196 * and the resulting pset is locked on return.
2197 */
2198 static processor_t
2199 choose_processor(
2200 processor_set_t pset,
2201 thread_t thread)
2202 {
2203 processor_set_t nset, cset = pset;
2204 processor_t processor = thread->last_processor;
2205
2206 /*
2207 * Prefer the last processor, when appropriate.
2208 */
2209 if (processor != PROCESSOR_NULL) {
2210 if (processor->processor_set != pset ||
2211 processor->state == PROCESSOR_SHUTDOWN || processor->state == PROCESSOR_OFF_LINE)
2212 processor = PROCESSOR_NULL;
2213 else
2214 if (processor->state == PROCESSOR_IDLE || processor->current_pri < thread->sched_pri)
2215 return (processor);
2216 }
2217
2218 /*
2219 * Iterate through the processor sets to locate
2220 * an appropriate processor.
2221 */
2222 do {
2223 /*
2224 * Choose an idle processor.
2225 */
2226 if (!queue_empty(&cset->idle_queue))
2227 return ((processor_t)queue_first(&cset->idle_queue));
2228
2229 if (thread->sched_pri >= BASEPRI_RTQUEUES) {
2230 /*
2231 * For an RT thread, iterate through active processors, first fit.
2232 */
2233 processor = (processor_t)queue_first(&cset->active_queue);
2234 while (!queue_end(&cset->active_queue, (queue_entry_t)processor)) {
2235 if (thread->sched_pri > processor->current_pri ||
2236 thread->realtime.deadline < processor->deadline)
2237 return (processor);
2238
2239 processor = (processor_t)queue_next((queue_entry_t)processor);
2240 }
2241
2242 processor = PROCESSOR_NULL;
2243 }
2244 else {
2245 /*
2246 * Check the low hint processor in the processor set if available.
2247 */
2248 if (cset->low_pri != PROCESSOR_NULL &&
2249 cset->low_pri->state != PROCESSOR_SHUTDOWN && cset->low_pri->state != PROCESSOR_OFF_LINE) {
2250 if (processor == PROCESSOR_NULL || cset->low_pri->current_pri < thread->sched_pri)
2251 processor = cset->low_pri;
2252 }
2253
2254 /*
2255 * Otherwise, choose an available processor in the set.
2256 */
2257 if (processor == PROCESSOR_NULL) {
2258 processor = (processor_t)dequeue_head(&cset->active_queue);
2259 if (processor != PROCESSOR_NULL)
2260 enqueue_tail(&cset->active_queue, (queue_entry_t)processor);
2261 }
2262 }
2263
2264 /*
2265 * Move onto the next processor set.
2266 */
2267 nset = next_pset(cset);
2268
2269 if (nset != pset) {
2270 pset_unlock(cset);
2271
2272 cset = nset;
2273 pset_lock(cset);
2274 }
2275 } while (nset != pset);
2276
2277 /*
2278 * Make sure that we pick a running processor,
2279 * and that the correct processor set is locked.
2280 */
2281 do {
2282 /*
2283 * If we haven't been able to choose a processor,
2284 * pick the current one and return it.
2285 */
2286 if (processor == PROCESSOR_NULL) {
2287 processor = current_processor();
2288
2289 /*
2290 * Check that the correct processor set is
2291 * returned locked.
2292 */
2293 if (cset != processor->processor_set) {
2294 pset_unlock(cset);
2295
2296 cset = processor->processor_set;
2297 pset_lock(cset);
2298 }
2299
2300 return (processor);
2301 }
2302
2303 /*
2304 * Check that the processor set for the chosen
2305 * processor is locked.
2306 */
2307 if (cset != processor->processor_set) {
2308 pset_unlock(cset);
2309
2310 cset = processor->processor_set;
2311 pset_lock(cset);
2312 }
2313
2314 /*
2315 * We must verify that the chosen processor is still available.
2316 */
2317 if (processor->state == PROCESSOR_SHUTDOWN || processor->state == PROCESSOR_OFF_LINE)
2318 processor = PROCESSOR_NULL;
2319 } while (processor == PROCESSOR_NULL);
2320
2321 return (processor);
2322 }
2323
2324 /*
2325 * thread_setrun:
2326 *
2327 * Dispatch thread for execution, onto an idle
2328 * processor or run queue, and signal a preemption
2329 * as appropriate.
2330 *
2331 * Thread must be locked.
2332 */
2333 void
2334 thread_setrun(
2335 thread_t thread,
2336 integer_t options)
2337 {
2338 processor_t processor;
2339 processor_set_t pset;
2340
2341 #if DEBUG
2342 assert(thread_runnable(thread));
2343 #endif
2344
2345 /*
2346 * Update priority if needed.
2347 */
2348 if (thread->sched_stamp != sched_tick)
2349 update_priority(thread);
2350
2351 assert(thread->runq == PROCESSOR_NULL);
2352
2353 if (thread->bound_processor == PROCESSOR_NULL) {
2354 /*
2355 * Unbound case.
2356 */
2357 if (thread->affinity_set != AFFINITY_SET_NULL) {
2358 /*
2359 * Use affinity set policy hint.
2360 */
2361 pset = thread->affinity_set->aset_pset;
2362 pset_lock(pset);
2363
2364 processor = choose_processor(pset, thread);
2365 }
2366 else
2367 if (thread->last_processor != PROCESSOR_NULL) {
2368 /*
2369 * Simple (last processor) affinity case.
2370 */
2371 processor = thread->last_processor;
2372 pset = processor->processor_set;
2373 pset_lock(pset);
2374
2375 /*
2376 * Choose a different processor in certain cases.
2377 */
2378 if (thread->sched_pri >= BASEPRI_RTQUEUES) {
2379 /*
2380 * If the processor is executing an RT thread with
2381 * an earlier deadline, choose another.
2382 */
2383 if (thread->sched_pri <= processor->current_pri ||
2384 thread->realtime.deadline >= processor->deadline)
2385 processor = choose_processor(pset, thread);
2386 }
2387 else
2388 processor = choose_processor(pset, thread);
2389 }
2390 else {
2391 /*
2392 * No Affinity case:
2393 *
2394 * Utilitize a per task hint to spread threads
2395 * among the available processor sets.
2396 */
2397 task_t task = thread->task;
2398
2399 pset = task->pset_hint;
2400 if (pset == PROCESSOR_SET_NULL)
2401 pset = current_processor()->processor_set;
2402
2403 pset = choose_next_pset(pset);
2404 pset_lock(pset);
2405
2406 processor = choose_processor(pset, thread);
2407 task->pset_hint = processor->processor_set;
2408 }
2409 }
2410 else {
2411 /*
2412 * Bound case:
2413 *
2414 * Unconditionally dispatch on the processor.
2415 */
2416 processor = thread->bound_processor;
2417 pset = processor->processor_set;
2418 pset_lock(pset);
2419 }
2420
2421 /*
2422 * Dispatch the thread on the choosen processor.
2423 */
2424 if (thread->sched_pri >= BASEPRI_RTQUEUES)
2425 realtime_setrun(processor, thread);
2426 else
2427 processor_setrun(processor, thread, options);
2428 }
2429
2430 /*
2431 * processor_queue_shutdown:
2432 *
2433 * Shutdown a processor run queue by moving
2434 * non-bound threads to the current processor.
2435 *
2436 * Associated pset must be locked, and is
2437 * returned unlocked.
2438 */
2439 void
2440 processor_queue_shutdown(
2441 processor_t processor)
2442 {
2443 processor_set_t pset = processor->processor_set;
2444 run_queue_t rq = &processor->runq;
2445 queue_t queue = rq->queues + rq->highq;
2446 int pri = rq->highq, count = rq->count;
2447 thread_t next, thread;
2448 queue_head_t tqueue;
2449
2450 queue_init(&tqueue);
2451
2452 while (count > 0) {
2453 thread = (thread_t)queue_first(queue);
2454 while (!queue_end(queue, (queue_entry_t)thread)) {
2455 next = (thread_t)queue_next((queue_entry_t)thread);
2456
2457 if (thread->bound_processor != processor) {
2458 remqueue(queue, (queue_entry_t)thread);
2459
2460 thread->runq = PROCESSOR_NULL;
2461 rq->count--;
2462 if (testbit(pri, sched_preempt_pri)) {
2463 rq->urgency--; assert(rq->urgency >= 0);
2464 }
2465 if (queue_empty(queue)) {
2466 if (pri != IDLEPRI)
2467 clrbit(MAXPRI - pri, rq->bitmap);
2468 rq->highq = MAXPRI - ffsbit(rq->bitmap);
2469 }
2470
2471 enqueue_tail(&tqueue, (queue_entry_t)thread);
2472 }
2473 count--;
2474
2475 thread = next;
2476 }
2477
2478 queue--; pri--;
2479 }
2480
2481 pset_unlock(pset);
2482
2483 processor = current_processor();
2484 pset = processor->processor_set;
2485
2486 while ((thread = (thread_t)dequeue_head(&tqueue)) != THREAD_NULL) {
2487 thread_lock(thread);
2488 thread->last_processor = PROCESSOR_NULL;
2489
2490 pset_lock(pset);
2491
2492 processor_enqueue(processor, thread, SCHED_TAILQ);
2493
2494 pset_unlock(pset);
2495
2496 thread_unlock(thread);
2497 }
2498 }
2499
2500 /*
2501 * Check for a possible preemption point in
2502 * the (current) thread.
2503 *
2504 * Called at splsched.
2505 */
2506 ast_t
2507 csw_check(
2508 thread_t thread,
2509 processor_t processor)
2510 {
2511 int current_pri = thread->sched_pri;
2512 ast_t result = AST_NONE;
2513 run_queue_t runq;
2514
2515 if (first_timeslice(processor)) {
2516 runq = &rt_runq;
2517 if (runq->highq >= BASEPRI_RTQUEUES)
2518 return (AST_PREEMPT | AST_URGENT);
2519
2520 if (runq->highq > current_pri) {
2521 if (runq->urgency > 0)
2522 return (AST_PREEMPT | AST_URGENT);
2523
2524 result |= AST_PREEMPT;
2525 }
2526
2527 runq = &processor->runq;
2528 if (runq->highq > current_pri) {
2529 if (runq->urgency > 0)
2530 return (AST_PREEMPT | AST_URGENT);
2531
2532 result |= AST_PREEMPT;
2533 }
2534 }
2535 else {
2536 runq = &rt_runq;
2537 if (runq->highq >= current_pri) {
2538 if (runq->urgency > 0)
2539 return (AST_PREEMPT | AST_URGENT);
2540
2541 result |= AST_PREEMPT;
2542 }
2543
2544 runq = &processor->runq;
2545 if (runq->highq >= current_pri) {
2546 if (runq->urgency > 0)
2547 return (AST_PREEMPT | AST_URGENT);
2548
2549 result |= AST_PREEMPT;
2550 }
2551 }
2552
2553 if (result != AST_NONE)
2554 return (result);
2555
2556 if (thread->state & TH_SUSP)
2557 result |= AST_PREEMPT;
2558
2559 return (result);
2560 }
2561
2562 /*
2563 * set_sched_pri:
2564 *
2565 * Set the scheduled priority of the specified thread.
2566 *
2567 * This may cause the thread to change queues.
2568 *
2569 * Thread must be locked.
2570 */
2571 void
2572 set_sched_pri(
2573 thread_t thread,
2574 int priority)
2575 {
2576 boolean_t removed = run_queue_remove(thread);
2577
2578 thread->sched_pri = priority;
2579 if (removed)
2580 thread_setrun(thread, SCHED_PREEMPT | SCHED_TAILQ);
2581 else
2582 if (thread->state & TH_RUN) {
2583 processor_t processor = thread->last_processor;
2584
2585 if (thread == current_thread()) {
2586 ast_t preempt = csw_check(thread, processor);
2587
2588 if (preempt != AST_NONE)
2589 ast_on(preempt);
2590 processor->current_pri = priority;
2591 }
2592 else
2593 if ( processor != PROCESSOR_NULL &&
2594 processor->active_thread == thread )
2595 cause_ast_check(processor);
2596 }
2597 }
2598
2599 #if 0
2600
2601 static void
2602 run_queue_check(
2603 run_queue_t rq,
2604 thread_t thread)
2605 {
2606 queue_t q;
2607 queue_entry_t qe;
2608
2609 if (rq != thread->runq)
2610 panic("run_queue_check: thread runq");
2611
2612 if (thread->sched_pri > MAXPRI || thread->sched_pri < MINPRI)
2613 panic("run_queue_check: thread sched_pri");
2614
2615 q = &rq->queues[thread->sched_pri];
2616 qe = queue_first(q);
2617 while (!queue_end(q, qe)) {
2618 if (qe == (queue_entry_t)thread)
2619 return;
2620
2621 qe = queue_next(qe);
2622 }
2623
2624 panic("run_queue_check: end");
2625 }
2626
2627 #endif /* DEBUG */
2628
2629 /*
2630 * run_queue_remove:
2631 *
2632 * Remove a thread from a current run queue and
2633 * return TRUE if successful.
2634 *
2635 * Thread must be locked.
2636 */
2637 boolean_t
2638 run_queue_remove(
2639 thread_t thread)
2640 {
2641 processor_t processor = thread->runq;
2642
2643 /*
2644 * If processor is PROCESSOR_NULL, the thread will stay out of the
2645 * run queues because the caller locked the thread. Otherwise
2646 * the thread is on a run queue, but could be chosen for dispatch
2647 * and removed.
2648 */
2649 if (processor != PROCESSOR_NULL) {
2650 void * rqlock;
2651 run_queue_t rq;
2652
2653 /*
2654 * The processor run queues are locked by the
2655 * processor set. Real-time priorities use a
2656 * global queue with a dedicated lock.
2657 */
2658 if (thread->sched_pri < BASEPRI_RTQUEUES) {
2659 rqlock = &processor->processor_set->sched_lock;
2660 rq = &processor->runq;
2661 }
2662 else {
2663 rqlock = &rt_lock; rq = &rt_runq;
2664 }
2665
2666 simple_lock(rqlock);
2667
2668 if (processor == thread->runq) {
2669 /*
2670 * Thread is on a run queue and we have a lock on
2671 * that run queue.
2672 */
2673 remqueue(&rq->queues[0], (queue_entry_t)thread);
2674 rq->count--;
2675 if (testbit(thread->sched_pri, sched_preempt_pri)) {
2676 rq->urgency--; assert(rq->urgency >= 0);
2677 }
2678
2679 if (queue_empty(rq->queues + thread->sched_pri)) {
2680 /* update run queue status */
2681 if (thread->sched_pri != IDLEPRI)
2682 clrbit(MAXPRI - thread->sched_pri, rq->bitmap);
2683 rq->highq = MAXPRI - ffsbit(rq->bitmap);
2684 }
2685
2686 thread->runq = PROCESSOR_NULL;
2687 }
2688 else {
2689 /*
2690 * The thread left the run queue before we could
2691 * lock the run queue.
2692 */
2693 assert(thread->runq == PROCESSOR_NULL);
2694 processor = PROCESSOR_NULL;
2695 }
2696
2697 simple_unlock(rqlock);
2698 }
2699
2700 return (processor != PROCESSOR_NULL);
2701 }
2702
2703 /*
2704 * choose_thread:
2705 *
2706 * Choose a thread to execute from the run queues
2707 * and return it.
2708 *
2709 * Called with pset scheduling lock and rt lock held,
2710 * released on return.
2711 */
2712 static thread_t
2713 choose_thread(
2714 processor_t processor)
2715 {
2716 processor_set_t pset = processor->processor_set;
2717 thread_t thread;
2718
2719 if (processor->runq.count > 0 && processor->runq.highq >= rt_runq.highq) {
2720 simple_unlock(&rt_lock);
2721
2722 thread = run_queue_dequeue(&processor->runq, SCHED_HEADQ);
2723
2724 pset_pri_hint(pset, processor, thread->sched_pri);
2725
2726 processor->deadline = UINT64_MAX;
2727 pset_unlock(pset);
2728
2729 return (thread);
2730 }
2731
2732 thread = run_queue_dequeue(&rt_runq, SCHED_HEADQ);
2733 simple_unlock(&rt_lock);
2734
2735 processor->deadline = thread->realtime.deadline;
2736 pset_unlock(pset);
2737
2738 return (thread);
2739 }
2740
2741 /*
2742 * steal_processor_thread:
2743 *
2744 * Locate a thread to steal from the processor and
2745 * return it.
2746 *
2747 * Associated pset must be locked. Returns THREAD_NULL
2748 * on failure.
2749 */
2750 static thread_t
2751 steal_processor_thread(
2752 processor_t processor)
2753 {
2754 run_queue_t rq = &processor->runq;
2755 queue_t queue = rq->queues + rq->highq;
2756 int pri = rq->highq, count = rq->count;
2757 thread_t thread;
2758
2759 while (count > 0) {
2760 thread = (thread_t)queue_first(queue);
2761 while (!queue_end(queue, (queue_entry_t)thread)) {
2762 if (thread->bound_processor != processor) {
2763 remqueue(queue, (queue_entry_t)thread);
2764
2765 thread->runq = PROCESSOR_NULL;
2766 rq->count--;
2767 if (testbit(pri, sched_preempt_pri)) {
2768 rq->urgency--; assert(rq->urgency >= 0);
2769 }
2770 if (queue_empty(queue)) {
2771 if (pri != IDLEPRI)
2772 clrbit(MAXPRI - pri, rq->bitmap);
2773 rq->highq = MAXPRI - ffsbit(rq->bitmap);
2774 }
2775
2776 return (thread);
2777 }
2778 count--;
2779
2780 thread = (thread_t)queue_next((queue_entry_t)thread);
2781 }
2782
2783 queue--; pri--;
2784 }
2785
2786 return (THREAD_NULL);
2787 }
2788
2789 /*
2790 * Locate and steal a thread, beginning
2791 * at the pset.
2792 *
2793 * The pset must be locked, and is returned
2794 * unlocked.
2795 *
2796 * Returns the stolen thread, or THREAD_NULL on
2797 * failure.
2798 */
2799 static thread_t
2800 steal_thread(
2801 processor_set_t pset)
2802 {
2803 processor_set_t nset, cset = pset;
2804 processor_t processor;
2805 thread_t thread;
2806
2807 do {
2808 processor = (processor_t)queue_first(&cset->active_queue);
2809 while (!queue_end(&cset->active_queue, (queue_entry_t)processor)) {
2810 if (processor->runq.count > 0) {
2811 thread = steal_processor_thread(processor);
2812 if (thread != THREAD_NULL) {
2813 remqueue(&cset->active_queue, (queue_entry_t)processor);
2814 enqueue_tail(&cset->active_queue, (queue_entry_t)processor);
2815
2816 processor->deadline = UINT64_MAX;
2817 pset_unlock(cset);
2818
2819 return (thread);
2820 }
2821 }
2822
2823 processor = (processor_t)queue_next((queue_entry_t)processor);
2824 }
2825
2826 nset = next_pset(cset);
2827
2828 if (nset != pset) {
2829 pset_unlock(cset);
2830
2831 cset = nset;
2832 pset_lock(cset);
2833 }
2834 } while (nset != pset);
2835
2836 pset_unlock(cset);
2837
2838 return (THREAD_NULL);
2839 }
2840
2841 /*
2842 * This is the processor idle loop, which just looks for other threads
2843 * to execute. Processor idle threads invoke this without supplying a
2844 * current thread to idle without an asserted wait state.
2845 *
2846 * Returns a the next thread to execute if dispatched directly.
2847 */
2848 static thread_t
2849 processor_idle(
2850 thread_t thread,
2851 processor_t processor)
2852 {
2853 processor_set_t pset = processor->processor_set;
2854 thread_t new_thread;
2855 int state;
2856
2857 (void)splsched();
2858
2859 #ifdef __ppc__
2860 pmsDown(); /* Step power down */
2861 #endif
2862
2863 KERNEL_DEBUG_CONSTANT(
2864 MACHDBG_CODE(DBG_MACH_SCHED,MACH_IDLE) | DBG_FUNC_START, (int)thread, 0, 0, 0, 0);
2865
2866 timer_switch(&PROCESSOR_DATA(processor, system_state),
2867 mach_absolute_time(), &PROCESSOR_DATA(processor, idle_state));
2868 PROCESSOR_DATA(processor, current_state) = &PROCESSOR_DATA(processor, idle_state);
2869
2870 while (processor->next_thread == THREAD_NULL && processor->runq.count == 0 && rt_runq.count == 0 &&
2871 (thread == THREAD_NULL || ((thread->state & (TH_WAIT|TH_SUSP)) == TH_WAIT && !thread->wake_active))) {
2872 machine_idle();
2873
2874 (void)splsched();
2875 }
2876
2877 timer_switch(&PROCESSOR_DATA(processor, idle_state),
2878 mach_absolute_time(), &PROCESSOR_DATA(processor, system_state));
2879 PROCESSOR_DATA(processor, current_state) = &PROCESSOR_DATA(processor, system_state);
2880
2881 pset_lock(pset);
2882
2883 #ifdef __ppc__
2884 pmsStep(0); /* Step up out of idle power */
2885 #endif
2886
2887 state = processor->state;
2888 if (state == PROCESSOR_DISPATCHING) {
2889 /*
2890 * Commmon case -- cpu dispatched.
2891 */
2892 new_thread = processor->next_thread;
2893 processor->next_thread = THREAD_NULL;
2894 processor->state = PROCESSOR_RUNNING;
2895
2896 if ( processor->runq.highq > new_thread->sched_pri ||
2897 (rt_runq.highq > 0 && rt_runq.highq >= new_thread->sched_pri) ) {
2898 processor->deadline = UINT64_MAX;
2899
2900 pset_unlock(pset);
2901
2902 thread_lock(new_thread);
2903 thread_setrun(new_thread, SCHED_HEADQ);
2904 thread_unlock(new_thread);
2905
2906 KERNEL_DEBUG_CONSTANT(
2907 MACHDBG_CODE(DBG_MACH_SCHED,MACH_IDLE) | DBG_FUNC_END, (int)thread, (int)state, 0, 0, 0);
2908
2909 return (THREAD_NULL);
2910 }
2911
2912 pset_unlock(pset);
2913
2914 KERNEL_DEBUG_CONSTANT(
2915 MACHDBG_CODE(DBG_MACH_SCHED,MACH_IDLE) | DBG_FUNC_END, (int)thread, (int)state, (int)new_thread, 0, 0);
2916
2917 return (new_thread);
2918 }
2919 else
2920 if (state == PROCESSOR_IDLE) {
2921 remqueue(&pset->idle_queue, (queue_entry_t)processor);
2922 pset->idle_count--;
2923
2924 processor->state = PROCESSOR_RUNNING;
2925 enqueue_tail(&pset->active_queue, (queue_entry_t)processor);
2926 }
2927 else
2928 if (state == PROCESSOR_SHUTDOWN) {
2929 /*
2930 * Going off-line. Force a
2931 * reschedule.
2932 */
2933 if ((new_thread = processor->next_thread) != THREAD_NULL) {
2934 processor->next_thread = THREAD_NULL;
2935 processor->deadline = UINT64_MAX;
2936
2937 pset_unlock(pset);
2938
2939 thread_lock(new_thread);
2940 thread_setrun(new_thread, SCHED_HEADQ);
2941 thread_unlock(new_thread);
2942
2943 KERNEL_DEBUG_CONSTANT(
2944 MACHDBG_CODE(DBG_MACH_SCHED,MACH_IDLE) | DBG_FUNC_END, (int)thread, (int)state, 0, 0, 0);
2945
2946 return (THREAD_NULL);
2947 }
2948 }
2949
2950 pset_unlock(pset);
2951
2952 KERNEL_DEBUG_CONSTANT(
2953 MACHDBG_CODE(DBG_MACH_SCHED,MACH_IDLE) | DBG_FUNC_END, (int)thread, (int)state, 0, 0, 0);
2954
2955 return (THREAD_NULL);
2956 }
2957
2958 /*
2959 * Each processor has a dedicated thread which
2960 * executes the idle loop when there is no suitable
2961 * previous context.
2962 */
2963 void
2964 idle_thread(void)
2965 {
2966 processor_t processor = current_processor();
2967 thread_t new_thread;
2968
2969 new_thread = processor_idle(THREAD_NULL, processor);
2970 if (new_thread != THREAD_NULL) {
2971 thread_run(processor->idle_thread, (thread_continue_t)idle_thread, NULL, new_thread);
2972 /*NOTREACHED*/
2973 }
2974
2975 thread_block((thread_continue_t)idle_thread);
2976 /*NOTREACHED*/
2977 }
2978
2979 kern_return_t
2980 idle_thread_create(
2981 processor_t processor)
2982 {
2983 kern_return_t result;
2984 thread_t thread;
2985 spl_t s;
2986
2987 result = kernel_thread_create((thread_continue_t)idle_thread, NULL, MAXPRI_KERNEL, &thread);
2988 if (result != KERN_SUCCESS)
2989 return (result);
2990
2991 s = splsched();
2992 thread_lock(thread);
2993 thread->bound_processor = processor;
2994 processor->idle_thread = thread;
2995 thread->sched_pri = thread->priority = IDLEPRI;
2996 thread->state = (TH_RUN | TH_IDLE);
2997 thread_unlock(thread);
2998 splx(s);
2999
3000 thread_deallocate(thread);
3001
3002 return (KERN_SUCCESS);
3003 }
3004
3005 static uint64_t sched_tick_deadline;
3006
3007 /*
3008 * sched_startup:
3009 *
3010 * Kicks off scheduler services.
3011 *
3012 * Called at splsched.
3013 */
3014 void
3015 sched_startup(void)
3016 {
3017 kern_return_t result;
3018 thread_t thread;
3019
3020 result = kernel_thread_start_priority((thread_continue_t)sched_tick_thread, NULL, MAXPRI_KERNEL, &thread);
3021 if (result != KERN_SUCCESS)
3022 panic("sched_startup");
3023
3024 thread_deallocate(thread);
3025
3026 /*
3027 * Yield to the sched_tick_thread while it times
3028 * a series of context switches back. It stores
3029 * the baseline value in sched_cswtime.
3030 *
3031 * The current thread is the only other thread
3032 * active at this point.
3033 */
3034 while (sched_cswtime == 0)
3035 thread_block(THREAD_CONTINUE_NULL);
3036
3037 thread_daemon_init();
3038
3039 thread_call_initialize();
3040 }
3041
3042 /*
3043 * sched_tick_thread:
3044 *
3045 * Perform periodic bookkeeping functions about ten
3046 * times per second.
3047 */
3048 static void
3049 sched_tick_continue(void)
3050 {
3051 uint64_t abstime = mach_absolute_time();
3052
3053 sched_tick++;
3054
3055 /*
3056 * Compute various averages.
3057 */
3058 compute_averages();
3059
3060 /*
3061 * Scan the run queues for threads which
3062 * may need to be updated.
3063 */
3064 thread_update_scan();
3065
3066 clock_deadline_for_periodic_event(sched_tick_interval, abstime,
3067 &sched_tick_deadline);
3068
3069 assert_wait_deadline((event_t)sched_tick_thread, THREAD_UNINT, sched_tick_deadline);
3070 thread_block((thread_continue_t)sched_tick_continue);
3071 /*NOTREACHED*/
3072 }
3073
3074 /*
3075 * Time a series of context switches to determine
3076 * a baseline. Toss the high and low and return
3077 * the one-way value.
3078 */
3079 static uint32_t
3080 time_cswitch(void)
3081 {
3082 uint32_t new, hi, low, accum;
3083 uint64_t abstime;
3084 int i, tries = 7;
3085
3086 accum = hi = low = 0;
3087 for (i = 0; i < tries; ++i) {
3088 abstime = mach_absolute_time();
3089 thread_block(THREAD_CONTINUE_NULL);
3090
3091 new = mach_absolute_time() - abstime;
3092
3093 if (i == 0)
3094 accum = hi = low = new;
3095 else {
3096 if (new < low)
3097 low = new;
3098 else
3099 if (new > hi)
3100 hi = new;
3101 accum += new;
3102 }
3103 }
3104
3105 return ((accum - hi - low) / (2 * (tries - 2)));
3106 }
3107
3108 void
3109 sched_tick_thread(void)
3110 {
3111 sched_cswtime = time_cswitch();
3112
3113 sched_tick_deadline = mach_absolute_time();
3114
3115 sched_tick_continue();
3116 /*NOTREACHED*/
3117 }
3118
3119 /*
3120 * thread_update_scan / runq_scan:
3121 *
3122 * Scan the run queues to account for timesharing threads
3123 * which need to be updated.
3124 *
3125 * Scanner runs in two passes. Pass one squirrels likely
3126 * threads away in an array, pass two does the update.
3127 *
3128 * This is necessary because the run queue is locked for
3129 * the candidate scan, but the thread is locked for the update.
3130 *
3131 * Array should be sized to make forward progress, without
3132 * disabling preemption for long periods.
3133 */
3134
3135 #define THREAD_UPDATE_SIZE 128
3136
3137 static thread_t thread_update_array[THREAD_UPDATE_SIZE];
3138 static int thread_update_count = 0;
3139
3140 /*
3141 * Scan a runq for candidate threads.
3142 *
3143 * Returns TRUE if retry is needed.
3144 */
3145 static boolean_t
3146 runq_scan(
3147 run_queue_t runq)
3148 {
3149 register int count;
3150 register queue_t q;
3151 register thread_t thread;
3152
3153 if ((count = runq->count) > 0) {
3154 q = runq->queues + runq->highq;
3155 while (count > 0) {
3156 queue_iterate(q, thread, thread_t, links) {
3157 if ( thread->sched_stamp != sched_tick &&
3158 (thread->sched_mode & TH_MODE_TIMESHARE) ) {
3159 if (thread_update_count == THREAD_UPDATE_SIZE)
3160 return (TRUE);
3161
3162 thread_update_array[thread_update_count++] = thread;
3163 thread_reference_internal(thread);
3164 }
3165
3166 count--;
3167 }
3168
3169 q--;
3170 }
3171 }
3172
3173 return (FALSE);
3174 }
3175
3176 static void
3177 thread_update_scan(void)
3178 {
3179 boolean_t restart_needed = FALSE;
3180 processor_t processor = processor_list;
3181 processor_set_t pset;
3182 thread_t thread;
3183 spl_t s;
3184
3185 do {
3186 do {
3187 pset = processor->processor_set;
3188
3189 s = splsched();
3190 pset_lock(pset);
3191
3192 restart_needed = runq_scan(&processor->runq);
3193
3194 pset_unlock(pset);
3195 splx(s);
3196
3197 if (restart_needed)
3198 break;
3199
3200 thread = processor->idle_thread;
3201 if (thread != THREAD_NULL && thread->sched_stamp != sched_tick) {
3202 if (thread_update_count == THREAD_UPDATE_SIZE) {
3203 restart_needed = TRUE;
3204 break;
3205 }
3206
3207 thread_update_array[thread_update_count++] = thread;
3208 thread_reference_internal(thread);
3209 }
3210 } while ((processor = processor->processor_list) != NULL);
3211
3212 /*
3213 * Ok, we now have a collection of candidates -- fix them.
3214 */
3215 while (thread_update_count > 0) {
3216 thread = thread_update_array[--thread_update_count];
3217 thread_update_array[thread_update_count] = THREAD_NULL;
3218
3219 s = splsched();
3220 thread_lock(thread);
3221 if ( !(thread->state & (TH_WAIT|TH_SUSP)) &&
3222 thread->sched_stamp != sched_tick )
3223 update_priority(thread);
3224 thread_unlock(thread);
3225 splx(s);
3226
3227 thread_deallocate(thread);
3228 }
3229 } while (restart_needed);
3230 }
3231
3232 /*
3233 * Just in case someone doesn't use the macro
3234 */
3235 #undef thread_wakeup
3236 void
3237 thread_wakeup(
3238 event_t x);
3239
3240 void
3241 thread_wakeup(
3242 event_t x)
3243 {
3244 thread_wakeup_with_result(x, THREAD_AWAKENED);
3245 }
3246
3247 boolean_t
3248 preemption_enabled(void)
3249 {
3250 return (get_preemption_level() == 0 && ml_get_interrupts_enabled());
3251 }
3252
3253 #if DEBUG
3254 static boolean_t
3255 thread_runnable(
3256 thread_t thread)
3257 {
3258 return ((thread->state & (TH_RUN|TH_WAIT)) == TH_RUN);
3259 }
3260 #endif /* DEBUG */
3261
3262 #if MACH_KDB
3263 #include <ddb/db_output.h>
3264 #define printf kdbprintf
3265 void db_sched(void);
3266
3267 void
3268 db_sched(void)
3269 {
3270 iprintf("Scheduling Statistics:\n");
3271 db_indent += 2;
3272 iprintf("Thread invocations: csw %d same %d\n",
3273 c_thread_invoke_csw, c_thread_invoke_same);
3274 #if MACH_COUNTERS
3275 iprintf("Thread block: calls %d\n",
3276 c_thread_block_calls);
3277 iprintf("Idle thread:\n\thandoff %d block %d\n",
3278 c_idle_thread_handoff,
3279 c_idle_thread_block);
3280 iprintf("Sched thread blocks: %d\n", c_sched_thread_block);
3281 #endif /* MACH_COUNTERS */
3282 db_indent -= 2;
3283 }
3284
3285 #include <ddb/db_output.h>
3286 void db_show_thread_log(void);
3287
3288 void
3289 db_show_thread_log(void)
3290 {
3291 }
3292 #endif /* MACH_KDB */