kern_idle.c revision 103216
1101776Stjr/*- 2101776Stjr * Copyright (c) 2000, All rights reserved. See /usr/src/COPYRIGHT 3101776Stjr * 4101776Stjr * $FreeBSD: head/sys/kern/kern_idle.c 103216 2002-09-11 08:13:56Z julian $ 5101776Stjr */ 6101776Stjr 7101776Stjr#include "opt_ktrace.h" 8101776Stjr 9101776Stjr#include <sys/param.h> 10101776Stjr#include <sys/systm.h> 11101776Stjr#include <sys/kernel.h> 12101776Stjr#include <sys/ktr.h> 13101776Stjr#include <sys/kthread.h> 14101776Stjr#include <sys/lock.h> 15101776Stjr#include <sys/mutex.h> 16101776Stjr#include <sys/pcpu.h> 17101776Stjr#include <sys/proc.h> 18101776Stjr#include <sys/resourcevar.h> 19101776Stjr#include <sys/smp.h> 20101776Stjr#include <sys/unistd.h> 21101776Stjr#ifdef KTRACE 22101776Stjr#include <sys/uio.h> 23101776Stjr#include <sys/ktrace.h> 24101776Stjr#endif 25101776Stjr 26101776Stjrstatic void idle_setup(void *dummy); 27101776StjrSYSINIT(idle_setup, SI_SUB_SCHED_IDLE, SI_ORDER_FIRST, idle_setup, NULL) 28101776Stjr 29101776Stjrstatic void idle_proc(void *dummy); 30101776Stjr 31101776Stjr/* 32101776Stjr * Setup per-cpu idle process contexts. The AP's shouldn't be running or 33103523Stjr * accessing their idle processes at this point, so don't bother with 34101776Stjr * locking. 35101776Stjr */ 36101776Stjrstatic void 37101776Stjridle_setup(void *dummy) 38101776Stjr{ 39103539Stjr#ifdef SMP 40103539Stjr struct pcpu *pc; 41101776Stjr#endif 42101776Stjr struct proc *p; 43101776Stjr struct thread *td; 44103539Stjr int error; 45103539Stjr 46103539Stjr#ifdef SMP 47103539Stjr SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { 48103539Stjr error = kthread_create(idle_proc, NULL, &p, 49103539Stjr RFSTOPPED | RFHIGHPID, "idle: cpu%d", pc->pc_cpuid); 50103539Stjr pc->pc_idlethread = FIRST_THREAD_IN_PROC(p); 51103539Stjr if (pc->pc_curthread == NULL) { 52103539Stjr pc->pc_curthread = pc->pc_idlethread; 53103539Stjr pc->pc_idlethread->td_critnest = 0; 54103539Stjr } 55103539Stjr#else 56103539Stjr error = kthread_create(idle_proc, NULL, &p, 57103539Stjr RFSTOPPED | RFHIGHPID, "idle"); 58103539Stjr PCPU_SET(idlethread, FIRST_THREAD_IN_PROC(p)); 59103539Stjr#endif 60103539Stjr if (error) 61103539Stjr panic("idle_setup: kthread_create error %d\n", error); 62103539Stjr 63103539Stjr p->p_flag |= P_NOLOAD; 64103523Stjr p->p_state = PRS_NORMAL; 65103523Stjr td = FIRST_THREAD_IN_PROC(p); 66103523Stjr td->td_state = TDS_CAN_RUN; 67103523Stjr td->td_kse->ke_flags |= KEF_IDLEKSE; 68103523Stjr#ifdef SMP 69101776Stjr } 70103523Stjr#endif 71103523Stjr} 72103539Stjr 73103523Stjr/* 74103523Stjr * idle process context 75103523Stjr */ 76103523Stjrstatic void 77103523Stjridle_proc(void *dummy) 78103523Stjr{ 79103523Stjr#ifdef DIAGNOSTIC 80103523Stjr int count; 81103523Stjr#endif 82103523Stjr struct thread *td; 83103523Stjr struct proc *p; 84103538Stjr 85103523Stjr td = curthread; 86103523Stjr p = td->td_proc; 87101776Stjr for (;;) { 88103539Stjr mtx_assert(&Giant, MA_NOTOWNED); 89103523Stjr 90103523Stjr#ifdef DIAGNOSTIC 91103539Stjr count = 0; 92103523Stjr 93103523Stjr while (count >= 0 && kserunnable() == 0) { 94101776Stjr#else 95 while (kserunnable() == 0) { 96#endif 97 /* 98 * This is a good place to put things to be done in 99 * the background, including sanity checks. 100 */ 101 102#ifdef DIAGNOSTIC 103 if (count++ < 0) 104 CTR0(KTR_PROC, "idle_proc: timed out waiting" 105 " for a process"); 106#endif 107 108#ifdef __i386__ 109 cpu_idle(); 110#endif 111 } 112 113 mtx_lock_spin(&sched_lock); 114 p->p_stats->p_ru.ru_nvcsw++; 115 td->td_state = TDS_CAN_RUN; 116 mi_switch(); 117 mtx_unlock_spin(&sched_lock); 118 } 119} 120