]> git.saurik.com Git - apple/xnu.git/blame - osfmk/kern/sched_prim.c
xnu-517.11.1.tar.gz
[apple/xnu.git] / osfmk / kern / sched_prim.c
CommitLineData
1c79356b
A
1/*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
e5568f75
A
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
43866e37 11 *
e5568f75
A
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
1c79356b
A
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
e5568f75
A
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
1c79356b
A
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22/*
23 * @OSF_FREE_COPYRIGHT@
24 */
25/*
26 * Mach Operating System
27 * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
28 * All Rights Reserved.
29 *
30 * Permission to use, copy, modify and distribute this software and its
31 * documentation is hereby granted, provided that both the copyright
32 * notice and this permission notice appear in all copies of the
33 * software, derivative works or modified versions, and any portions
34 * thereof, and that both notices appear in supporting documentation.
35 *
36 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
37 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
38 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
39 *
40 * Carnegie Mellon requests users of this software to return to
41 *
42 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
43 * School of Computer Science
44 * Carnegie Mellon University
45 * Pittsburgh PA 15213-3890
46 *
47 * any improvements or extensions that they make and grant Carnegie Mellon
48 * the rights to redistribute these changes.
49 */
50/*
51 */
52/*
53 * File: sched_prim.c
54 * Author: Avadis Tevanian, Jr.
55 * Date: 1986
56 *
57 * Scheduling primitives
58 *
59 */
60
61#include <debug.h>
62#include <cpus.h>
63#include <mach_kdb.h>
64#include <simple_clock.h>
1c79356b
A
65
66#include <ddb/db_output.h>
67#include <mach/machine.h>
68#include <machine/machine_routines.h>
69#include <machine/sched_param.h>
70#include <kern/ast.h>
71#include <kern/clock.h>
72#include <kern/counters.h>
73#include <kern/cpu_number.h>
74#include <kern/cpu_data.h>
75#include <kern/etap_macros.h>
76#include <kern/lock.h>
77#include <kern/macro_help.h>
78#include <kern/machine.h>
79#include <kern/misc_protos.h>
80#include <kern/processor.h>
81#include <kern/queue.h>
82#include <kern/sched.h>
83#include <kern/sched_prim.h>
84#include <kern/syscall_subr.h>
85#include <kern/task.h>
86#include <kern/thread.h>
87#include <kern/thread_swap.h>
88#include <vm/pmap.h>
89#include <vm/vm_kern.h>
90#include <vm/vm_map.h>
91#include <mach/policy.h>
92#include <mach/sync_policy.h>
1c79356b
A
93#include <kern/mk_sp.h> /*** ??? fix so this can be removed ***/
94#include <sys/kdebug.h>
95
0b4e3aa0 96#define DEFAULT_PREEMPTION_RATE 100 /* (1/s) */
1c79356b
A
97int default_preemption_rate = DEFAULT_PREEMPTION_RATE;
98
0b4e3aa0
A
99#define MAX_UNSAFE_QUANTA 800
100int max_unsafe_quanta = MAX_UNSAFE_QUANTA;
101
102#define MAX_POLL_QUANTA 2
103int max_poll_quanta = MAX_POLL_QUANTA;
104
105#define SCHED_POLL_YIELD_SHIFT 4 /* 1/16 */
106int sched_poll_yield_shift = SCHED_POLL_YIELD_SHIFT;
107
0b4e3aa0 108uint32_t std_quantum_us;
1c79356b 109
55e303ae
A
110uint64_t max_unsafe_computation;
111uint32_t sched_safe_duration;
112uint64_t max_poll_computation;
113
114uint32_t std_quantum;
115uint32_t min_std_quantum;
116
117uint32_t max_rt_quantum;
118uint32_t min_rt_quantum;
119
120static uint32_t sched_tick_interval;
121
1c79356b
A
122unsigned sched_tick;
123
124#if SIMPLE_CLOCK
125int sched_usec;
126#endif /* SIMPLE_CLOCK */
127
128/* Forwards */
1c79356b
A
129void wait_queues_init(void);
130
55e303ae
A
131static thread_t choose_thread(
132 processor_set_t pset,
133 processor_t processor);
1c79356b 134
55e303ae 135static void do_thread_scan(void);
1c79356b 136
1c79356b 137#if DEBUG
0b4e3aa0 138static
1c79356b
A
139boolean_t thread_runnable(
140 thread_t thread);
141
0b4e3aa0
A
142#endif /*DEBUG*/
143
144
1c79356b
A
145/*
146 * State machine
147 *
148 * states are combinations of:
149 * R running
150 * W waiting (or on wait queue)
151 * N non-interruptible
152 * O swapped out
153 * I being swapped in
154 *
155 * init action
156 * assert_wait thread_block clear_wait swapout swapin
157 *
158 * R RW, RWN R; setrun - -
159 * RN RWN RN; setrun - -
160 *
161 * RW W R -
162 * RWN WN RN -
163 *
164 * W R; setrun WO
165 * WN RN; setrun -
166 *
167 * RO - - R
168 *
169 */
170
171/*
172 * Waiting protocols and implementation:
173 *
174 * Each thread may be waiting for exactly one event; this event
175 * is set using assert_wait(). That thread may be awakened either
176 * by performing a thread_wakeup_prim() on its event,
177 * or by directly waking that thread up with clear_wait().
178 *
179 * The implementation of wait events uses a hash table. Each
180 * bucket is queue of threads having the same hash function
181 * value; the chain for the queue (linked list) is the run queue
182 * field. [It is not possible to be waiting and runnable at the
183 * same time.]
184 *
185 * Locks on both the thread and on the hash buckets govern the
186 * wait event field and the queue chain field. Because wakeup
187 * operations only have the event as an argument, the event hash
188 * bucket must be locked before any thread.
189 *
190 * Scheduling operations may also occur at interrupt level; therefore,
191 * interrupts below splsched() must be prevented when holding
192 * thread or hash bucket locks.
193 *
194 * The wait event hash table declarations are as follows:
195 */
196
197#define NUMQUEUES 59
198
199struct wait_queue wait_queues[NUMQUEUES];
200
201#define wait_hash(event) \
202 ((((int)(event) < 0)? ~(int)(event): (int)(event)) % NUMQUEUES)
203
204void
205sched_init(void)
206{
207 /*
0b4e3aa0
A
208 * Calculate the timeslicing quantum
209 * in us.
1c79356b
A
210 */
211 if (default_preemption_rate < 1)
212 default_preemption_rate = DEFAULT_PREEMPTION_RATE;
0b4e3aa0 213 std_quantum_us = (1000 * 1000) / default_preemption_rate;
1c79356b 214
0b4e3aa0 215 printf("standard timeslicing quantum is %d us\n", std_quantum_us);
1c79356b 216
55e303ae
A
217 sched_safe_duration = (2 * max_unsafe_quanta / default_preemption_rate) *
218 (1 << SCHED_TICK_SHIFT);
219
1c79356b
A
220 wait_queues_init();
221 pset_sys_bootstrap(); /* initialize processor mgmt. */
1c79356b
A
222 sched_tick = 0;
223#if SIMPLE_CLOCK
224 sched_usec = 0;
225#endif /* SIMPLE_CLOCK */
226 ast_init();
1c79356b
A
227}
228
55e303ae
A
229void
230sched_timebase_init(void)
231{
232 uint64_t abstime;
233
234 clock_interval_to_absolutetime_interval(
235 std_quantum_us, NSEC_PER_USEC, &abstime);
236 assert((abstime >> 32) == 0 && (uint32_t)abstime != 0);
237 std_quantum = abstime;
238
239 /* 250 us */
240 clock_interval_to_absolutetime_interval(250, NSEC_PER_USEC, &abstime);
241 assert((abstime >> 32) == 0 && (uint32_t)abstime != 0);
242 min_std_quantum = abstime;
243
244 /* 50 us */
245 clock_interval_to_absolutetime_interval(50, NSEC_PER_USEC, &abstime);
246 assert((abstime >> 32) == 0 && (uint32_t)abstime != 0);
247 min_rt_quantum = abstime;
248
249 /* 50 ms */
250 clock_interval_to_absolutetime_interval(
251 50, 1000*NSEC_PER_USEC, &abstime);
252 assert((abstime >> 32) == 0 && (uint32_t)abstime != 0);
253 max_rt_quantum = abstime;
254
255 clock_interval_to_absolutetime_interval(1000 >> SCHED_TICK_SHIFT,
256 USEC_PER_SEC, &abstime);
257 assert((abstime >> 32) == 0 && (uint32_t)abstime != 0);
258 sched_tick_interval = abstime;
259
260 max_unsafe_computation = max_unsafe_quanta * std_quantum;
261 max_poll_computation = max_poll_quanta * std_quantum;
262}
263
1c79356b
A
264void
265wait_queues_init(void)
266{
267 register int i;
268
269 for (i = 0; i < NUMQUEUES; i++) {
270 wait_queue_init(&wait_queues[i], SYNC_POLICY_FIFO);
271 }
272}
273
274/*
0b4e3aa0 275 * Thread wait timer expiration.
1c79356b
A
276 */
277void
278thread_timer_expire(
279 timer_call_param_t p0,
280 timer_call_param_t p1)
281{
282 thread_t thread = p0;
283 spl_t s;
284
285 s = splsched();
55e303ae 286 thread_lock(thread);
0b4e3aa0
A
287 if (--thread->wait_timer_active == 1) {
288 if (thread->wait_timer_is_set) {
289 thread->wait_timer_is_set = FALSE;
55e303ae 290 clear_wait_internal(thread, THREAD_TIMED_OUT);
0b4e3aa0 291 }
1c79356b 292 }
55e303ae 293 thread_unlock(thread);
1c79356b
A
294 splx(s);
295}
296
297/*
298 * thread_set_timer:
299 *
300 * Set a timer for the current thread, if the thread
301 * is ready to wait. Must be called between assert_wait()
302 * and thread_block().
303 */
304void
305thread_set_timer(
0b4e3aa0
A
306 uint32_t interval,
307 uint32_t scale_factor)
1c79356b
A
308{
309 thread_t thread = current_thread();
0b4e3aa0 310 uint64_t deadline;
1c79356b
A
311 spl_t s;
312
313 s = splsched();
1c79356b
A
314 thread_lock(thread);
315 if ((thread->state & TH_WAIT) != 0) {
316 clock_interval_to_deadline(interval, scale_factor, &deadline);
317 timer_call_enter(&thread->wait_timer, deadline);
318 assert(!thread->wait_timer_is_set);
319 thread->wait_timer_active++;
320 thread->wait_timer_is_set = TRUE;
321 }
322 thread_unlock(thread);
1c79356b
A
323 splx(s);
324}
325
326void
327thread_set_timer_deadline(
0b4e3aa0 328 uint64_t deadline)
1c79356b
A
329{
330 thread_t thread = current_thread();
331 spl_t s;
332
333 s = splsched();
1c79356b
A
334 thread_lock(thread);
335 if ((thread->state & TH_WAIT) != 0) {
336 timer_call_enter(&thread->wait_timer, deadline);
337 assert(!thread->wait_timer_is_set);
338 thread->wait_timer_active++;
339 thread->wait_timer_is_set = TRUE;
340 }
341 thread_unlock(thread);
1c79356b
A
342 splx(s);
343}
344
345void
346thread_cancel_timer(void)
347{
348 thread_t thread = current_thread();
349 spl_t s;
350
351 s = splsched();
55e303ae 352 thread_lock(thread);
1c79356b
A
353 if (thread->wait_timer_is_set) {
354 if (timer_call_cancel(&thread->wait_timer))
355 thread->wait_timer_active--;
356 thread->wait_timer_is_set = FALSE;
357 }
55e303ae 358 thread_unlock(thread);
1c79356b
A
359 splx(s);
360}
361
1c79356b
A
362/*
363 * Set up thread timeout element when thread is created.
364 */
365void
366thread_timer_setup(
367 thread_t thread)
368{
0b4e3aa0
A
369 extern void thread_depress_expire(
370 timer_call_param_t p0,
371 timer_call_param_t p1);
372
1c79356b
A
373 timer_call_setup(&thread->wait_timer, thread_timer_expire, thread);
374 thread->wait_timer_is_set = FALSE;
375 thread->wait_timer_active = 1;
1c79356b 376
0b4e3aa0
A
377 timer_call_setup(&thread->depress_timer, thread_depress_expire, thread);
378 thread->depress_timer_active = 1;
379
380 thread->ref_count++;
1c79356b
A
381}
382
383void
384thread_timer_terminate(void)
385{
386 thread_t thread = current_thread();
9bccf70c 387 wait_result_t res;
1c79356b
A
388 spl_t s;
389
390 s = splsched();
55e303ae 391 thread_lock(thread);
1c79356b
A
392 if (thread->wait_timer_is_set) {
393 if (timer_call_cancel(&thread->wait_timer))
394 thread->wait_timer_active--;
395 thread->wait_timer_is_set = FALSE;
396 }
397
398 thread->wait_timer_active--;
399
400 while (thread->wait_timer_active > 0) {
55e303ae 401 thread_unlock(thread);
1c79356b
A
402 splx(s);
403
55e303ae 404 delay(1);
1c79356b
A
405
406 s = splsched();
55e303ae 407 thread_lock(thread);
1c79356b
A
408 }
409
0b4e3aa0
A
410 thread->depress_timer_active--;
411
412 while (thread->depress_timer_active > 0) {
55e303ae 413 thread_unlock(thread);
0b4e3aa0
A
414 splx(s);
415
55e303ae 416 delay(1);
0b4e3aa0
A
417
418 s = splsched();
55e303ae 419 thread_lock(thread);
0b4e3aa0
A
420 }
421
55e303ae 422 thread_unlock(thread);
1c79356b
A
423 splx(s);
424
425 thread_deallocate(thread);
426}
427
428/*
429 * Routine: thread_go_locked
430 * Purpose:
431 * Start a thread running.
432 * Conditions:
433 * thread lock held, IPC locks may be held.
434 * thread must have been pulled from wait queue under same lock hold.
9bccf70c
A
435 * Returns:
436 * KERN_SUCCESS - Thread was set running
437 * KERN_NOT_WAITING - Thread was not waiting
1c79356b 438 */
9bccf70c 439kern_return_t
1c79356b
A
440thread_go_locked(
441 thread_t thread,
55e303ae 442 wait_result_t wresult)
1c79356b 443{
1c79356b 444 assert(thread->at_safe_point == FALSE);
9bccf70c 445 assert(thread->wait_event == NO_EVENT64);
1c79356b
A
446 assert(thread->wait_queue == WAIT_QUEUE_NULL);
447
9bccf70c 448 if ((thread->state & (TH_WAIT|TH_TERMINATE)) == TH_WAIT) {
55e303ae
A
449 thread_roust_t roust_hint;
450
1c79356b 451 thread->state &= ~(TH_WAIT|TH_UNINT);
55e303ae
A
452 _mk_sp_thread_unblock(thread);
453
454 roust_hint = thread->roust;
455 thread->roust = NULL;
456 if ( roust_hint != NULL &&
457 (*roust_hint)(thread, wresult) ) {
458 if (thread->wait_timer_is_set) {
459 if (timer_call_cancel(&thread->wait_timer))
460 thread->wait_timer_active--;
461 thread->wait_timer_is_set = FALSE;
462 }
463
464 return (KERN_SUCCESS);
465 }
466
467 thread->wait_result = wresult;
468
1c79356b
A
469 if (!(thread->state & TH_RUN)) {
470 thread->state |= TH_RUN;
0b4e3aa0 471
9bccf70c
A
472 if (thread->active_callout)
473 call_thread_unblock();
474
55e303ae
A
475 pset_run_incr(thread->processor_set);
476 if (thread->sched_mode & TH_MODE_TIMESHARE)
477 pset_share_incr(thread->processor_set);
478
479 thread_setrun(thread, SCHED_PREEMPT | SCHED_TAILQ);
1c79356b 480 }
0b4e3aa0 481
55e303ae
A
482 KERNEL_DEBUG_CONSTANT(
483 MACHDBG_CODE(DBG_MACH_SCHED,MACH_MAKE_RUNNABLE) | DBG_FUNC_NONE,
484 (int)thread, (int)thread->sched_pri, 0, 0, 0);
485
486 return (KERN_SUCCESS);
1c79356b 487 }
55e303ae
A
488
489 return (KERN_NOT_WAITING);
1c79356b
A
490}
491
9bccf70c
A
492/*
493 * Routine: thread_mark_wait_locked
494 * Purpose:
495 * Mark a thread as waiting. If, given the circumstances,
496 * it doesn't want to wait (i.e. already aborted), then
497 * indicate that in the return value.
498 * Conditions:
499 * at splsched() and thread is locked.
500 */
501__private_extern__
502wait_result_t
1c79356b 503thread_mark_wait_locked(
9bccf70c
A
504 thread_t thread,
505 wait_interrupt_t interruptible)
1c79356b 506{
55e303ae 507 boolean_t at_safe_point;
1c79356b 508
9bccf70c
A
509 /*
510 * The thread may have certain types of interrupts/aborts masked
511 * off. Even if the wait location says these types of interrupts
512 * are OK, we have to honor mask settings (outer-scoped code may
513 * not be able to handle aborts at the moment).
514 */
515 if (interruptible > thread->interrupt_level)
516 interruptible = thread->interrupt_level;
517
518 at_safe_point = (interruptible == THREAD_ABORTSAFE);
519
55e303ae
A
520 if ( interruptible == THREAD_UNINT ||
521 !(thread->state & TH_ABORT) ||
522 (!at_safe_point &&
523 (thread->state & TH_ABORT_SAFELY)) ) {
9bccf70c
A
524 thread->state |= (interruptible) ? TH_WAIT : (TH_WAIT | TH_UNINT);
525 thread->at_safe_point = at_safe_point;
526 thread->sleep_stamp = sched_tick;
527 return (thread->wait_result = THREAD_WAITING);
9bccf70c 528 }
55e303ae
A
529 else
530 if (thread->state & TH_ABORT_SAFELY)
531 thread->state &= ~(TH_ABORT|TH_ABORT_SAFELY);
532
9bccf70c 533 return (thread->wait_result = THREAD_INTERRUPTED);
1c79356b
A
534}
535
9bccf70c
A
536/*
537 * Routine: thread_interrupt_level
538 * Purpose:
539 * Set the maximum interruptible state for the
540 * current thread. The effective value of any
541 * interruptible flag passed into assert_wait
542 * will never exceed this.
543 *
544 * Useful for code that must not be interrupted,
545 * but which calls code that doesn't know that.
546 * Returns:
547 * The old interrupt level for the thread.
548 */
549__private_extern__
550wait_interrupt_t
551thread_interrupt_level(
552 wait_interrupt_t new_level)
553{
554 thread_t thread = current_thread();
555 wait_interrupt_t result = thread->interrupt_level;
1c79356b 556
9bccf70c
A
557 thread->interrupt_level = new_level;
558 return result;
559}
1c79356b
A
560
561/*
562 * Routine: assert_wait_timeout
563 * Purpose:
564 * Assert that the thread intends to block,
565 * waiting for a timeout (no user known event).
566 */
567unsigned int assert_wait_timeout_event;
568
9bccf70c 569wait_result_t
1c79356b 570assert_wait_timeout(
9bccf70c
A
571 mach_msg_timeout_t msecs,
572 wait_interrupt_t interruptible)
1c79356b 573{
9bccf70c 574 wait_result_t res;
1c79356b 575
9bccf70c
A
576 res = assert_wait((event_t)&assert_wait_timeout_event, interruptible);
577 if (res == THREAD_WAITING)
578 thread_set_timer(msecs, 1000*NSEC_PER_USEC);
579 return res;
1c79356b
A
580}
581
582/*
583 * Check to see if an assert wait is possible, without actually doing one.
584 * This is used by debug code in locks and elsewhere to verify that it is
585 * always OK to block when trying to take a blocking lock (since waiting
586 * for the actual assert_wait to catch the case may make it hard to detect
587 * this case.
588 */
589boolean_t
590assert_wait_possible(void)
591{
592
593 thread_t thread;
594 extern unsigned int debug_mode;
595
596#if DEBUG
597 if(debug_mode) return TRUE; /* Always succeed in debug mode */
598#endif
599
600 thread = current_thread();
601
602 return (thread == NULL || wait_queue_assert_possible(thread));
603}
604
605/*
606 * assert_wait:
607 *
608 * Assert that the current thread is about to go to
609 * sleep until the specified event occurs.
610 */
9bccf70c 611wait_result_t
1c79356b
A
612assert_wait(
613 event_t event,
9bccf70c 614 wait_interrupt_t interruptible)
1c79356b
A
615{
616 register wait_queue_t wq;
617 register int index;
618
619 assert(event != NO_EVENT);
1c79356b
A
620
621 index = wait_hash(event);
622 wq = &wait_queues[index];
9bccf70c
A
623 return wait_queue_assert_wait(wq, event, interruptible);
624}
625
55e303ae
A
626__private_extern__
627wait_queue_t
628wait_event_wait_queue(
629 event_t event)
630{
631 assert(event != NO_EVENT);
632
633 return (&wait_queues[wait_hash(event)]);
634}
635
636wait_result_t
637assert_wait_prim(
638 event_t event,
639 thread_roust_t roust_hint,
640 uint64_t deadline,
641 wait_interrupt_t interruptible)
642{
643 thread_t thread = current_thread();
644 wait_result_t wresult;
645 wait_queue_t wq;
646 spl_t s;
647
648 assert(event != NO_EVENT);
649
650 wq = &wait_queues[wait_hash(event)];
651
652 s = splsched();
653 wait_queue_lock(wq);
654 thread_lock(thread);
655
656 wresult = wait_queue_assert_wait64_locked(wq, (uint32_t)event,
657 interruptible, thread);
658 if (wresult == THREAD_WAITING) {
659 if (roust_hint != NULL)
660 thread->roust = roust_hint;
661
662 if (deadline != 0) {
663 timer_call_enter(&thread->wait_timer, deadline);
664 assert(!thread->wait_timer_is_set);
665 thread->wait_timer_active++;
666 thread->wait_timer_is_set = TRUE;
667 }
668 }
669
670 thread_unlock(thread);
671 wait_queue_unlock(wq);
672 splx(s);
673
674 return (wresult);
675}
9bccf70c
A
676
677/*
678 * thread_sleep_fast_usimple_lock:
679 *
680 * Cause the current thread to wait until the specified event
681 * occurs. The specified simple_lock is unlocked before releasing
682 * the cpu and re-acquired as part of waking up.
683 *
684 * This is the simple lock sleep interface for components that use a
685 * faster version of simple_lock() than is provided by usimple_lock().
686 */
687__private_extern__ wait_result_t
688thread_sleep_fast_usimple_lock(
689 event_t event,
690 simple_lock_t lock,
691 wait_interrupt_t interruptible)
692{
693 wait_result_t res;
694
695 res = assert_wait(event, interruptible);
696 if (res == THREAD_WAITING) {
697 simple_unlock(lock);
698 res = thread_block(THREAD_CONTINUE_NULL);
699 simple_lock(lock);
700 }
701 return res;
1c79356b
A
702}
703
9bccf70c
A
704
705/*
706 * thread_sleep_usimple_lock:
707 *
708 * Cause the current thread to wait until the specified event
709 * occurs. The specified usimple_lock is unlocked before releasing
710 * the cpu and re-acquired as part of waking up.
711 *
712 * This is the simple lock sleep interface for components where
713 * simple_lock() is defined in terms of usimple_lock().
714 */
715wait_result_t
716thread_sleep_usimple_lock(
717 event_t event,
718 usimple_lock_t lock,
719 wait_interrupt_t interruptible)
720{
721 wait_result_t res;
722
723 res = assert_wait(event, interruptible);
724 if (res == THREAD_WAITING) {
725 usimple_unlock(lock);
726 res = thread_block(THREAD_CONTINUE_NULL);
727 usimple_lock(lock);
728 }
729 return res;
730}
731
732/*
733 * thread_sleep_mutex:
734 *
735 * Cause the current thread to wait until the specified event
736 * occurs. The specified mutex is unlocked before releasing
737 * the cpu. The mutex will be re-acquired before returning.
738 *
739 * JMM - Add hint to make sure mutex is available before rousting
740 */
741wait_result_t
742thread_sleep_mutex(
743 event_t event,
744 mutex_t *mutex,
745 wait_interrupt_t interruptible)
746{
747 wait_result_t res;
748
749 res = assert_wait(event, interruptible);
750 if (res == THREAD_WAITING) {
751 mutex_unlock(mutex);
752 res = thread_block(THREAD_CONTINUE_NULL);
753 mutex_lock(mutex);
754 }
755 return res;
756}
1c79356b 757
9bccf70c
A
758/*
759 * thread_sleep_mutex_deadline:
760 *
761 * Cause the current thread to wait until the specified event
762 * (or deadline) occurs. The specified mutex is unlocked before
763 * releasing the cpu. The mutex will be re-acquired before returning.
764 *
765 * JMM - Add hint to make sure mutex is available before rousting
766 */
767wait_result_t
768thread_sleep_mutex_deadline(
769 event_t event,
770 mutex_t *mutex,
771 uint64_t deadline,
772 wait_interrupt_t interruptible)
773{
774 wait_result_t res;
775
776 res = assert_wait(event, interruptible);
777 if (res == THREAD_WAITING) {
778 mutex_unlock(mutex);
779 thread_set_timer_deadline(deadline);
780 res = thread_block(THREAD_CONTINUE_NULL);
781 if (res != THREAD_TIMED_OUT)
782 thread_cancel_timer();
783 mutex_lock(mutex);
784 }
785 return res;
786}
787
788/*
789 * thread_sleep_lock_write:
790 *
791 * Cause the current thread to wait until the specified event
792 * occurs. The specified (write) lock is unlocked before releasing
793 * the cpu. The (write) lock will be re-acquired before returning.
794 *
795 * JMM - Add hint to make sure mutex is available before rousting
796 */
797wait_result_t
798thread_sleep_lock_write(
799 event_t event,
800 lock_t *lock,
801 wait_interrupt_t interruptible)
802{
803 wait_result_t res;
804
805 res = assert_wait(event, interruptible);
806 if (res == THREAD_WAITING) {
807 lock_write_done(lock);
808 res = thread_block(THREAD_CONTINUE_NULL);
809 lock_write(lock);
810 }
811 return res;
812}
813
814
815/*
816 * thread_sleep_funnel:
817 *
818 * Cause the current thread to wait until the specified event
819 * occurs. If the thread is funnelled, the funnel will be released
820 * before giving up the cpu. The funnel will be re-acquired before returning.
821 *
822 * JMM - Right now the funnel is dropped and re-acquired inside
823 * thread_block(). At some point, this may give thread_block() a hint.
824 */
825wait_result_t
826thread_sleep_funnel(
827 event_t event,
828 wait_interrupt_t interruptible)
829{
830 wait_result_t res;
831
832 res = assert_wait(event, interruptible);
833 if (res == THREAD_WAITING) {
834 res = thread_block(THREAD_CONTINUE_NULL);
835 }
836 return res;
837}
838
1c79356b
A
839/*
840 * thread_[un]stop(thread)
841 * Once a thread has blocked interruptibly (via assert_wait) prevent
842 * it from running until thread_unstop.
843 *
844 * If someone else has already stopped the thread, wait for the
845 * stop to be cleared, and then stop it again.
846 *
847 * Return FALSE if interrupted.
848 *
849 * NOTE: thread_hold/thread_suspend should be called on the activation
850 * before calling thread_stop. TH_SUSP is only recognized when
851 * a thread blocks and only prevents clear_wait/thread_wakeup
852 * from restarting an interruptible wait. The wake_active flag is
853 * used to indicate that someone is waiting on the thread.
854 */
855boolean_t
856thread_stop(
9bccf70c 857 thread_t thread)
1c79356b 858{
9bccf70c 859 spl_t s = splsched();
1c79356b 860
1c79356b
A
861 wake_lock(thread);
862
863 while (thread->state & TH_SUSP) {
9bccf70c 864 wait_result_t result;
e7c99d92 865
1c79356b 866 thread->wake_active = TRUE;
9bccf70c 867 result = assert_wait(&thread->wake_active, THREAD_ABORTSAFE);
1c79356b
A
868 wake_unlock(thread);
869 splx(s);
870
9bccf70c
A
871 if (result == THREAD_WAITING)
872 result = thread_block(THREAD_CONTINUE_NULL);
873
874 if (result != THREAD_AWAKENED)
1c79356b
A
875 return (FALSE);
876
877 s = splsched();
878 wake_lock(thread);
879 }
9bccf70c 880
1c79356b
A
881 thread_lock(thread);
882 thread->state |= TH_SUSP;
1c79356b 883
9bccf70c
A
884 while (thread->state & TH_RUN) {
885 wait_result_t result;
886 processor_t processor = thread->last_processor;
887
55e303ae
A
888 if ( processor != PROCESSOR_NULL &&
889 processor->state == PROCESSOR_RUNNING &&
890 processor->active_thread == thread )
9bccf70c
A
891 cause_ast_check(processor);
892 thread_unlock(thread);
893
894 thread->wake_active = TRUE;
895 result = assert_wait(&thread->wake_active, THREAD_ABORTSAFE);
896 wake_unlock(thread);
897 splx(s);
898
899 if (result == THREAD_WAITING)
900 result = thread_block(THREAD_CONTINUE_NULL);
901
902 if (result != THREAD_AWAKENED) {
903 thread_unstop(thread);
904 return (FALSE);
905 }
906
907 s = splsched();
908 wake_lock(thread);
909 thread_lock(thread);
910 }
911
912 thread_unlock(thread);
1c79356b
A
913 wake_unlock(thread);
914 splx(s);
915
916 return (TRUE);
917}
918
919/*
920 * Clear TH_SUSP and if the thread has been stopped and is now runnable,
921 * put it back on the run queue.
922 */
923void
924thread_unstop(
9bccf70c 925 thread_t thread)
1c79356b 926{
9bccf70c 927 spl_t s = splsched();
1c79356b 928
1c79356b
A
929 wake_lock(thread);
930 thread_lock(thread);
931
9bccf70c 932 if ((thread->state & (TH_RUN|TH_WAIT|TH_SUSP)) == TH_SUSP) {
0b4e3aa0
A
933 thread->state &= ~TH_SUSP;
934 thread->state |= TH_RUN;
935
936 _mk_sp_thread_unblock(thread);
55e303ae
A
937
938 pset_run_incr(thread->processor_set);
939 if (thread->sched_mode & TH_MODE_TIMESHARE)
940 pset_share_incr(thread->processor_set);
941
942 thread_setrun(thread, SCHED_PREEMPT | SCHED_TAILQ);
943
944 KERNEL_DEBUG_CONSTANT(
945 MACHDBG_CODE(DBG_MACH_SCHED,MACH_MAKE_RUNNABLE) | DBG_FUNC_NONE,
946 (int)thread, (int)thread->sched_pri, 0, 0, 0);
1c79356b
A
947 }
948 else
949 if (thread->state & TH_SUSP) {
950 thread->state &= ~TH_SUSP;
951
952 if (thread->wake_active) {
953 thread->wake_active = FALSE;
954 thread_unlock(thread);
955 wake_unlock(thread);
956 splx(s);
1c79356b 957
9bccf70c 958 thread_wakeup(&thread->wake_active);
1c79356b
A
959 return;
960 }
961 }
962
963 thread_unlock(thread);
964 wake_unlock(thread);
965 splx(s);
966}
967
968/*
969 * Wait for the thread's RUN bit to clear
970 */
971boolean_t
972thread_wait(
9bccf70c 973 thread_t thread)
1c79356b 974{
9bccf70c 975 spl_t s = splsched();
1c79356b 976
1c79356b 977 wake_lock(thread);
9bccf70c 978 thread_lock(thread);
1c79356b 979
9bccf70c
A
980 while (thread->state & TH_RUN) {
981 wait_result_t result;
982 processor_t processor = thread->last_processor;
e7c99d92 983
55e303ae
A
984 if ( processor != PROCESSOR_NULL &&
985 processor->state == PROCESSOR_RUNNING &&
986 processor->active_thread == thread )
9bccf70c
A
987 cause_ast_check(processor);
988 thread_unlock(thread);
1c79356b
A
989
990 thread->wake_active = TRUE;
9bccf70c 991 result = assert_wait(&thread->wake_active, THREAD_ABORTSAFE);
1c79356b
A
992 wake_unlock(thread);
993 splx(s);
994
9bccf70c
A
995 if (result == THREAD_WAITING)
996 result = thread_block(THREAD_CONTINUE_NULL);
997
998 if (result != THREAD_AWAKENED)
999 return (FALSE);
1c79356b
A
1000
1001 s = splsched();
1002 wake_lock(thread);
9bccf70c 1003 thread_lock(thread);
1c79356b 1004 }
0b4e3aa0 1005
9bccf70c 1006 thread_unlock(thread);
1c79356b
A
1007 wake_unlock(thread);
1008 splx(s);
0b4e3aa0
A
1009
1010 return (TRUE);
1c79356b
A
1011}
1012
1c79356b
A
1013/*
1014 * Routine: clear_wait_internal
1015 *
1016 * Clear the wait condition for the specified thread.
1017 * Start the thread executing if that is appropriate.
1018 * Arguments:
1019 * thread thread to awaken
1020 * result Wakeup result the thread should see
1021 * Conditions:
1022 * At splsched
1023 * the thread is locked.
9bccf70c
A
1024 * Returns:
1025 * KERN_SUCCESS thread was rousted out a wait
1026 * KERN_FAILURE thread was waiting but could not be rousted
1027 * KERN_NOT_WAITING thread was not waiting
1c79356b 1028 */
9bccf70c 1029__private_extern__ kern_return_t
1c79356b 1030clear_wait_internal(
9bccf70c 1031 thread_t thread,
55e303ae 1032 wait_result_t wresult)
1c79356b 1033{
9bccf70c 1034 wait_queue_t wq = thread->wait_queue;
55e303ae 1035 int i = LockTimeOut;
9bccf70c 1036
9bccf70c 1037 do {
55e303ae
A
1038 if (wresult == THREAD_INTERRUPTED && (thread->state & TH_UNINT))
1039 return (KERN_FAILURE);
9bccf70c
A
1040
1041 if (wq != WAIT_QUEUE_NULL) {
1042 if (wait_queue_lock_try(wq)) {
1043 wait_queue_pull_thread_locked(wq, thread, TRUE);
1044 /* wait queue unlocked, thread still locked */
55e303ae
A
1045 }
1046 else {
9bccf70c
A
1047 thread_unlock(thread);
1048 delay(1);
55e303ae 1049
9bccf70c 1050 thread_lock(thread);
55e303ae
A
1051 if (wq != thread->wait_queue)
1052 return (KERN_NOT_WAITING);
9bccf70c 1053
9bccf70c
A
1054 continue;
1055 }
1c79356b 1056 }
55e303ae
A
1057
1058 return (thread_go_locked(thread, wresult));
1059 } while (--i > 0);
1060
9bccf70c
A
1061 panic("clear_wait_internal: deadlock: thread=0x%x, wq=0x%x, cpu=%d\n",
1062 thread, wq, cpu_number());
55e303ae
A
1063
1064 return (KERN_FAILURE);
1c79356b
A
1065}
1066
1067
1068/*
1069 * clear_wait:
1070 *
1071 * Clear the wait condition for the specified thread. Start the thread
1072 * executing if that is appropriate.
1073 *
1074 * parameters:
1075 * thread thread to awaken
1076 * result Wakeup result the thread should see
1077 */
9bccf70c 1078kern_return_t
1c79356b 1079clear_wait(
9bccf70c
A
1080 thread_t thread,
1081 wait_result_t result)
1c79356b 1082{
9bccf70c 1083 kern_return_t ret;
1c79356b
A
1084 spl_t s;
1085
1086 s = splsched();
1087 thread_lock(thread);
9bccf70c 1088 ret = clear_wait_internal(thread, result);
1c79356b
A
1089 thread_unlock(thread);
1090 splx(s);
9bccf70c 1091 return ret;
1c79356b
A
1092}
1093
1094
1095/*
1096 * thread_wakeup_prim:
1097 *
1098 * Common routine for thread_wakeup, thread_wakeup_with_result,
1099 * and thread_wakeup_one.
1100 *
1101 */
9bccf70c 1102kern_return_t
1c79356b
A
1103thread_wakeup_prim(
1104 event_t event,
1105 boolean_t one_thread,
9bccf70c 1106 wait_result_t result)
1c79356b
A
1107{
1108 register wait_queue_t wq;
1109 register int index;
1110
1111 index = wait_hash(event);
1112 wq = &wait_queues[index];
1113 if (one_thread)
9bccf70c 1114 return (wait_queue_wakeup_one(wq, event, result));
1c79356b 1115 else
9bccf70c 1116 return (wait_queue_wakeup_all(wq, event, result));
1c79356b
A
1117}
1118
1119/*
1120 * thread_bind:
1121 *
1122 * Force a thread to execute on the specified processor.
1c79356b 1123 *
55e303ae
A
1124 * Returns the previous binding. PROCESSOR_NULL means
1125 * not bound.
1126 *
1127 * XXX - DO NOT export this to users - XXX
1c79356b 1128 */
55e303ae 1129processor_t
1c79356b
A
1130thread_bind(
1131 register thread_t thread,
1132 processor_t processor)
1133{
55e303ae
A
1134 processor_t prev;
1135 run_queue_t runq = RUN_QUEUE_NULL;
1136 spl_t s;
1c79356b
A
1137
1138 s = splsched();
1139 thread_lock(thread);
55e303ae
A
1140 prev = thread->bound_processor;
1141 if (prev != PROCESSOR_NULL)
1142 runq = run_queue_remove(thread);
1143
1144 thread->bound_processor = processor;
1145
1146 if (runq != RUN_QUEUE_NULL)
1147 thread_setrun(thread, SCHED_PREEMPT | SCHED_TAILQ);
1c79356b
A
1148 thread_unlock(thread);
1149 splx(s);
55e303ae
A
1150
1151 return (prev);
1c79356b
A
1152}
1153
55e303ae
A
1154struct {
1155 uint32_t idle_pset_last,
1156 idle_pset_any,
1157 idle_bound;
1158
1159 uint32_t pset_self,
1160 pset_last,
1161 pset_other,
1162 bound_self,
1163 bound_other;
1164
1165 uint32_t realtime_self,
1166 realtime_last,
1167 realtime_other;
1168
1169 uint32_t missed_realtime,
1170 missed_other;
1171} dispatch_counts;
1172
1c79356b 1173/*
55e303ae
A
1174 * Select a thread for the current processor to run.
1175 *
1176 * May select the current thread, which must be locked.
1c79356b
A
1177 */
1178thread_t
1179thread_select(
55e303ae 1180 register processor_t processor)
1c79356b
A
1181{
1182 register thread_t thread;
1183 processor_set_t pset;
1c79356b 1184 boolean_t other_runnable;
1c79356b
A
1185
1186 /*
1187 * Check for other non-idle runnable threads.
1188 */
55e303ae
A
1189 pset = processor->processor_set;
1190 thread = processor->active_thread;
0b4e3aa0
A
1191
1192 /* Update the thread's priority */
1193 if (thread->sched_stamp != sched_tick)
1194 update_priority(thread);
1c79356b 1195
55e303ae 1196 processor->current_pri = thread->sched_pri;
9bccf70c 1197
55e303ae 1198 simple_lock(&pset->sched_lock);
1c79356b 1199
55e303ae 1200 other_runnable = processor->runq.count > 0 || pset->runq.count > 0;
1c79356b
A
1201
1202 if ( thread->state == TH_RUN &&
1c79356b
A
1203 thread->processor_set == pset &&
1204 (thread->bound_processor == PROCESSOR_NULL ||
55e303ae
A
1205 thread->bound_processor == processor) ) {
1206 if ( thread->sched_pri >= BASEPRI_RTQUEUES &&
1207 first_timeslice(processor) ) {
1208 if (pset->runq.highq >= BASEPRI_RTQUEUES) {
1209 register run_queue_t runq = &pset->runq;
1210 register queue_t q;
1211
1212 q = runq->queues + runq->highq;
1213 if (((thread_t)q->next)->realtime.deadline <
1214 processor->deadline) {
1215 thread = (thread_t)q->next;
1216 ((queue_entry_t)thread)->next->prev = q;
1217 q->next = ((queue_entry_t)thread)->next;
1218 thread->runq = RUN_QUEUE_NULL;
1219 assert(thread->sched_mode & TH_MODE_PREEMPT);
1220 runq->count--; runq->urgency--;
1221 if (queue_empty(q)) {
1222 if (runq->highq != IDLEPRI)
1223 clrbit(MAXPRI - runq->highq, runq->bitmap);
1224 runq->highq = MAXPRI - ffsbit(runq->bitmap);
1225 }
1226 }
1227 }
1228
1229 processor->deadline = thread->realtime.deadline;
1230
1231 simple_unlock(&pset->sched_lock);
1232
1233 return (thread);
1234 }
1c79356b 1235
55e303ae
A
1236 if ( (!other_runnable ||
1237 (processor->runq.highq < thread->sched_pri &&
1238 pset->runq.highq < thread->sched_pri)) ) {
1c79356b 1239
55e303ae
A
1240 /* I am the highest priority runnable (non-idle) thread */
1241
1242 processor->deadline = UINT64_MAX;
1243
1244 simple_unlock(&pset->sched_lock);
1245
1246 return (thread);
1247 }
1c79356b 1248 }
55e303ae 1249
9bccf70c 1250 if (other_runnable)
55e303ae 1251 thread = choose_thread(pset, processor);
1c79356b 1252 else {
1c79356b
A
1253 /*
1254 * Nothing is runnable, so set this processor idle if it
55e303ae 1255 * was running. Return its idle thread.
1c79356b 1256 */
55e303ae
A
1257 if (processor->state == PROCESSOR_RUNNING) {
1258 remqueue(&pset->active_queue, (queue_entry_t)processor);
1259 processor->state = PROCESSOR_IDLE;
1c79356b 1260
55e303ae 1261 enqueue_tail(&pset->idle_queue, (queue_entry_t)processor);
1c79356b
A
1262 pset->idle_count++;
1263 }
1c79356b 1264
55e303ae
A
1265 processor->deadline = UINT64_MAX;
1266
1267 thread = processor->idle_thread;
1c79356b
A
1268 }
1269
55e303ae
A
1270 simple_unlock(&pset->sched_lock);
1271
1c79356b
A
1272 return (thread);
1273}
1274
1c79356b 1275/*
55e303ae
A
1276 * Perform a context switch and start executing the new thread.
1277 *
1278 * If continuation is non-zero, resume the old (current) thread
1279 * next by executing at continuation on a new stack, in lieu
1280 * of returning.
1281 *
1c79356b 1282 * Returns TRUE if the hand-off succeeds.
9bccf70c 1283 *
55e303ae 1284 * Called at splsched.
1c79356b
A
1285 */
1286
55e303ae
A
1287#define funnel_release_check(thread, debug) \
1288MACRO_BEGIN \
1289 if ((thread)->funnel_state & TH_FN_OWNED) { \
1290 (thread)->funnel_state = TH_FN_REFUNNEL; \
1291 KERNEL_DEBUG(0x603242c | DBG_FUNC_NONE, \
1292 (thread)->funnel_lock, (debug), 0, 0, 0); \
1293 funnel_unlock((thread)->funnel_lock); \
1294 } \
1295MACRO_END
1296
1297#define funnel_refunnel_check(thread, debug) \
1298MACRO_BEGIN \
1299 if ((thread)->funnel_state & TH_FN_REFUNNEL) { \
1300 kern_return_t result = (thread)->wait_result; \
1301 \
1302 (thread)->funnel_state = 0; \
1303 KERNEL_DEBUG(0x6032428 | DBG_FUNC_NONE, \
1304 (thread)->funnel_lock, (debug), 0, 0, 0); \
1305 funnel_lock((thread)->funnel_lock); \
1306 KERNEL_DEBUG(0x6032430 | DBG_FUNC_NONE, \
1307 (thread)->funnel_lock, (debug), 0, 0, 0); \
1308 (thread)->funnel_state = TH_FN_OWNED; \
1309 (thread)->wait_result = result; \
1310 } \
1311MACRO_END
1312
1c79356b
A
1313static thread_t
1314__current_thread(void)
1315{
1316 return (current_thread());
1317}
1318
1319boolean_t
1320thread_invoke(
1321 register thread_t old_thread,
1322 register thread_t new_thread,
1323 int reason,
9bccf70c 1324 thread_continue_t old_cont)
1c79356b 1325{
9bccf70c
A
1326 thread_continue_t new_cont;
1327 processor_t processor;
1c79356b 1328
9bccf70c 1329 if (get_preemption_level() != 0)
0b4e3aa0 1330 panic("thread_invoke: preemption_level %d\n",
9bccf70c 1331 get_preemption_level());
0b4e3aa0 1332
1c79356b 1333 /*
9bccf70c 1334 * Mark thread interruptible.
1c79356b
A
1335 */
1336 thread_lock(new_thread);
1337 new_thread->state &= ~TH_UNINT;
1338
1c79356b
A
1339 assert(thread_runnable(new_thread));
1340
9bccf70c 1341 assert(old_thread->continuation == NULL);
1c79356b 1342
9bccf70c
A
1343 /*
1344 * Allow time constraint threads to hang onto
1345 * a stack.
1346 */
0b4e3aa0 1347 if ( (old_thread->sched_mode & TH_MODE_REALTIME) &&
55e303ae
A
1348 !old_thread->reserved_stack ) {
1349 old_thread->reserved_stack = old_thread->kernel_stack;
1c79356b
A
1350 }
1351
9bccf70c
A
1352 if (old_cont != NULL) {
1353 if (new_thread->state & TH_STACK_HANDOFF) {
1354 /*
1355 * If the old thread is using a privileged stack,
1356 * check to see whether we can exchange it with
1357 * that of the new thread.
1358 */
55e303ae
A
1359 if ( old_thread->kernel_stack == old_thread->reserved_stack &&
1360 !new_thread->reserved_stack)
9bccf70c 1361 goto need_stack;
1c79356b 1362
9bccf70c
A
1363 new_thread->state &= ~TH_STACK_HANDOFF;
1364 new_cont = new_thread->continuation;
1365 new_thread->continuation = NULL;
1c79356b 1366
9bccf70c
A
1367 /*
1368 * Set up ast context of new thread and switch
1369 * to its timer.
1370 */
1371 processor = current_processor();
55e303ae 1372 processor->active_thread = new_thread;
9bccf70c 1373 processor->current_pri = new_thread->sched_pri;
55e303ae 1374 new_thread->last_processor = processor;
9bccf70c
A
1375 ast_context(new_thread->top_act, processor->slot_num);
1376 timer_switch(&new_thread->system_timer);
1377 thread_unlock(new_thread);
0b4e3aa0 1378
9bccf70c 1379 current_task()->csw++;
1c79356b 1380
9bccf70c
A
1381 old_thread->reason = reason;
1382 old_thread->continuation = old_cont;
0b4e3aa0 1383
9bccf70c 1384 _mk_sp_thread_done(old_thread, new_thread, processor);
1c79356b 1385
55e303ae 1386 machine_stack_handoff(old_thread, new_thread);
9bccf70c
A
1387
1388 _mk_sp_thread_begin(new_thread, processor);
1c79356b 1389
1c79356b
A
1390 wake_lock(old_thread);
1391 thread_lock(old_thread);
1c79356b 1392
9bccf70c
A
1393 /*
1394 * Inline thread_dispatch but
1395 * don't free stack.
1396 */
1397
1398 switch (old_thread->state & (TH_RUN|TH_WAIT|TH_UNINT|TH_IDLE)) {
1399
1400 case TH_RUN | TH_UNINT:
1401 case TH_RUN:
1402 /*
1403 * Still running, put back
1404 * onto a run queue.
1405 */
1406 old_thread->state |= TH_STACK_HANDOFF;
1407 _mk_sp_thread_dispatch(old_thread);
1408
1409 thread_unlock(old_thread);
1410 wake_unlock(old_thread);
1411 break;
1c79356b 1412
9bccf70c
A
1413 case TH_RUN | TH_WAIT | TH_UNINT:
1414 case TH_RUN | TH_WAIT:
1415 {
55e303ae 1416 boolean_t term, wake, callout;
1c79356b 1417
9bccf70c
A
1418 /*
1419 * Waiting.
1420 */
1421 old_thread->sleep_stamp = sched_tick;
1422 old_thread->state |= TH_STACK_HANDOFF;
1423 old_thread->state &= ~TH_RUN;
55e303ae
A
1424
1425 term = (old_thread->state & TH_TERMINATE)? TRUE: FALSE;
1426 callout = old_thread->active_callout;
9bccf70c
A
1427 wake = old_thread->wake_active;
1428 old_thread->wake_active = FALSE;
55e303ae
A
1429
1430 if (old_thread->sched_mode & TH_MODE_TIMESHARE)
1431 pset_share_decr(old_thread->processor_set);
1432 pset_run_decr(old_thread->processor_set);
9bccf70c
A
1433
1434 thread_unlock(old_thread);
1435 wake_unlock(old_thread);
1436
55e303ae 1437 if (callout)
9bccf70c
A
1438 call_thread_block();
1439
1440 if (wake)
1441 thread_wakeup((event_t)&old_thread->wake_active);
1442
55e303ae 1443 if (term)
9bccf70c
A
1444 thread_reaper_enqueue(old_thread);
1445 break;
1446 }
1c79356b 1447
9bccf70c
A
1448 case TH_RUN | TH_IDLE:
1449 /*
1450 * The idle threads don't go
1451 * onto a run queue.
1452 */
1453 old_thread->state |= TH_STACK_HANDOFF;
1454 thread_unlock(old_thread);
1455 wake_unlock(old_thread);
1456 break;
1c79356b 1457
9bccf70c
A
1458 default:
1459 panic("thread_invoke: state 0x%x\n", old_thread->state);
1460 }
1c79356b 1461
9bccf70c 1462 counter_always(c_thread_invoke_hits++);
1c79356b 1463
55e303ae 1464 funnel_refunnel_check(new_thread, 2);
9bccf70c 1465 (void) spllo();
1c79356b 1466
9bccf70c
A
1467 assert(new_cont);
1468 call_continuation(new_cont);
1469 /*NOTREACHED*/
1470 return (TRUE);
1c79356b 1471 }
9bccf70c
A
1472 else
1473 if (new_thread->state & TH_STACK_ALLOC) {
1474 /*
1475 * Waiting for a stack
1476 */
1c79356b 1477 counter_always(c_thread_invoke_misses++);
9bccf70c
A
1478 thread_unlock(new_thread);
1479 return (FALSE);
1480 }
1481 else
1482 if (new_thread == old_thread) {
1483 /* same thread but with continuation */
1484 counter(++c_thread_invoke_same);
1485 thread_unlock(new_thread);
1486
55e303ae 1487 funnel_refunnel_check(new_thread, 3);
9bccf70c 1488 (void) spllo();
55e303ae 1489
9bccf70c
A
1490 call_continuation(old_cont);
1491 /*NOTREACHED*/
1492 }
1c79356b 1493 }
9bccf70c
A
1494 else {
1495 /*
1496 * Check that the new thread has a stack
1497 */
1498 if (new_thread->state & TH_STACK_HANDOFF) {
1499need_stack:
1500 if (!stack_alloc_try(new_thread, thread_continue)) {
1501 counter_always(c_thread_invoke_misses++);
1502 thread_swapin(new_thread);
1503 return (FALSE);
1504 }
1c79356b 1505
9bccf70c
A
1506 new_thread->state &= ~TH_STACK_HANDOFF;
1507 }
1508 else
1509 if (new_thread->state & TH_STACK_ALLOC) {
1510 /*
1511 * Waiting for a stack
1512 */
1513 counter_always(c_thread_invoke_misses++);
1514 thread_unlock(new_thread);
1515 return (FALSE);
1516 }
1517 else
1518 if (old_thread == new_thread) {
1519 counter(++c_thread_invoke_same);
1520 thread_unlock(new_thread);
1521 return (TRUE);
1522 }
1523 }
1c79356b
A
1524
1525 /*
9bccf70c 1526 * Set up ast context of new thread and switch to its timer.
1c79356b 1527 */
9bccf70c 1528 processor = current_processor();
55e303ae 1529 processor->active_thread = new_thread;
9bccf70c 1530 processor->current_pri = new_thread->sched_pri;
55e303ae 1531 new_thread->last_processor = processor;
9bccf70c 1532 ast_context(new_thread->top_act, processor->slot_num);
1c79356b
A
1533 timer_switch(&new_thread->system_timer);
1534 assert(thread_runnable(new_thread));
1c79356b
A
1535 thread_unlock(new_thread);
1536
1537 counter_always(c_thread_invoke_csw++);
1538 current_task()->csw++;
1539
1c79356b 1540 assert(old_thread->runq == RUN_QUEUE_NULL);
9bccf70c
A
1541 old_thread->reason = reason;
1542 old_thread->continuation = old_cont;
1c79356b 1543
9bccf70c 1544 _mk_sp_thread_done(old_thread, new_thread, processor);
1c79356b
A
1545
1546 /*
55e303ae
A
1547 * Here is where we actually change register context,
1548 * and address space if required. Note that control
1549 * will not return here immediately.
1c79356b 1550 */
55e303ae 1551 old_thread = machine_switch_context(old_thread, old_cont, new_thread);
1c79356b
A
1552
1553 /* Now on new thread's stack. Set a local variable to refer to it. */
1554 new_thread = __current_thread();
1555 assert(old_thread != new_thread);
1556
1c79356b 1557 assert(thread_runnable(new_thread));
9bccf70c 1558 _mk_sp_thread_begin(new_thread, new_thread->last_processor);
1c79356b
A
1559
1560 /*
1561 * We're back. Now old_thread is the thread that resumed
1562 * us, and we have to dispatch it.
1563 */
1c79356b 1564 thread_dispatch(old_thread);
9bccf70c
A
1565
1566 if (old_cont) {
55e303ae 1567 funnel_refunnel_check(new_thread, 3);
9bccf70c 1568 (void) spllo();
55e303ae 1569
9bccf70c
A
1570 call_continuation(old_cont);
1571 /*NOTREACHED*/
1c79356b
A
1572 }
1573
9bccf70c 1574 return (TRUE);
1c79356b
A
1575}
1576
1577/*
1578 * thread_continue:
1579 *
55e303ae
A
1580 * Called at splsched when a thread first receives
1581 * a new stack after a continuation.
1c79356b
A
1582 */
1583void
1584thread_continue(
0b4e3aa0 1585 register thread_t old_thread)
1c79356b 1586{
9bccf70c
A
1587 register thread_t self = current_thread();
1588 register thread_continue_t continuation;
1589
1590 continuation = self->continuation;
1591 self->continuation = NULL;
1592
1593 _mk_sp_thread_begin(self, self->last_processor);
1c79356b
A
1594
1595 /*
1596 * We must dispatch the old thread and then
1597 * call the current thread's continuation.
1598 * There might not be an old thread, if we are
1599 * the first thread to run on this processor.
1600 */
0b4e3aa0 1601 if (old_thread != THREAD_NULL)
1c79356b 1602 thread_dispatch(old_thread);
1c79356b 1603
55e303ae 1604 funnel_refunnel_check(self, 4);
9bccf70c 1605 (void)spllo();
55e303ae 1606
9bccf70c 1607 call_continuation(continuation);
1c79356b
A
1608 /*NOTREACHED*/
1609}
1610
1c79356b
A
1611/*
1612 * thread_block_reason:
1613 *
55e303ae
A
1614 * Forces a reschedule, blocking the caller if a wait
1615 * has been asserted.
1616 *
1617 * If a continuation is specified, then thread_invoke will
1c79356b
A
1618 * attempt to discard the thread's kernel stack. When the
1619 * thread resumes, it will execute the continuation function
1620 * on a new kernel stack.
1621 */
1622counter(mach_counter_t c_thread_block_calls = 0;)
1623
1624int
1625thread_block_reason(
9bccf70c
A
1626 thread_continue_t continuation,
1627 ast_t reason)
1c79356b
A
1628{
1629 register thread_t thread = current_thread();
55e303ae 1630 register processor_t processor;
1c79356b
A
1631 register thread_t new_thread;
1632 spl_t s;
1633
1634 counter(++c_thread_block_calls);
1635
1636 check_simple_locks();
1637
1c79356b
A
1638 s = splsched();
1639
55e303ae
A
1640 if (!(reason & AST_PREEMPT))
1641 funnel_release_check(thread, 2);
1c79356b 1642
55e303ae 1643 processor = current_processor();
1c79356b 1644
9bccf70c
A
1645 /* If we're explicitly yielding, force a subsequent quantum */
1646 if (reason & AST_YIELD)
55e303ae 1647 processor->timeslice = 0;
0b4e3aa0 1648
9bccf70c
A
1649 /* We're handling all scheduling AST's */
1650 ast_off(AST_SCHEDULING);
1c79356b 1651
9bccf70c 1652 thread_lock(thread);
55e303ae 1653 new_thread = thread_select(processor);
9bccf70c 1654 assert(new_thread && thread_runnable(new_thread));
1c79356b
A
1655 thread_unlock(thread);
1656 while (!thread_invoke(thread, new_thread, reason, continuation)) {
1657 thread_lock(thread);
55e303ae 1658 new_thread = thread_select(processor);
9bccf70c 1659 assert(new_thread && thread_runnable(new_thread));
1c79356b
A
1660 thread_unlock(thread);
1661 }
1662
55e303ae 1663 funnel_refunnel_check(thread, 5);
1c79356b
A
1664 splx(s);
1665
9bccf70c 1666 return (thread->wait_result);
1c79356b
A
1667}
1668
1669/*
1670 * thread_block:
1671 *
9bccf70c 1672 * Block the current thread if a wait has been asserted.
1c79356b
A
1673 */
1674int
1675thread_block(
9bccf70c 1676 thread_continue_t continuation)
1c79356b 1677{
0b4e3aa0 1678 return thread_block_reason(continuation, AST_NONE);
1c79356b
A
1679}
1680
1681/*
1682 * thread_run:
1683 *
9bccf70c 1684 * Switch directly from the current (old) thread to the
55e303ae 1685 * new thread, handing off our quantum if appropriate.
9bccf70c
A
1686 *
1687 * New thread must be runnable, and not on a run queue.
1c79356b 1688 *
55e303ae 1689 * Called at splsched.
1c79356b
A
1690 */
1691int
1692thread_run(
9bccf70c
A
1693 thread_t old_thread,
1694 thread_continue_t continuation,
1695 thread_t new_thread)
1c79356b 1696{
9bccf70c
A
1697 ast_t handoff = AST_HANDOFF;
1698
1699 assert(old_thread == current_thread());
1700
55e303ae 1701 funnel_release_check(old_thread, 3);
9bccf70c
A
1702
1703 while (!thread_invoke(old_thread, new_thread, handoff, continuation)) {
55e303ae 1704 register processor_t processor = current_processor();
9bccf70c 1705
1c79356b 1706 thread_lock(old_thread);
55e303ae 1707 new_thread = thread_select(processor);
1c79356b 1708 thread_unlock(old_thread);
9bccf70c
A
1709 handoff = AST_NONE;
1710 }
1711
55e303ae 1712 funnel_refunnel_check(old_thread, 6);
9bccf70c
A
1713
1714 return (old_thread->wait_result);
1c79356b
A
1715}
1716
1717/*
55e303ae
A
1718 * Dispatches a running thread that is not on a
1719 * run queue.
1720 *
1c79356b
A
1721 * Called at splsched.
1722 */
1723void
1724thread_dispatch(
1725 register thread_t thread)
1726{
9bccf70c
A
1727 wake_lock(thread);
1728 thread_lock(thread);
1729
1c79356b
A
1730 /*
1731 * If we are discarding the thread's stack, we must do it
1732 * before the thread has a chance to run.
1733 */
1c79356b 1734#ifndef i386
9bccf70c
A
1735 if (thread->continuation != NULL) {
1736 assert((thread->state & TH_STACK_STATE) == 0);
1737 thread->state |= TH_STACK_HANDOFF;
1738 stack_free(thread);
1739 }
1c79356b
A
1740#endif
1741
1742 switch (thread->state & (TH_RUN|TH_WAIT|TH_UNINT|TH_IDLE)) {
1743
1744 case TH_RUN | TH_UNINT:
1745 case TH_RUN:
1746 /*
1747 * No reason to stop. Put back on a run queue.
1748 */
0b4e3aa0 1749 _mk_sp_thread_dispatch(thread);
1c79356b
A
1750 break;
1751
1752 case TH_RUN | TH_WAIT | TH_UNINT:
1753 case TH_RUN | TH_WAIT:
9bccf70c 1754 {
55e303ae 1755 boolean_t term, wake, callout;
1c79356b
A
1756
1757 /*
1758 * Waiting
1759 */
9bccf70c 1760 thread->sleep_stamp = sched_tick;
1c79356b 1761 thread->state &= ~TH_RUN;
55e303ae
A
1762
1763 term = (thread->state & TH_TERMINATE)? TRUE: FALSE;
1764 callout = thread->active_callout;
9bccf70c
A
1765 wake = thread->wake_active;
1766 thread->wake_active = FALSE;
55e303ae
A
1767
1768 if (thread->sched_mode & TH_MODE_TIMESHARE)
1769 pset_share_decr(thread->processor_set);
1770 pset_run_decr(thread->processor_set);
1c79356b 1771
9bccf70c
A
1772 thread_unlock(thread);
1773 wake_unlock(thread);
1774
55e303ae 1775 if (callout)
9bccf70c
A
1776 call_thread_block();
1777
1778 if (wake)
1c79356b 1779 thread_wakeup((event_t)&thread->wake_active);
9bccf70c 1780
55e303ae 1781 if (term)
9bccf70c
A
1782 thread_reaper_enqueue(thread);
1783
1784 return;
1785 }
1c79356b
A
1786
1787 case TH_RUN | TH_IDLE:
1788 /*
9bccf70c
A
1789 * The idle threads don't go
1790 * onto a run queue.
1c79356b
A
1791 */
1792 break;
1793
1794 default:
55e303ae 1795 panic("thread_dispatch: state 0x%x\n", thread->state);
1c79356b 1796 }
9bccf70c 1797
1c79356b
A
1798 thread_unlock(thread);
1799 wake_unlock(thread);
1800}
1801
1802/*
55e303ae
A
1803 * Enqueue thread on run queue. Thread must be locked,
1804 * and not already be on a run queue. Returns TRUE
1805 * if a preemption is indicated based on the state
1806 * of the run queue.
1807 *
1808 * Run queue must be locked, see run_queue_remove()
1809 * for more info.
1c79356b 1810 */
55e303ae 1811static boolean_t
1c79356b
A
1812run_queue_enqueue(
1813 register run_queue_t rq,
1814 register thread_t thread,
55e303ae 1815 integer_t options)
1c79356b 1816{
9bccf70c
A
1817 register int whichq = thread->sched_pri;
1818 register queue_t queue = &rq->queues[whichq];
1819 boolean_t result = FALSE;
1c79356b 1820
1c79356b
A
1821 assert(whichq >= MINPRI && whichq <= MAXPRI);
1822
1c79356b 1823 assert(thread->runq == RUN_QUEUE_NULL);
9bccf70c
A
1824 if (queue_empty(queue)) {
1825 enqueue_tail(queue, (queue_entry_t)thread);
1826
1827 setbit(MAXPRI - whichq, rq->bitmap);
55e303ae 1828 if (whichq > rq->highq) {
9bccf70c 1829 rq->highq = whichq;
55e303ae
A
1830 result = TRUE;
1831 }
9bccf70c
A
1832 }
1833 else
55e303ae 1834 if (options & SCHED_HEADQ)
9bccf70c 1835 enqueue_head(queue, (queue_entry_t)thread);
55e303ae
A
1836 else
1837 enqueue_tail(queue, (queue_entry_t)thread);
1c79356b 1838
1c79356b 1839 thread->runq = rq;
9bccf70c
A
1840 if (thread->sched_mode & TH_MODE_PREEMPT)
1841 rq->urgency++;
1842 rq->count++;
1c79356b 1843
9bccf70c 1844 return (result);
1c79356b
A
1845}
1846
1847/*
55e303ae
A
1848 * Enqueue a thread for realtime execution, similar
1849 * to above. Handles preemption directly.
1c79356b 1850 */
55e303ae
A
1851static void
1852realtime_schedule_insert(
1853 register processor_set_t pset,
1854 register thread_t thread)
1c79356b 1855{
55e303ae
A
1856 register run_queue_t rq = &pset->runq;
1857 register int whichq = thread->sched_pri;
1858 register queue_t queue = &rq->queues[whichq];
1859 uint64_t deadline = thread->realtime.deadline;
1860 boolean_t try_preempt = FALSE;
1c79356b 1861
55e303ae 1862 assert(whichq >= BASEPRI_REALTIME && whichq <= MAXPRI);
1c79356b 1863
55e303ae
A
1864 assert(thread->runq == RUN_QUEUE_NULL);
1865 if (queue_empty(queue)) {
1866 enqueue_tail(queue, (queue_entry_t)thread);
1867
1868 setbit(MAXPRI - whichq, rq->bitmap);
1869 if (whichq > rq->highq)
1870 rq->highq = whichq;
1871 try_preempt = TRUE;
1872 }
1873 else {
1874 register thread_t entry = (thread_t)queue_first(queue);
1875
1876 while (TRUE) {
1877 if ( queue_end(queue, (queue_entry_t)entry) ||
1878 deadline < entry->realtime.deadline ) {
1879 entry = (thread_t)queue_prev((queue_entry_t)entry);
1880 break;
1881 }
1882
1883 entry = (thread_t)queue_next((queue_entry_t)entry);
1884 }
1885
1886 if ((queue_entry_t)entry == queue)
1887 try_preempt = TRUE;
1888
1889 insque((queue_entry_t)thread, (queue_entry_t)entry);
1890 }
1891
1892 thread->runq = rq;
1893 assert(thread->sched_mode & TH_MODE_PREEMPT);
1894 rq->count++; rq->urgency++;
1895
1896 if (try_preempt) {
1897 register processor_t processor;
1898
1899 processor = current_processor();
1900 if ( pset == processor->processor_set &&
1901 (thread->sched_pri > processor->current_pri ||
1902 deadline < processor->deadline ) ) {
1903 dispatch_counts.realtime_self++;
1904 simple_unlock(&pset->sched_lock);
1905
1906 ast_on(AST_PREEMPT | AST_URGENT);
1907 return;
1908 }
1909
1910 if ( pset->processor_count > 1 ||
1911 pset != processor->processor_set ) {
1912 processor_t myprocessor, lastprocessor;
1913 queue_entry_t next;
1914
1915 myprocessor = processor;
1916 processor = thread->last_processor;
1917 if ( processor != myprocessor &&
1918 processor != PROCESSOR_NULL &&
1919 processor->processor_set == pset &&
1920 processor->state == PROCESSOR_RUNNING &&
1921 (thread->sched_pri > processor->current_pri ||
1922 deadline < processor->deadline ) ) {
1923 dispatch_counts.realtime_last++;
1924 cause_ast_check(processor);
1925 simple_unlock(&pset->sched_lock);
1926 return;
1927 }
1928
1929 lastprocessor = processor;
1930 queue = &pset->active_queue;
1931 processor = (processor_t)queue_first(queue);
1932 while (!queue_end(queue, (queue_entry_t)processor)) {
1933 next = queue_next((queue_entry_t)processor);
1934
1935 if ( processor != myprocessor &&
1936 processor != lastprocessor &&
1937 (thread->sched_pri > processor->current_pri ||
1938 deadline < processor->deadline ) ) {
1939 if (!queue_end(queue, next)) {
1940 remqueue(queue, (queue_entry_t)processor);
1941 enqueue_tail(queue, (queue_entry_t)processor);
1942 }
1943 dispatch_counts.realtime_other++;
1944 cause_ast_check(processor);
1945 simple_unlock(&pset->sched_lock);
1946 return;
1947 }
1948
1949 processor = (processor_t)next;
1950 }
1951 }
1952 }
1953
1954 simple_unlock(&pset->sched_lock);
1955}
1956
1957/*
1958 * thread_setrun:
1959 *
1960 * Dispatch thread for execution, directly onto an idle
1961 * processor if possible. Else put on appropriate run
1962 * queue. (local if bound, else processor set)
1963 *
1964 * Thread must be locked.
1965 */
1966void
1967thread_setrun(
1968 register thread_t new_thread,
1969 integer_t options)
1970{
1971 register processor_t processor;
1972 register processor_set_t pset;
1973 register thread_t thread;
1974 ast_t preempt = (options & SCHED_PREEMPT)?
1975 AST_PREEMPT: AST_NONE;
1976
1977 assert(thread_runnable(new_thread));
1978
1979 /*
1980 * Update priority if needed.
1981 */
1982 if (new_thread->sched_stamp != sched_tick)
1983 update_priority(new_thread);
1984
1985 /*
9bccf70c 1986 * Check for urgent preemption.
1c79356b 1987 */
9bccf70c 1988 if (new_thread->sched_mode & TH_MODE_PREEMPT)
55e303ae 1989 preempt = (AST_PREEMPT | AST_URGENT);
9bccf70c
A
1990
1991 assert(new_thread->runq == RUN_QUEUE_NULL);
1992
1c79356b
A
1993 if ((processor = new_thread->bound_processor) == PROCESSOR_NULL) {
1994 /*
9bccf70c
A
1995 * First try to dispatch on
1996 * the last processor.
1c79356b
A
1997 */
1998 pset = new_thread->processor_set;
9bccf70c
A
1999 processor = new_thread->last_processor;
2000 if ( pset->processor_count > 1 &&
2001 processor != PROCESSOR_NULL &&
2002 processor->state == PROCESSOR_IDLE ) {
55e303ae 2003 processor_lock(processor);
9bccf70c
A
2004 simple_lock(&pset->sched_lock);
2005 if ( processor->processor_set == pset &&
2006 processor->state == PROCESSOR_IDLE ) {
2007 remqueue(&pset->idle_queue, (queue_entry_t)processor);
1c79356b
A
2008 pset->idle_count--;
2009 processor->next_thread = new_thread;
55e303ae
A
2010 if (new_thread->sched_pri >= BASEPRI_RTQUEUES)
2011 processor->deadline = new_thread->realtime.deadline;
2012 else
2013 processor->deadline = UINT64_MAX;
1c79356b 2014 processor->state = PROCESSOR_DISPATCHING;
55e303ae 2015 dispatch_counts.idle_pset_last++;
9bccf70c 2016 simple_unlock(&pset->sched_lock);
55e303ae 2017 processor_unlock(processor);
9bccf70c 2018 if (processor != current_processor())
1c79356b 2019 machine_signal_idle(processor);
1c79356b
A
2020 return;
2021 }
55e303ae 2022 processor_unlock(processor);
9bccf70c
A
2023 }
2024 else
2025 simple_lock(&pset->sched_lock);
2026
2027 /*
2028 * Next pick any idle processor
2029 * in the processor set.
2030 */
2031 if (pset->idle_count > 0) {
2032 processor = (processor_t)dequeue_head(&pset->idle_queue);
2033 pset->idle_count--;
2034 processor->next_thread = new_thread;
55e303ae
A
2035 if (new_thread->sched_pri >= BASEPRI_RTQUEUES)
2036 processor->deadline = new_thread->realtime.deadline;
2037 else
2038 processor->deadline = UINT64_MAX;
9bccf70c 2039 processor->state = PROCESSOR_DISPATCHING;
55e303ae 2040 dispatch_counts.idle_pset_any++;
9bccf70c
A
2041 simple_unlock(&pset->sched_lock);
2042 if (processor != current_processor())
2043 machine_signal_idle(processor);
9bccf70c
A
2044 return;
2045 }
1c79356b 2046
55e303ae
A
2047 if (new_thread->sched_pri >= BASEPRI_RTQUEUES)
2048 realtime_schedule_insert(pset, new_thread);
2049 else {
2050 if (!run_queue_enqueue(&pset->runq, new_thread, options))
2051 preempt = AST_NONE;
9bccf70c 2052
9bccf70c 2053 /*
55e303ae 2054 * Update the timesharing quanta.
1c79356b 2055 */
55e303ae
A
2056 timeshare_quanta_update(pset);
2057
9bccf70c 2058 /*
55e303ae 2059 * Preempt check.
9bccf70c 2060 */
55e303ae 2061 if (preempt != AST_NONE) {
9bccf70c 2062 /*
55e303ae
A
2063 * First try the current processor
2064 * if it is a member of the correct
2065 * processor set.
9bccf70c 2066 */
55e303ae
A
2067 processor = current_processor();
2068 thread = processor->active_thread;
2069 if ( pset == processor->processor_set &&
2070 csw_needed(thread, processor) ) {
2071 dispatch_counts.pset_self++;
9bccf70c 2072 simple_unlock(&pset->sched_lock);
55e303ae
A
2073
2074 ast_on(preempt);
9bccf70c
A
2075 return;
2076 }
2077
2078 /*
55e303ae
A
2079 * If that failed and we have other
2080 * processors available keep trying.
9bccf70c 2081 */
55e303ae
A
2082 if ( pset->processor_count > 1 ||
2083 pset != processor->processor_set ) {
2084 queue_t queue = &pset->active_queue;
2085 processor_t myprocessor, lastprocessor;
2086 queue_entry_t next;
2087
2088 /*
2089 * Next try the last processor
2090 * dispatched on.
2091 */
2092 myprocessor = processor;
2093 processor = new_thread->last_processor;
9bccf70c 2094 if ( processor != myprocessor &&
55e303ae
A
2095 processor != PROCESSOR_NULL &&
2096 processor->processor_set == pset &&
2097 processor->state == PROCESSOR_RUNNING &&
9bccf70c 2098 new_thread->sched_pri > processor->current_pri ) {
55e303ae 2099 dispatch_counts.pset_last++;
9bccf70c
A
2100 cause_ast_check(processor);
2101 simple_unlock(&pset->sched_lock);
9bccf70c
A
2102 return;
2103 }
2104
55e303ae
A
2105 /*
2106 * Lastly, pick any other
2107 * available processor.
2108 */
2109 lastprocessor = processor;
2110 processor = (processor_t)queue_first(queue);
2111 while (!queue_end(queue, (queue_entry_t)processor)) {
2112 next = queue_next((queue_entry_t)processor);
2113
2114 if ( processor != myprocessor &&
2115 processor != lastprocessor &&
2116 new_thread->sched_pri >
2117 processor->current_pri ) {
2118 if (!queue_end(queue, next)) {
2119 remqueue(queue, (queue_entry_t)processor);
2120 enqueue_tail(queue, (queue_entry_t)processor);
2121 }
2122 dispatch_counts.pset_other++;
2123 cause_ast_check(processor);
2124 simple_unlock(&pset->sched_lock);
2125 return;
2126 }
2127
2128 processor = (processor_t)next;
2129 }
9bccf70c
A
2130 }
2131 }
9bccf70c 2132
55e303ae
A
2133 simple_unlock(&pset->sched_lock);
2134 }
1c79356b
A
2135 }
2136 else {
2137 /*
2138 * Bound, can only run on bound processor. Have to lock
2139 * processor here because it may not be the current one.
2140 */
55e303ae
A
2141 processor_lock(processor);
2142 pset = processor->processor_set;
2143 if (pset != PROCESSOR_SET_NULL) {
9bccf70c 2144 simple_lock(&pset->sched_lock);
1c79356b 2145 if (processor->state == PROCESSOR_IDLE) {
9bccf70c 2146 remqueue(&pset->idle_queue, (queue_entry_t)processor);
1c79356b
A
2147 pset->idle_count--;
2148 processor->next_thread = new_thread;
55e303ae 2149 processor->deadline = UINT64_MAX;
1c79356b 2150 processor->state = PROCESSOR_DISPATCHING;
55e303ae 2151 dispatch_counts.idle_bound++;
9bccf70c 2152 simple_unlock(&pset->sched_lock);
55e303ae 2153 processor_unlock(processor);
9bccf70c 2154 if (processor != current_processor())
1c79356b 2155 machine_signal_idle(processor);
1c79356b
A
2156 return;
2157 }
1c79356b
A
2158 }
2159
55e303ae
A
2160 if (!run_queue_enqueue(&processor->runq, new_thread, options))
2161 preempt = AST_NONE;
9bccf70c 2162
55e303ae
A
2163 if (preempt != AST_NONE) {
2164 if (processor == current_processor()) {
2165 thread = processor->active_thread;
9bccf70c 2166 if (csw_needed(thread, processor)) {
9bccf70c 2167 dispatch_counts.bound_self++;
55e303ae 2168 ast_on(preempt);
9bccf70c
A
2169 }
2170 }
55e303ae
A
2171 else
2172 if ( processor->state == PROCESSOR_RUNNING &&
2173 new_thread->sched_pri > processor->current_pri ) {
2174 dispatch_counts.bound_other++;
2175 cause_ast_check(processor);
9bccf70c
A
2176 }
2177 }
55e303ae
A
2178
2179 if (pset != PROCESSOR_SET_NULL)
2180 simple_unlock(&pset->sched_lock);
2181
2182 processor_unlock(processor);
9bccf70c
A
2183 }
2184}
2185
2186/*
55e303ae
A
2187 * Check for a possible preemption point in
2188 * the (current) thread.
2189 *
2190 * Called at splsched.
9bccf70c
A
2191 */
2192ast_t
2193csw_check(
2194 thread_t thread,
2195 processor_t processor)
2196{
2197 int current_pri = thread->sched_pri;
2198 ast_t result = AST_NONE;
2199 run_queue_t runq;
2200
55e303ae 2201 if (first_timeslice(processor)) {
9bccf70c 2202 runq = &processor->processor_set->runq;
55e303ae
A
2203 if (runq->highq >= BASEPRI_RTQUEUES)
2204 return (AST_PREEMPT | AST_URGENT);
2205
9bccf70c
A
2206 if (runq->highq > current_pri) {
2207 if (runq->urgency > 0)
55e303ae 2208 return (AST_PREEMPT | AST_URGENT);
9bccf70c 2209
55e303ae 2210 result |= AST_PREEMPT;
9bccf70c
A
2211 }
2212
2213 runq = &processor->runq;
2214 if (runq->highq > current_pri) {
2215 if (runq->urgency > 0)
55e303ae 2216 return (AST_PREEMPT | AST_URGENT);
9bccf70c 2217
55e303ae 2218 result |= AST_PREEMPT;
9bccf70c
A
2219 }
2220 }
2221 else {
2222 runq = &processor->processor_set->runq;
2223 if (runq->highq >= current_pri) {
2224 if (runq->urgency > 0)
55e303ae 2225 return (AST_PREEMPT | AST_URGENT);
9bccf70c 2226
55e303ae 2227 result |= AST_PREEMPT;
9bccf70c
A
2228 }
2229
2230 runq = &processor->runq;
2231 if (runq->highq >= current_pri) {
2232 if (runq->urgency > 0)
55e303ae 2233 return (AST_PREEMPT | AST_URGENT);
9bccf70c 2234
55e303ae 2235 result |= AST_PREEMPT;
9bccf70c 2236 }
1c79356b 2237 }
9bccf70c
A
2238
2239 if (result != AST_NONE)
2240 return (result);
2241
2242 if (thread->state & TH_SUSP)
55e303ae 2243 result |= AST_PREEMPT;
9bccf70c
A
2244
2245 return (result);
1c79356b
A
2246}
2247
2248/*
9bccf70c 2249 * set_sched_pri:
1c79356b 2250 *
55e303ae
A
2251 * Set the scheduled priority of the specified thread.
2252 *
9bccf70c 2253 * This may cause the thread to change queues.
1c79356b 2254 *
55e303ae 2255 * Thread must be locked.
1c79356b
A
2256 */
2257void
9bccf70c 2258set_sched_pri(
1c79356b 2259 thread_t thread,
9bccf70c 2260 int priority)
1c79356b 2261{
55e303ae 2262 register struct run_queue *rq = run_queue_remove(thread);
9bccf70c
A
2263
2264 if ( !(thread->sched_mode & TH_MODE_TIMESHARE) &&
2265 (priority >= BASEPRI_PREEMPT ||
2266 (thread->task_priority < MINPRI_KERNEL &&
2267 thread->task_priority >= BASEPRI_BACKGROUND &&
2268 priority > thread->task_priority) ||
2269 (thread->sched_mode & TH_MODE_FORCEDPREEMPT) ) )
2270 thread->sched_mode |= TH_MODE_PREEMPT;
2271 else
2272 thread->sched_mode &= ~TH_MODE_PREEMPT;
1c79356b 2273
9bccf70c
A
2274 thread->sched_pri = priority;
2275 if (rq != RUN_QUEUE_NULL)
55e303ae 2276 thread_setrun(thread, SCHED_PREEMPT | SCHED_TAILQ);
9bccf70c 2277 else
55e303ae 2278 if (thread->state & TH_RUN) {
9bccf70c
A
2279 processor_t processor = thread->last_processor;
2280
2281 if (thread == current_thread()) {
2282 ast_t preempt = csw_check(thread, processor);
2283
2284 if (preempt != AST_NONE)
2285 ast_on(preempt);
2286 processor->current_pri = priority;
2287 }
2288 else
2289 if ( processor != PROCESSOR_NULL &&
55e303ae 2290 processor->active_thread == thread )
9bccf70c 2291 cause_ast_check(processor);
1c79356b
A
2292 }
2293}
2294
2295/*
55e303ae 2296 * run_queue_remove:
1c79356b 2297 *
55e303ae
A
2298 * Remove a thread from its current run queue and
2299 * return the run queue if successful.
2300 *
2301 * Thread must be locked.
1c79356b
A
2302 */
2303run_queue_t
55e303ae 2304run_queue_remove(
1c79356b
A
2305 thread_t thread)
2306{
55e303ae 2307 register run_queue_t rq = thread->runq;
1c79356b 2308
1c79356b
A
2309 /*
2310 * If rq is RUN_QUEUE_NULL, the thread will stay out of the
55e303ae
A
2311 * run queues because the caller locked the thread. Otherwise
2312 * the thread is on a run queue, but could be chosen for dispatch
2313 * and removed.
1c79356b
A
2314 */
2315 if (rq != RUN_QUEUE_NULL) {
55e303ae
A
2316 processor_set_t pset = thread->processor_set;
2317 processor_t processor = thread->bound_processor;
2318
2319 /*
2320 * The run queues are locked by the pset scheduling
2321 * lock, except when a processor is off-line the
2322 * local run queue is locked by the processor lock.
2323 */
2324 if (processor != PROCESSOR_NULL) {
2325 processor_lock(processor);
2326 pset = processor->processor_set;
2327 }
2328
2329 if (pset != PROCESSOR_SET_NULL)
2330 simple_lock(&pset->sched_lock);
2331
1c79356b
A
2332 if (rq == thread->runq) {
2333 /*
55e303ae
A
2334 * Thread is on a run queue and we have a lock on
2335 * that run queue.
1c79356b 2336 */
1c79356b
A
2337 remqueue(&rq->queues[0], (queue_entry_t)thread);
2338 rq->count--;
9bccf70c
A
2339 if (thread->sched_mode & TH_MODE_PREEMPT)
2340 rq->urgency--;
2341 assert(rq->urgency >= 0);
1c79356b
A
2342
2343 if (queue_empty(rq->queues + thread->sched_pri)) {
2344 /* update run queue status */
2345 if (thread->sched_pri != IDLEPRI)
2346 clrbit(MAXPRI - thread->sched_pri, rq->bitmap);
2347 rq->highq = MAXPRI - ffsbit(rq->bitmap);
2348 }
55e303ae 2349
1c79356b 2350 thread->runq = RUN_QUEUE_NULL;
1c79356b
A
2351 }
2352 else {
2353 /*
55e303ae
A
2354 * The thread left the run queue before we could
2355 * lock the run queue.
1c79356b
A
2356 */
2357 assert(thread->runq == RUN_QUEUE_NULL);
1c79356b
A
2358 rq = RUN_QUEUE_NULL;
2359 }
55e303ae
A
2360
2361 if (pset != PROCESSOR_SET_NULL)
2362 simple_unlock(&pset->sched_lock);
2363
2364 if (processor != PROCESSOR_NULL)
2365 processor_unlock(processor);
1c79356b
A
2366 }
2367
2368 return (rq);
2369}
2370
1c79356b
A
2371/*
2372 * choose_thread:
2373 *
55e303ae
A
2374 * Remove a thread to execute from the run queues
2375 * and return it.
1c79356b 2376 *
55e303ae 2377 * Called with pset scheduling lock held.
1c79356b 2378 */
55e303ae 2379static thread_t
1c79356b 2380choose_thread(
55e303ae
A
2381 processor_set_t pset,
2382 processor_t processor)
1c79356b 2383{
1c79356b 2384 register run_queue_t runq;
55e303ae
A
2385 register thread_t thread;
2386 register queue_t q;
1c79356b 2387
55e303ae 2388 runq = &processor->runq;
1c79356b 2389
1c79356b
A
2390 if (runq->count > 0 && runq->highq >= pset->runq.highq) {
2391 q = runq->queues + runq->highq;
55e303ae
A
2392
2393 thread = (thread_t)q->next;
2394 ((queue_entry_t)thread)->next->prev = q;
2395 q->next = ((queue_entry_t)thread)->next;
2396 thread->runq = RUN_QUEUE_NULL;
2397 runq->count--;
2398 if (thread->sched_mode & TH_MODE_PREEMPT)
2399 runq->urgency--;
2400 assert(runq->urgency >= 0);
2401 if (queue_empty(q)) {
2402 if (runq->highq != IDLEPRI)
2403 clrbit(MAXPRI - runq->highq, runq->bitmap);
2404 runq->highq = MAXPRI - ffsbit(runq->bitmap);
1c79356b 2405 }
1c79356b 2406
55e303ae 2407 processor->deadline = UINT64_MAX;
1c79356b 2408
55e303ae 2409 return (thread);
1c79356b 2410 }
1c79356b 2411
55e303ae 2412 runq = &pset->runq;
9bccf70c 2413
55e303ae
A
2414 assert(runq->count > 0);
2415 q = runq->queues + runq->highq;
1c79356b 2416
55e303ae
A
2417 thread = (thread_t)q->next;
2418 ((queue_entry_t)thread)->next->prev = q;
2419 q->next = ((queue_entry_t)thread)->next;
2420 thread->runq = RUN_QUEUE_NULL;
2421 runq->count--;
2422 if (runq->highq >= BASEPRI_RTQUEUES)
2423 processor->deadline = thread->realtime.deadline;
2424 else
2425 processor->deadline = UINT64_MAX;
2426 if (thread->sched_mode & TH_MODE_PREEMPT)
2427 runq->urgency--;
2428 assert(runq->urgency >= 0);
2429 if (queue_empty(q)) {
2430 if (runq->highq != IDLEPRI)
2431 clrbit(MAXPRI - runq->highq, runq->bitmap);
2432 runq->highq = MAXPRI - ffsbit(runq->bitmap);
1c79356b 2433 }
1c79356b 2434
55e303ae
A
2435 timeshare_quanta_update(pset);
2436
2437 return (thread);
1c79356b
A
2438}
2439
2440/*
2441 * no_dispatch_count counts number of times processors go non-idle
2442 * without being dispatched. This should be very rare.
2443 */
2444int no_dispatch_count = 0;
2445
2446/*
2447 * This is the idle thread, which just looks for other threads
2448 * to execute.
2449 */
2450void
2451idle_thread_continue(void)
2452{
55e303ae 2453 register processor_t processor;
1c79356b
A
2454 register volatile thread_t *threadp;
2455 register volatile int *gcount;
2456 register volatile int *lcount;
2457 register thread_t new_thread;
2458 register int state;
2459 register processor_set_t pset;
2460 int mycpu;
2461
2462 mycpu = cpu_number();
55e303ae
A
2463 processor = cpu_to_processor(mycpu);
2464 threadp = (volatile thread_t *) &processor->next_thread;
2465 lcount = (volatile int *) &processor->runq.count;
1c79356b 2466
55e303ae 2467 gcount = (volatile int *)&processor->processor_set->runq.count;
1c79356b 2468
55e303ae
A
2469 (void)splsched();
2470 while ( (*threadp == (volatile thread_t)THREAD_NULL) &&
2471 (*gcount == 0) && (*lcount == 0) ) {
de355530 2472
55e303ae
A
2473 /* check for ASTs while we wait */
2474 if (need_ast[mycpu] &~ ( AST_SCHEDULING | AST_BSD )) {
2475 /* no ASTs for us */
2476 need_ast[mycpu] &= AST_NONE;
2477 (void)spllo();
1c79356b 2478 }
55e303ae
A
2479 else
2480 machine_idle();
2481
2482 (void)splsched();
2483 }
2484
2485 /*
2486 * This is not a switch statement to avoid the
2487 * bounds checking code in the common case.
2488 */
2489 pset = processor->processor_set;
2490 simple_lock(&pset->sched_lock);
1c79356b 2491
55e303ae
A
2492 state = processor->state;
2493 if (state == PROCESSOR_DISPATCHING) {
1c79356b 2494 /*
55e303ae 2495 * Commmon case -- cpu dispatched.
1c79356b 2496 */
55e303ae
A
2497 new_thread = *threadp;
2498 *threadp = (volatile thread_t) THREAD_NULL;
2499 processor->state = PROCESSOR_RUNNING;
2500 enqueue_tail(&pset->active_queue, (queue_entry_t)processor);
2501
2502 if ( pset->runq.highq >= BASEPRI_RTQUEUES &&
2503 new_thread->sched_pri >= BASEPRI_RTQUEUES ) {
2504 register run_queue_t runq = &pset->runq;
2505 register queue_t q;
2506
2507 q = runq->queues + runq->highq;
2508 if (((thread_t)q->next)->realtime.deadline <
2509 processor->deadline) {
2510 thread_t thread = new_thread;
2511
2512 new_thread = (thread_t)q->next;
2513 ((queue_entry_t)new_thread)->next->prev = q;
2514 q->next = ((queue_entry_t)new_thread)->next;
2515 new_thread->runq = RUN_QUEUE_NULL;
2516 processor->deadline = new_thread->realtime.deadline;
2517 assert(new_thread->sched_mode & TH_MODE_PREEMPT);
2518 runq->count--; runq->urgency--;
2519 if (queue_empty(q)) {
2520 if (runq->highq != IDLEPRI)
2521 clrbit(MAXPRI - runq->highq, runq->bitmap);
2522 runq->highq = MAXPRI - ffsbit(runq->bitmap);
2523 }
2524 dispatch_counts.missed_realtime++;
2525 simple_unlock(&pset->sched_lock);
1c79356b 2526
55e303ae
A
2527 thread_lock(thread);
2528 thread_setrun(thread, SCHED_HEADQ);
2529 thread_unlock(thread);
1c79356b 2530
1c79356b 2531 counter(c_idle_thread_handoff++);
55e303ae 2532 thread_run(processor->idle_thread,
1c79356b 2533 idle_thread_continue, new_thread);
55e303ae 2534 /*NOTREACHED*/
1c79356b 2535 }
9bccf70c 2536 simple_unlock(&pset->sched_lock);
1c79356b 2537
55e303ae
A
2538 counter(c_idle_thread_handoff++);
2539 thread_run(processor->idle_thread,
2540 idle_thread_continue, new_thread);
2541 /*NOTREACHED*/
1c79356b 2542 }
9bccf70c 2543
55e303ae
A
2544 if ( processor->runq.highq > new_thread->sched_pri ||
2545 pset->runq.highq > new_thread->sched_pri ) {
2546 thread_t thread = new_thread;
2547
2548 new_thread = choose_thread(pset, processor);
2549 dispatch_counts.missed_other++;
2550 simple_unlock(&pset->sched_lock);
1c79356b 2551
55e303ae
A
2552 thread_lock(thread);
2553 thread_setrun(thread, SCHED_HEADQ);
2554 thread_unlock(thread);
2555
2556 counter(c_idle_thread_handoff++);
2557 thread_run(processor->idle_thread,
2558 idle_thread_continue, new_thread);
9bccf70c 2559 /* NOTREACHED */
1c79356b
A
2560 }
2561 else {
9bccf70c 2562 simple_unlock(&pset->sched_lock);
1c79356b 2563
55e303ae
A
2564 counter(c_idle_thread_handoff++);
2565 thread_run(processor->idle_thread,
2566 idle_thread_continue, new_thread);
2567 /* NOTREACHED */
1c79356b 2568 }
55e303ae
A
2569 }
2570 else
2571 if (state == PROCESSOR_IDLE) {
2572 /*
2573 * Processor was not dispatched (Rare).
2574 * Set it running again and force a
2575 * reschedule.
2576 */
2577 no_dispatch_count++;
2578 pset->idle_count--;
2579 remqueue(&pset->idle_queue, (queue_entry_t)processor);
2580 processor->state = PROCESSOR_RUNNING;
2581 enqueue_tail(&pset->active_queue, (queue_entry_t)processor);
2582 simple_unlock(&pset->sched_lock);
1c79356b 2583
55e303ae
A
2584 counter(c_idle_thread_block++);
2585 thread_block(idle_thread_continue);
2586 /* NOTREACHED */
1c79356b 2587 }
55e303ae
A
2588 else
2589 if (state == PROCESSOR_SHUTDOWN) {
2590 /*
2591 * Going off-line. Force a
2592 * reschedule.
2593 */
2594 if ((new_thread = (thread_t)*threadp) != THREAD_NULL) {
2595 *threadp = (volatile thread_t) THREAD_NULL;
2596 processor->deadline = UINT64_MAX;
2597 simple_unlock(&pset->sched_lock);
2598
2599 thread_lock(new_thread);
2600 thread_setrun(new_thread, SCHED_HEADQ);
2601 thread_unlock(new_thread);
2602 }
2603 else
2604 simple_unlock(&pset->sched_lock);
2605
2606 counter(c_idle_thread_block++);
2607 thread_block(idle_thread_continue);
2608 /* NOTREACHED */
2609 }
2610
2611 simple_unlock(&pset->sched_lock);
2612
2613 panic("idle_thread: state %d\n", cpu_state(mycpu));
2614 /*NOTREACHED*/
1c79356b
A
2615}
2616
2617void
2618idle_thread(void)
2619{
1c79356b 2620 counter(c_idle_thread_block++);
9bccf70c 2621 thread_block(idle_thread_continue);
1c79356b
A
2622 /*NOTREACHED*/
2623}
2624
55e303ae 2625static uint64_t sched_tick_deadline;
0b4e3aa0
A
2626
2627void sched_tick_thread(void);
2628
2629void
2630sched_tick_init(void)
2631{
55e303ae 2632 kernel_thread_with_priority(sched_tick_thread, MAXPRI_STANDARD);
0b4e3aa0 2633}
1c79356b
A
2634
2635/*
2636 * sched_tick_thread
2637 *
55e303ae
A
2638 * Perform periodic bookkeeping functions about ten
2639 * times per second.
1c79356b
A
2640 */
2641void
2642sched_tick_thread_continue(void)
2643{
0b4e3aa0 2644 uint64_t abstime;
1c79356b
A
2645#if SIMPLE_CLOCK
2646 int new_usec;
2647#endif /* SIMPLE_CLOCK */
2648
55e303ae 2649 abstime = mach_absolute_time();
1c79356b
A
2650
2651 sched_tick++; /* age usage one more time */
2652#if SIMPLE_CLOCK
2653 /*
2654 * Compensate for clock drift. sched_usec is an
2655 * exponential average of the number of microseconds in
2656 * a second. It decays in the same fashion as cpu_usage.
2657 */
2658 new_usec = sched_usec_elapsed();
2659 sched_usec = (5*sched_usec + 3*new_usec)/8;
2660#endif /* SIMPLE_CLOCK */
2661
2662 /*
2663 * Compute the scheduler load factors.
2664 */
2665 compute_mach_factor();
2666
2667 /*
55e303ae
A
2668 * Scan the run queues for timesharing threads which
2669 * may need to have their priorities recalculated.
1c79356b
A
2670 */
2671 do_thread_scan();
2672
2673 clock_deadline_for_periodic_event(sched_tick_interval, abstime,
2674 &sched_tick_deadline);
2675
2676 assert_wait((event_t)sched_tick_thread_continue, THREAD_INTERRUPTIBLE);
2677 thread_set_timer_deadline(sched_tick_deadline);
2678 thread_block(sched_tick_thread_continue);
2679 /*NOTREACHED*/
2680}
2681
2682void
2683sched_tick_thread(void)
2684{
55e303ae 2685 sched_tick_deadline = mach_absolute_time();
1c79356b
A
2686
2687 thread_block(sched_tick_thread_continue);
2688 /*NOTREACHED*/
2689}
2690
1c79356b 2691/*
55e303ae
A
2692 * do_thread_scan:
2693 *
2694 * Scan the run queues for timesharing threads which need
2695 * to be aged, possibily adjusting their priorities upwards.
1c79356b
A
2696 *
2697 * Scanner runs in two passes. Pass one squirrels likely
55e303ae 2698 * thread away in an array (takes out references for them).
1c79356b
A
2699 * Pass two does the priority updates. This is necessary because
2700 * the run queue lock is required for the candidate scan, but
9bccf70c 2701 * cannot be held during updates.
1c79356b
A
2702 *
2703 * Array length should be enough so that restart isn't necessary,
9bccf70c 2704 * but restart logic is included.
1c79356b
A
2705 *
2706 */
55e303ae
A
2707
2708#define MAX_STUCK_THREADS 128
2709
2710static thread_t stuck_threads[MAX_STUCK_THREADS];
2711static int stuck_count = 0;
1c79356b
A
2712
2713/*
2714 * do_runq_scan is the guts of pass 1. It scans a runq for
2715 * stuck threads. A boolean is returned indicating whether
2716 * a retry is needed.
2717 */
55e303ae 2718static boolean_t
1c79356b
A
2719do_runq_scan(
2720 run_queue_t runq)
2721{
2722 register queue_t q;
2723 register thread_t thread;
2724 register int count;
1c79356b
A
2725 boolean_t result = FALSE;
2726
1c79356b
A
2727 if ((count = runq->count) > 0) {
2728 q = runq->queues + runq->highq;
2729 while (count > 0) {
2730 queue_iterate(q, thread, thread_t, links) {
55e303ae 2731 if ( thread->sched_stamp != sched_tick &&
0b4e3aa0 2732 (thread->sched_mode & TH_MODE_TIMESHARE) ) {
55e303ae
A
2733 /*
2734 * Stuck, save its id for later.
2735 */
2736 if (stuck_count == MAX_STUCK_THREADS) {
1c79356b 2737 /*
55e303ae 2738 * !@#$% No more room.
1c79356b 2739 */
55e303ae
A
2740 return (TRUE);
2741 }
1c79356b 2742
55e303ae
A
2743 if (thread_lock_try(thread)) {
2744 thread->ref_count++;
2745 thread_unlock(thread);
2746 stuck_threads[stuck_count++] = thread;
1c79356b 2747 }
55e303ae
A
2748 else
2749 result = TRUE;
1c79356b
A
2750 }
2751
2752 count--;
2753 }
2754
2755 q--;
2756 }
2757 }
1c79356b
A
2758
2759 return (result);
2760}
2761
2762boolean_t thread_scan_enabled = TRUE;
2763
55e303ae 2764static void
1c79356b
A
2765do_thread_scan(void)
2766{
2767 register boolean_t restart_needed = FALSE;
2768 register thread_t thread;
2769 register processor_set_t pset = &default_pset;
2770 register processor_t processor;
2771 spl_t s;
2772
2773 if (!thread_scan_enabled)
2774 return;
2775
2776 do {
55e303ae
A
2777 s = splsched();
2778 simple_lock(&pset->sched_lock);
1c79356b 2779 restart_needed = do_runq_scan(&pset->runq);
55e303ae
A
2780 simple_unlock(&pset->sched_lock);
2781
1c79356b 2782 if (!restart_needed) {
55e303ae 2783 simple_lock(&pset->sched_lock);
1c79356b
A
2784 processor = (processor_t)queue_first(&pset->processors);
2785 while (!queue_end(&pset->processors, (queue_entry_t)processor)) {
2786 if (restart_needed = do_runq_scan(&processor->runq))
2787 break;
2788
0b4e3aa0
A
2789 thread = processor->idle_thread;
2790 if (thread->sched_stamp != sched_tick) {
2791 if (stuck_count == MAX_STUCK_THREADS) {
2792 restart_needed = TRUE;
2793 break;
2794 }
2795
2796 stuck_threads[stuck_count++] = thread;
2797 }
2798
1c79356b
A
2799 processor = (processor_t)queue_next(&processor->processors);
2800 }
55e303ae 2801 simple_unlock(&pset->sched_lock);
1c79356b 2802 }
55e303ae 2803 splx(s);
1c79356b
A
2804
2805 /*
2806 * Ok, we now have a collection of candidates -- fix them.
2807 */
2808 while (stuck_count > 0) {
55e303ae
A
2809 boolean_t idle_thread;
2810
1c79356b
A
2811 thread = stuck_threads[--stuck_count];
2812 stuck_threads[stuck_count] = THREAD_NULL;
55e303ae 2813
1c79356b
A
2814 s = splsched();
2815 thread_lock(thread);
55e303ae
A
2816 idle_thread = (thread->state & TH_IDLE) != 0;
2817 if ( !(thread->state & (TH_WAIT|TH_SUSP)) &&
2818 thread->sched_stamp != sched_tick )
2819 update_priority(thread);
1c79356b
A
2820 thread_unlock(thread);
2821 splx(s);
55e303ae
A
2822
2823 if (!idle_thread)
0b4e3aa0 2824 thread_deallocate(thread);
1c79356b 2825 }
9bccf70c
A
2826
2827 if (restart_needed)
2828 delay(1); /* XXX */
1c79356b
A
2829
2830 } while (restart_needed);
2831}
2832
2833/*
2834 * Just in case someone doesn't use the macro
2835 */
2836#undef thread_wakeup
2837void
2838thread_wakeup(
2839 event_t x);
2840
2841void
2842thread_wakeup(
2843 event_t x)
2844{
2845 thread_wakeup_with_result(x, THREAD_AWAKENED);
2846}
2847
9bccf70c 2848
0b4e3aa0 2849#if DEBUG
0b4e3aa0 2850static boolean_t
1c79356b 2851thread_runnable(
0b4e3aa0 2852 thread_t thread)
1c79356b 2853{
0b4e3aa0 2854 return ((thread->state & (TH_RUN|TH_WAIT)) == TH_RUN);
1c79356b 2855}
1c79356b
A
2856#endif /* DEBUG */
2857
2858#if MACH_KDB
2859#include <ddb/db_output.h>
2860#define printf kdbprintf
2861extern int db_indent;
2862void db_sched(void);
2863
2864void
2865db_sched(void)
2866{
2867 iprintf("Scheduling Statistics:\n");
2868 db_indent += 2;
2869 iprintf("Thread invocations: csw %d same %d\n",
2870 c_thread_invoke_csw, c_thread_invoke_same);
2871#if MACH_COUNTERS
2872 iprintf("Thread block: calls %d\n",
2873 c_thread_block_calls);
2874 iprintf("Idle thread:\n\thandoff %d block %d no_dispatch %d\n",
2875 c_idle_thread_handoff,
2876 c_idle_thread_block, no_dispatch_count);
2877 iprintf("Sched thread blocks: %d\n", c_sched_thread_block);
2878#endif /* MACH_COUNTERS */
2879 db_indent -= 2;
2880}
55e303ae
A
2881
2882#include <ddb/db_output.h>
2883void db_show_thread_log(void);
2884
2885void
2886db_show_thread_log(void)
2887{
2888}
1c79356b 2889#endif /* MACH_KDB */