37 #include <sys/cdefs.h>
40 #include "opt_kdtrace.h"
41 #include "opt_ktrace.h"
42 #include "opt_sched.h"
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/condvar.h>
48 #include <sys/kernel.h>
51 #include <sys/mutex.h>
53 #include <sys/resourcevar.h>
54 #include <sys/sched.h>
56 #include <sys/signalvar.h>
57 #include <sys/sleepqueue.h>
60 #include <sys/sysctl.h>
61 #include <sys/sysproto.h>
62 #include <sys/vmmeter.h>
65 #include <sys/ktrace.h>
68 #include <machine/cpu.h>
72 #include <vm/vm_param.h>
76 #define KTDSTATE(td) \
77 (((td)->td_inhibitors & TDI_SLEEPING) != 0 ? "sleep" : \
78 ((td)->td_inhibitors & TDI_SUSPENDED) != 0 ? "suspended" : \
79 ((td)->td_inhibitors & TDI_SWAPPED) != 0 ? "swapped" : \
80 ((td)->td_inhibitors & TDI_LOCK) != 0 ? "blocked" : \
81 ((td)->td_inhibitors & TDI_IWAIT) != 0 ? "iwait" : "yielding")
93 { {0, 0, 0}, FSCALE };
99 0.9200444146293232 * FSCALE,
100 0.9834714538216174 * FSCALE,
101 0.9944598480048967 * FSCALE,
105 SYSCTL_INT(_kern, OID_AUTO, fscale, CTLFLAG_RD, SYSCTL_NULL_INT_PTR, FSCALE,
"");
107 static void loadav(
void *arg);
148 const char *wmesg,
int timo)
152 struct lock_class *
class;
153 int catch, flags, lock_state, pri, rval;
154 WITNESS_SAVE_DECL(lock_witness);
159 if (KTRPOINT(td, KTR_CSW))
162 WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, lock,
163 "Sleeping on \"%s\"", wmesg);
164 KASSERT(timo != 0 || mtx_owned(&
Giant) || lock != NULL,
165 (
"sleeping without a lock"));
166 KASSERT(p != NULL, (
"msleep1"));
167 KASSERT(ident != NULL && TD_IS_RUNNING(td), (
"msleep"));
168 if (priority & PDROP)
169 KASSERT(lock != NULL && lock != &
Giant.lock_object,
170 (
"PDROP requires a non-Giant lock"));
172 class = LOCK_CLASS(lock);
176 if (cold || SCHEDULER_STOPPED()) {
185 if (lock != NULL && priority & PDROP)
186 class->lc_unlock(lock);
189 catch = priority & PCATCH;
190 pri = priority & PRIMASK;
197 if (TD_ON_SLEEPQ(td))
201 flags = SLEEPQ_PAUSE;
203 flags = SLEEPQ_SLEEP;
205 flags |= SLEEPQ_INTERRUPTIBLE;
206 if (priority & PBDRY)
207 flags |= SLEEPQ_STOP_ON_BDRY;
210 CTR5(KTR_PROC,
"sleep: thread %ld (pid %ld, %s) on %s (%p)",
211 td->td_tid, p->p_pid, td->td_name, wmesg, ident);
213 if (lock == &
Giant.lock_object)
214 mtx_assert(&
Giant, MA_OWNED);
216 if (lock != NULL && lock != &
Giant.lock_object &&
217 !(class->lc_flags & LC_SLEEPABLE)) {
218 WITNESS_SAVE(lock, lock_witness);
219 lock_state =
class->lc_unlock(lock);
236 if (lock != NULL && class->lc_flags & LC_SLEEPABLE) {
238 WITNESS_SAVE(lock, lock_witness);
239 lock_state =
class->lc_unlock(lock);
253 if (KTRPOINT(td, KTR_CSW))
257 if (lock != NULL && lock != &
Giant.lock_object && !(priority & PDROP)) {
258 class->lc_lock(lock, lock_state);
259 WITNESS_RESTORE(lock, lock_witness);
265 msleep_spin(
void *ident,
struct mtx *mtx,
const char *wmesg,
int timo)
270 WITNESS_SAVE_DECL(mtx);
274 KASSERT(mtx != NULL, (
"sleeping without a mutex"));
275 KASSERT(p != NULL, (
"msleep1"));
276 KASSERT(ident != NULL && TD_IS_RUNNING(td), (
"msleep"));
278 if (cold || SCHEDULER_STOPPED()) {
291 CTR5(KTR_PROC,
"msleep_spin: thread %ld (pid %ld, %s) on %s (%p)",
292 td->td_tid, p->p_pid, td->td_name, wmesg, ident);
295 mtx_assert(mtx, MA_OWNED | MA_NOTRECURSED);
296 WITNESS_SAVE(&mtx->lock_object, mtx);
297 mtx_unlock_spin(mtx);
302 sleepq_add(ident, &mtx->lock_object, wmesg, SLEEPQ_SLEEP, 0);
314 if (KTRPOINT(td, KTR_CSW)) {
322 WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL,
"Sleeping on \"%s\"",
333 if (KTRPOINT(td, KTR_CSW))
338 WITNESS_RESTORE(&mtx->lock_object, mtx);
352 KASSERT(timo >= 0, (
"pause: timo must be >= 0"));
385 if (wakeup_swapper) {
386 KASSERT(ident != &
proc0,
387 (
"wakeup and wakeup_swapper and proc0"));
412 thread_unlock(curthread);
415 panic(
"%s: did not reenter debugger", __func__);
424 uint64_t runtime, new_switchtime;
429 THREAD_LOCK_ASSERT(td, MA_OWNED | MA_NOTRECURSED);
431 KASSERT(!TD_ON_RUNQ(td), (
"mi_switch: called by old code"));
433 if (!TD_ON_LOCK(td) && !TD_IS_RUNNING(td))
434 mtx_assert(&
Giant, MA_NOTOWNED);
436 KASSERT(td->td_critnest == 1 ||
panicstr,
437 (
"mi_switch: switch in a critical section"));
438 KASSERT((flags & (SW_INVOL | SW_VOL)) != 0,
439 (
"mi_switch: switch must be voluntary or involuntary"));
440 KASSERT(newtd != curthread, (
"mi_switch: preempting back to ourself"));
447 if (SCHEDULER_STOPPED())
449 if (flags & SW_VOL) {
450 td->td_ru.ru_nvcsw++;
451 td->td_swvoltick =
ticks;
453 td->td_ru.ru_nivcsw++;
455 SCHED_STAT_INC(sched_switch_stats[flags & SW_TYPE_MASK]);
462 runtime = new_switchtime - PCPU_GET(switchtime);
463 td->td_runtime += runtime;
464 td->td_incruntime += runtime;
465 PCPU_SET(switchtime, new_switchtime);
467 PCPU_INC(cnt.v_swtch);
468 PCPU_SET(switchticks,
ticks);
469 CTR4(KTR_PROC,
"mi_switch: old thread %ld (td_sched %p, pid %ld, %s)",
470 td->td_tid, td->td_sched, p->p_pid, td->td_name);
471 #if (KTR_COMPILE & KTR_SCHED) != 0
472 if (TD_IS_IDLETHREAD(td))
473 KTR_STATE1(KTR_SCHED,
"thread",
sched_tdname(td),
"idle",
474 "prio:%d", td->td_priority);
477 "prio:%d", td->td_priority,
"wmesg:\"%s\"", td->td_wmesg,
478 "lockname:\"%s\"", td->td_lockname);
480 SDT_PROBE0(sched, , , preempt);
485 KTR_STATE1(KTR_SCHED,
"thread",
sched_tdname(td),
"running",
486 "prio:%d", td->td_priority);
488 CTR4(KTR_PROC,
"mi_switch: new thread %ld (td_sched %p, pid %ld, %s)",
489 td->td_tid, td->td_sched, p->p_pid, td->td_name);
494 if ((td = PCPU_GET(deadthread))) {
495 PCPU_SET(deadthread, NULL);
509 THREAD_LOCK_ASSERT(td, MA_OWNED);
510 KASSERT(td->td_proc->p_state != PRS_ZOMBIE,
511 (
"setrunnable: pid %d is a zombie", td->td_proc->p_pid));
512 switch (td->td_state) {
521 if (td->td_inhibitors != TDI_SWAPPED)
527 printf(
"state is 0x%x", td->td_state);
528 panic(
"setrunnable(2)");
530 if ((td->td_flags & TDF_INMEM) == 0) {
531 if ((td->td_flags & TDF_SWAPINREQ) == 0) {
532 td->td_flags |= TDF_SWAPINREQ;
553 for (i = 0; i < 3; i++)
554 avg->ldavg[i] = (
cexp[i] * avg->ldavg[i] +
555 nrun * FSCALE * (FSCALE -
cexp[i])) >> FSHIFT;
580 return ((u_int)
ticks - (u_int)curthread->td_swvoltick >=
hogticks);
599 if (prio == PRI_USER)
600 prio = td->td_user_pri;
603 mi_switch(SW_VOL | SWT_RELINQUISH, NULL);
616 if (PRI_BASE(td->td_pri_class) == PRI_TIMESHARE)
618 mi_switch(SW_VOL | SWT_RELINQUISH, NULL);
620 td->td_retval[0] = 0;
void sleepq_release(void *wchan)
void sleepq_add(void *wchan, struct lock_object *lock, const char *wmesg, int flags, int queue)
void sched_prio(struct thread *td, u_char prio)
void sched_switch(struct thread *td, struct thread *newtd, int flags)
char * sched_tdname(struct thread *td)
int sleepq_timedwait_sig(void *wchan, int pri)
void panic(const char *fmt,...)
static struct callout loadav_callout
void mi_switch(int flags, struct thread *newtd)
void sleepq_remove(struct thread *td, void *wchan)
void sleepq_set_timeout(void *wchan, int timo)
int sleepq_wait_sig(void *wchan, int pri)
void wakeup_one(void *ident)
void sleepq_lock(void *wchan)
SYSCTL_INT(_kern, OID_AUTO, fscale, CTLFLAG_RD, SYSCTL_NULL_INT_PTR, FSCALE,"")
struct loadavg averunnable
void sleepq_wait(void *wchan, int pri)
int setrunnable(struct thread *td)
SDT_PROVIDER_DECLARE(sched)
int sleepq_broadcast(void *wchan, int flags, int pri, int queue)
static void kdb_switch(void)
void sched_wakeup(struct thread *td)
int _sleep(void *ident, struct lock_object *lock, int priority, const char *wmesg, int timo)
int sleepq_signal(void *wchan, int flags, int pri, int queue)
int msleep_spin(void *ident, struct mtx *mtx, const char *wmesg, int timo)
int pause(const char *wmesg, int timo)
int printf(const char *fmt,...)
SYSINIT(synch_setup, SI_SUB_KICK_SCHEDULER, SI_ORDER_FIRST, synch_setup, NULL)
void kern_yield(int prio)
void callout_init(struct callout *c, int mpsafe)
static void loadav(void *arg)
void init_sleepqueues(void)
void thread_stash(struct thread *td)
int sys_yield(struct thread *td, struct yield_args *uap)
SDT_PROBE_DEFINE(sched,,, preempt)
static void synch_setup(void *dummy)
int sleepq_timedwait(void *wchan, int pri)