kern_idle.c revision 101176
1/*- 2 * Copyright (c) 2000, All rights reserved. See /usr/src/COPYRIGHT 3 * 4 * $FreeBSD: head/sys/kern/kern_idle.c 101176 2002-08-01 18:45:10Z julian $ 5 */ 6 7#include "opt_ktrace.h" 8 9#include <sys/param.h> 10#include <sys/systm.h> 11#include <sys/kernel.h> 12#include <sys/ktr.h> 13#include <sys/kthread.h> 14#include <sys/lock.h> 15#include <sys/mutex.h> 16#include <sys/pcpu.h> 17#include <sys/proc.h> 18#include <sys/resourcevar.h> 19#include <sys/smp.h> 20#include <sys/unistd.h> 21#ifdef KTRACE 22#include <sys/uio.h> 23#include <sys/ktrace.h> 24#endif 25 26static void idle_setup(void *dummy); 27SYSINIT(idle_setup, SI_SUB_SCHED_IDLE, SI_ORDER_FIRST, idle_setup, NULL) 28 29static void idle_proc(void *dummy); 30 31/* 32 * Setup per-cpu idle process contexts. The AP's shouldn't be running or 33 * accessing their idle processes at this point, so don't bother with 34 * locking. 35 */ 36static void 37idle_setup(void *dummy) 38{ 39#ifdef SMP 40 struct pcpu *pc; 41#endif 42 struct proc *p; 43 struct thread *td; 44 int error; 45 46#ifdef SMP 47 SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { 48 error = kthread_create(idle_proc, NULL, &p, 49 RFSTOPPED | RFHIGHPID, "idle: cpu%d", pc->pc_cpuid); 50 pc->pc_idlethread = FIRST_THREAD_IN_PROC(p); 51 if (pc->pc_curthread == NULL) { 52 pc->pc_curthread = pc->pc_idlethread; 53 pc->pc_idlethread->td_critnest = 0; 54 } 55#else 56 error = kthread_create(idle_proc, NULL, &p, 57 RFSTOPPED | RFHIGHPID, "idle"); 58 PCPU_SET(idlethread, FIRST_THREAD_IN_PROC(p)); 59#endif 60 if (error) 61 panic("idle_setup: kthread_create error %d\n", error); 62 63 p->p_flag |= P_NOLOAD; 64 p->p_state = PRS_NORMAL; 65 td = FIRST_THREAD_IN_PROC(p); 66 td->td_state = TDS_UNQUEUED; 67 td->td_kse->ke_flags |= KEF_IDLEKSE; 68#ifdef SMP 69 } 70#endif 71} 72 73/* 74 * idle process context 75 */ 76static void 77idle_proc(void *dummy) 78{ 79#ifdef DIAGNOSTIC 80 int count; 81#endif 82 struct thread *td; 83 struct proc *p; 84 85 td = curthread; 86 p = td->td_proc; 87 for (;;) { 88 mtx_assert(&Giant, MA_NOTOWNED); 89 90#ifdef DIAGNOSTIC 91 count = 0; 92 93 while (count >= 0 && kserunnable() == 0) { 94#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_UNQUEUED; 116 mi_switch(); 117 mtx_unlock_spin(&sched_lock); 118 } 119} 120