kern_idle.c revision 99072
165557Sjasone/*-
265557Sjasone * Copyright (c) 2000, All rights reserved.  See /usr/src/COPYRIGHT
365557Sjasone *
465557Sjasone * $FreeBSD: head/sys/kern/kern_idle.c 99072 2002-06-29 17:26:22Z julian $
565557Sjasone */
665557Sjasone
765557Sjasone#include "opt_ktrace.h"
865557Sjasone
965557Sjasone#include <sys/param.h>
1065557Sjasone#include <sys/systm.h>
1165557Sjasone#include <sys/kernel.h>
1265557Sjasone#include <sys/ktr.h>
1376440Sjhb#include <sys/kthread.h>
1476166Smarkm#include <sys/lock.h>
1576166Smarkm#include <sys/mutex.h>
1676440Sjhb#include <sys/pcpu.h>
1776166Smarkm#include <sys/proc.h>
1876440Sjhb#include <sys/resourcevar.h>
1976078Sjhb#include <sys/smp.h>
2065557Sjasone#include <sys/unistd.h>
2165557Sjasone#ifdef KTRACE
2265557Sjasone#include <sys/uio.h>
2365557Sjasone#include <sys/ktrace.h>
2465557Sjasone#endif
2565557Sjasone
2665557Sjasonestatic void idle_setup(void *dummy);
2765557SjasoneSYSINIT(idle_setup, SI_SUB_SCHED_IDLE, SI_ORDER_FIRST, idle_setup, NULL)
2865557Sjasone
2965557Sjasonestatic void idle_proc(void *dummy);
3065557Sjasone
3165557Sjasone/*
3272222Sjhb * Setup per-cpu idle process contexts.  The AP's shouldn't be running or
3372222Sjhb * accessing their idle processes at this point, so don't bother with
3472222Sjhb * locking.
3565557Sjasone */
3665557Sjasonestatic void
3765557Sjasoneidle_setup(void *dummy)
3865557Sjasone{
3976078Sjhb#ifdef SMP
4087702Sjhb	struct pcpu *pc;
4176078Sjhb#endif
4276078Sjhb	struct proc *p;
4399072Sjulian	struct thread *td;
4465557Sjasone	int error;
4565557Sjasone
4676078Sjhb#ifdef SMP
4787702Sjhb	SLIST_FOREACH(pc, &cpuhead, pc_allcpu) {
4876078Sjhb		error = kthread_create(idle_proc, NULL, &p,
4987702Sjhb		    RFSTOPPED | RFHIGHPID, "idle: cpu%d", pc->pc_cpuid);
5090361Sjulian		pc->pc_idlethread = FIRST_THREAD_IN_PROC(p);
5188088Sjhb		if (pc->pc_curthread == NULL) {
5287702Sjhb			pc->pc_curthread = pc->pc_idlethread;
5388088Sjhb			pc->pc_idlethread->td_critnest = 0;
5488088Sjhb		}
5565557Sjasone#else
5676078Sjhb		error = kthread_create(idle_proc, NULL, &p,
5776078Sjhb		    RFSTOPPED | RFHIGHPID, "idle");
5890361Sjulian		PCPU_SET(idlethread, FIRST_THREAD_IN_PROC(p));
5965557Sjasone#endif
6065557Sjasone		if (error)
6165557Sjasone			panic("idle_setup: kthread_create error %d\n", error);
6265557Sjasone
6376078Sjhb		p->p_flag |= P_NOLOAD;
6499072Sjulian		td = FIRST_THREAD_IN_PROC(p);
6599072Sjulian		td->td_state = TDS_RUNQ;
6699072Sjulian		td->td_kse->ke_state = KES_ONRUNQ;
6799072Sjulian		td->td_kse->ke_flags |= KEF_IDLEKSE;
6876078Sjhb#ifdef SMP
6965557Sjasone	}
7076078Sjhb#endif
7165557Sjasone}
7265557Sjasone
7365557Sjasone/*
7465557Sjasone * idle process context
7565557Sjasone */
7665557Sjasonestatic void
7765557Sjasoneidle_proc(void *dummy)
7865557Sjasone{
7967266Sjhb#ifdef DIAGNOSTIC
8065557Sjasone	int count;
8167266Sjhb#endif
8299072Sjulian	struct thread *td;
8399072Sjulian	struct proc *p;
8465557Sjasone
8599072Sjulian	td = curthread;
8699072Sjulian	p = td->td_proc;
8799072Sjulian	td->td_state = TDS_RUNNING;
8899072Sjulian	td->td_kse->ke_state = KES_RUNNING;
8965557Sjasone	for (;;) {
9065557Sjasone		mtx_assert(&Giant, MA_NOTOWNED);
9165557Sjasone
9267266Sjhb#ifdef DIAGNOSTIC
9365557Sjasone		count = 0;
9465557Sjasone
9599072Sjulian		while (count >= 0 && kserunnable() == 0) {
9667266Sjhb#else
9799072Sjulian		while (kserunnable() == 0) {
9867266Sjhb#endif
9965557Sjasone		/*
10065557Sjasone		 * This is a good place to put things to be done in
10165557Sjasone		 * the background, including sanity checks.
10265557Sjasone		 */
10366207Smsmith
10467266Sjhb#ifdef DIAGNOSTIC
10565557Sjasone			if (count++ < 0)
10665557Sjasone				CTR0(KTR_PROC, "idle_proc: timed out waiting"
10765557Sjasone				    " for a process");
10867266Sjhb#endif
10966207Smsmith
11067308Sjhb#ifdef __i386__
11167308Sjhb			cpu_idle();
11267308Sjhb#endif
11365557Sjasone		}
11465557Sjasone
11572200Sbmilekic		mtx_lock_spin(&sched_lock);
11699072Sjulian		p->p_stats->p_ru.ru_nvcsw++;
11765557Sjasone		mi_switch();
11899072Sjulian		td->td_kse->ke_state = KES_RUNNING;
11972200Sbmilekic		mtx_unlock_spin(&sched_lock);
12065557Sjasone	}
12165557Sjasone}
122