kern_idle.c revision 104964
11541Srgrimes/*- 21541Srgrimes * Copyright (c) 2000, All rights reserved. See /usr/src/COPYRIGHT 31541Srgrimes * 41541Srgrimes * $FreeBSD: head/sys/kern/kern_idle.c 104964 2002-10-12 05:32:24Z jeff $ 51541Srgrimes */ 61541Srgrimes 71541Srgrimes#include "opt_ktrace.h" 81541Srgrimes 91541Srgrimes#include <sys/param.h> 101541Srgrimes#include <sys/systm.h> 111541Srgrimes#include <sys/kernel.h> 121541Srgrimes#include <sys/ktr.h> 131541Srgrimes#include <sys/kthread.h> 141541Srgrimes#include <sys/lock.h> 151541Srgrimes#include <sys/mutex.h> 161541Srgrimes#include <sys/pcpu.h> 171541Srgrimes#include <sys/proc.h> 181541Srgrimes#include <sys/resourcevar.h> 191541Srgrimes#include <sys/sched.h> 201541Srgrimes#include <sys/smp.h> 211541Srgrimes#include <sys/unistd.h> 221541Srgrimes#ifdef KTRACE 231541Srgrimes#include <sys/uio.h> 241541Srgrimes#include <sys/ktrace.h> 251541Srgrimes#endif 261541Srgrimes 271541Srgrimesstatic void idle_setup(void *dummy); 281541SrgrimesSYSINIT(idle_setup, SI_SUB_SCHED_IDLE, SI_ORDER_FIRST, idle_setup, NULL) 291541Srgrimes 301541Srgrimesstatic void idle_proc(void *dummy); 311541Srgrimes 321541Srgrimes/* 331541Srgrimes * Setup per-cpu idle process contexts. The AP's shouldn't be running or 3450477Speter * accessing their idle processes at this point, so don't bother with 351541Srgrimes * locking. 361541Srgrimes */ 3732358Seivindstatic void 3816333Sgpalmeridle_setup(void *dummy) 3941793Sluigi{ 4030966Sjoerg#ifdef SMP 4134746Speter struct pcpu *pc; 4250561Sdes#endif 4355009Sshin struct proc *p; 44101095Srwatson struct thread *td; 4564060Sdarrenr int error; 4677574Skris 4716333Sgpalmer#ifdef SMP 481541Srgrimes SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { 491541Srgrimes error = kthread_create(idle_proc, NULL, &p, 50101095Srwatson RFSTOPPED | RFHIGHPID, 0, "idle: cpu%d", pc->pc_cpuid); 511541Srgrimes pc->pc_idlethread = FIRST_THREAD_IN_PROC(p); 5241793Sluigi if (pc->pc_curthread == NULL) { 531541Srgrimes pc->pc_curthread = pc->pc_idlethread; 541541Srgrimes pc->pc_idlethread->td_critnest = 0; 551541Srgrimes } 561541Srgrimes#else 571541Srgrimes error = kthread_create(idle_proc, NULL, &p, 587091Swollman RFSTOPPED | RFHIGHPID, 0, "idle"); 597090Sbde PCPU_SET(idlethread, FIRST_THREAD_IN_PROC(p)); 601541Srgrimes#endif 6164075Sache if (error) 621541Srgrimes panic("idle_setup: kthread_create error %d\n", error); 6383934Sbrooks 6430948Sjulian p->p_flag |= P_NOLOAD; 6519622Sfenner p->p_state = PRS_NORMAL; 661541Srgrimes td = FIRST_THREAD_IN_PROC(p); 678426Swollman td->td_state = TDS_CAN_RUN; 681541Srgrimes td->td_kse->ke_flags |= KEF_IDLEKSE; 691541Srgrimes#ifdef SMP 701541Srgrimes } 717090Sbde#endif 721541Srgrimes} 731541Srgrimes 741541Srgrimes/* 751541Srgrimes * idle process context 7618797Swollman */ 771541Srgrimesstatic void 782531Swollmanidle_proc(void *dummy) 7915680Sgpalmer{ 8015680Sgpalmer#ifdef DIAGNOSTIC 8184516Sps int count; 8215680Sgpalmer#endif 8355009Sshin struct thread *td; 8455009Sshin struct proc *p; 8555009Sshin 8655009Sshin td = curthread; 8755009Sshin p = td->td_proc; 88105199Ssam for (;;) { 89105199Ssam mtx_assert(&Giant, MA_NOTOWNED); 90105199Ssam 91105199Ssam#ifdef DIAGNOSTIC 92105199Ssam count = 0; 939209Swollman 942531Swollman while (count >= 0 && sched_runnable() == 0) { 9536192Sdg#else 9612296Sphk while (sched_runnable() == 0) { 9746381Sbillf#endif 9812296Sphk /* 9913266Swollman * This is a good place to put things to be done in 10012296Sphk * the background, including sanity checks. 10146381Sbillf */ 10212296Sphk 1031541Srgrimes#ifdef DIAGNOSTIC 10412296Sphk if (count++ < 0) 10546381Sbillf CTR0(KTR_PROC, "idle_proc: timed out waiting" 10612296Sphk " for a process"); 10712296Sphk#endif 10812296Sphk 10946381Sbillf#ifdef __i386__ 11033440Sguido cpu_idle(); 11133440Sguido#endif 11246381Sbillf } 11346381Sbillf 11446381Sbillf mtx_lock_spin(&sched_lock); 11555009Sshin p->p_stats->p_ru.ru_nvcsw++; 11655009Sshin td->td_state = TDS_CAN_RUN; 11755009Sshin mi_switch(); 11855009Sshin mtx_unlock_spin(&sched_lock); 11955009Sshin } 12055009Sshin} 121109843Ssilby