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