1 /*- 2 * Copyright (c) 2000, All rights reserved. See /usr/src/COPYRIGHT 3 * 4 * $FreeBSD$ 5 */ 6 7 #include "opt_ktrace.h" 8 9 #include <sys/param.h> 10 #include <sys/systm.h> 11 #include <sys/proc.h> 12 #include <sys/kernel.h> 13 #include <sys/ktr.h> 14 #include <sys/signalvar.h> 15 #include <sys/resourcevar.h> 16 #include <sys/vmmeter.h> 17 #include <sys/sysctl.h> 18 #include <sys/unistd.h> 19 #include <sys/ipl.h> 20 #include <sys/kthread.h> 21 #include <sys/mutex.h> 22 #include <sys/queue.h> 23 #include <sys/eventhandler.h> 24 #include <vm/vm.h> 25 #include <vm/vm_extern.h> 26 #ifdef KTRACE 27 #include <sys/uio.h> 28 #include <sys/ktrace.h> 29 #endif 30 31 #include <machine/cpu.h> 32 #include <machine/md_var.h> 33 #include <machine/smp.h> 34 35 #include <machine/globaldata.h> 36 #include <machine/globals.h> 37 38 static void idle_setup(void *dummy); 39 SYSINIT(idle_setup, SI_SUB_SCHED_IDLE, SI_ORDER_FIRST, idle_setup, NULL) 40 41 static void idle_proc(void *dummy); 42 43 /* 44 * setup per-cpu idle process contexts 45 */ 46 static void 47 idle_setup(void *dummy) 48 { 49 struct globaldata *gd; 50 int error; 51 52 SLIST_FOREACH(gd, &cpuhead, gd_allcpu) { 53 #ifdef SMP 54 error = kthread_create(idle_proc, NULL, &gd->gd_idleproc, 55 RFSTOPPED|RFHIGHPID, "idle: cpu%d", 56 gd->gd_cpuid); 57 #else 58 error = kthread_create(idle_proc, NULL, &gd->gd_idleproc, 59 RFSTOPPED|RFHIGHPID, "idle"); 60 #endif 61 if (error) 62 panic("idle_setup: kthread_create error %d\n", error); 63 64 gd->gd_idleproc->p_flag |= P_NOLOAD; 65 gd->gd_idleproc->p_stat = SRUN; 66 } 67 } 68 69 /* 70 * idle process context 71 */ 72 static void 73 idle_proc(void *dummy) 74 { 75 #ifdef DIAGNOSTIC 76 int count; 77 #endif 78 79 for (;;) { 80 mtx_assert(&Giant, MA_NOTOWNED); 81 82 #ifdef DIAGNOSTIC 83 count = 0; 84 85 while (count >= 0 && procrunnable() == 0) { 86 #else 87 while (procrunnable() == 0) { 88 #endif 89 /* 90 * This is a good place to put things to be done in 91 * the background, including sanity checks. 92 */ 93 94 #ifdef DIAGNOSTIC 95 if (count++ < 0) 96 CTR0(KTR_PROC, "idle_proc: timed out waiting" 97 " for a process"); 98 #endif 99 100 if (vm_page_zero_idle() != 0) 101 continue; 102 103 #ifdef __i386__ 104 cpu_idle(); 105 #endif 106 } 107 108 mtx_enter(&sched_lock, MTX_SPIN); 109 mi_switch(); 110 mtx_exit(&sched_lock, MTX_SPIN); 111 } 112 } 113