kern_idle.c revision 99942
1/*- 2 * Copyright (c) 2000, All rights reserved. See /usr/src/COPYRIGHT 3 * 4 * $FreeBSD: head/sys/kern/kern_idle.c 99942 2002-07-14 03:43:33Z 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 td = FIRST_THREAD_IN_PROC(p); 65 td->td_state = TDS_UNQUEUED; 66 td->td_kse->ke_flags |= KEF_IDLEKSE; 67#ifdef SMP 68 } 69#endif 70} 71 72/* 73 * idle process context 74 */ 75static void 76idle_proc(void *dummy) 77{ 78#ifdef DIAGNOSTIC 79 int count; 80#endif 81 struct thread *td; 82 struct proc *p; 83 84 td = curthread; 85 p = td->td_proc; 86 for (;;) { 87 mtx_assert(&Giant, MA_NOTOWNED); 88 89#ifdef DIAGNOSTIC 90 count = 0; 91 92 while (count >= 0 && kserunnable() == 0) { 93#else 94 while (kserunnable() == 0) { 95#endif 96 /* 97 * This is a good place to put things to be done in 98 * the background, including sanity checks. 99 */ 100 101#ifdef DIAGNOSTIC 102 if (count++ < 0) 103 CTR0(KTR_PROC, "idle_proc: timed out waiting" 104 " for a process"); 105#endif 106 107#ifdef __i386__ 108 cpu_idle(); 109#endif 110 } 111 112 mtx_lock_spin(&sched_lock); 113 p->p_stats->p_ru.ru_nvcsw++; 114 mi_switch(); 115 mtx_unlock_spin(&sched_lock); 116 } 117} 118