kern_idle.c revision 87702
165557Sjasone/*-
265557Sjasone * Copyright (c) 2000, All rights reserved.  See /usr/src/COPYRIGHT
365557Sjasone *
465557Sjasone * $FreeBSD: head/sys/kern/kern_idle.c 87702 2001-12-11 23:33:44Z jhb $
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;
4365557Sjasone	int error;
4465557Sjasone
4576078Sjhb#ifdef SMP
4687702Sjhb	SLIST_FOREACH(pc, &cpuhead, pc_allcpu) {
4776078Sjhb		error = kthread_create(idle_proc, NULL, &p,
4887702Sjhb		    RFSTOPPED | RFHIGHPID, "idle: cpu%d", pc->pc_cpuid);
4987702Sjhb		pc->pc_idlethread = &p->p_thread;
5087702Sjhb		if (pc->pc_curthread == NULL)
5187702Sjhb			pc->pc_curthread = pc->pc_idlethread;
5265557Sjasone#else
5376078Sjhb		error = kthread_create(idle_proc, NULL, &p,
5476078Sjhb		    RFSTOPPED | RFHIGHPID, "idle");
5583366Sjulian		PCPU_SET(idlethread, &p->p_thread);
5665557Sjasone#endif
5765557Sjasone		if (error)
5865557Sjasone			panic("idle_setup: kthread_create error %d\n", error);
5965557Sjasone
6076078Sjhb		p->p_flag |= P_NOLOAD;
6176078Sjhb		p->p_stat = SRUN;
6276078Sjhb#ifdef SMP
6365557Sjasone	}
6476078Sjhb#endif
6565557Sjasone}
6665557Sjasone
6765557Sjasone/*
6865557Sjasone * idle process context
6965557Sjasone */
7065557Sjasonestatic void
7165557Sjasoneidle_proc(void *dummy)
7265557Sjasone{
7367266Sjhb#ifdef DIAGNOSTIC
7465557Sjasone	int count;
7567266Sjhb#endif
7665557Sjasone
7765557Sjasone	for (;;) {
7865557Sjasone		mtx_assert(&Giant, MA_NOTOWNED);
7965557Sjasone
8067266Sjhb#ifdef DIAGNOSTIC
8165557Sjasone		count = 0;
8265557Sjasone
8365557Sjasone		while (count >= 0 && procrunnable() == 0) {
8467266Sjhb#else
8567266Sjhb		while (procrunnable() == 0) {
8667266Sjhb#endif
8765557Sjasone		/*
8865557Sjasone		 * This is a good place to put things to be done in
8965557Sjasone		 * the background, including sanity checks.
9065557Sjasone		 */
9166207Smsmith
9267266Sjhb#ifdef DIAGNOSTIC
9365557Sjasone			if (count++ < 0)
9465557Sjasone				CTR0(KTR_PROC, "idle_proc: timed out waiting"
9565557Sjasone				    " for a process");
9667266Sjhb#endif
9766207Smsmith
9867308Sjhb#ifdef __i386__
9967308Sjhb			cpu_idle();
10067308Sjhb#endif
10165557Sjasone		}
10265557Sjasone
10372200Sbmilekic		mtx_lock_spin(&sched_lock);
10472222Sjhb		curproc->p_stats->p_ru.ru_nvcsw++;
10565557Sjasone		mi_switch();
10672200Sbmilekic		mtx_unlock_spin(&sched_lock);
10765557Sjasone	}
10865557Sjasone}
109