kern_idle.c revision 76166
1/*-
2 * Copyright (c) 2000, All rights reserved.  See /usr/src/COPYRIGHT
3 *
4 * $FreeBSD: head/sys/kern/kern_idle.c 76166 2001-05-01 08:13:21Z markm $
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/lock.h>
14#include <sys/mutex.h>
15#include <sys/proc.h>
16#include <sys/signalvar.h>
17#include <sys/smp.h>
18#include <sys/resourcevar.h>
19#include <sys/vmmeter.h>
20#include <sys/sysctl.h>
21#include <sys/unistd.h>
22#include <sys/ipl.h>
23#include <sys/kthread.h>
24#include <sys/queue.h>
25#include <sys/eventhandler.h>
26#include <vm/vm.h>
27#include <vm/vm_extern.h>
28#ifdef KTRACE
29#include <sys/uio.h>
30#include <sys/ktrace.h>
31#endif
32
33#include <machine/cpu.h>
34#include <machine/md_var.h>
35
36#include <machine/globaldata.h>
37#include <machine/globals.h>
38
39static void idle_setup(void *dummy);
40SYSINIT(idle_setup, SI_SUB_SCHED_IDLE, SI_ORDER_FIRST, idle_setup, NULL)
41
42static void idle_proc(void *dummy);
43
44/*
45 * Setup per-cpu idle process contexts.  The AP's shouldn't be running or
46 * accessing their idle processes at this point, so don't bother with
47 * locking.
48 */
49static void
50idle_setup(void *dummy)
51{
52#ifdef SMP
53	struct globaldata *gd;
54#endif
55	struct proc *p;
56	int error;
57
58#ifdef SMP
59	SLIST_FOREACH(gd, &cpuhead, gd_allcpu) {
60		error = kthread_create(idle_proc, NULL, &p,
61		    RFSTOPPED | RFHIGHPID, "idle: cpu%d", gd->gd_cpuid);
62		gd->gd_idleproc = p;
63		if (gd->gd_curproc == NULL)
64			gd->gd_curproc = p;
65#else
66		error = kthread_create(idle_proc, NULL, &p,
67		    RFSTOPPED | RFHIGHPID, "idle");
68		PCPU_SET(idleproc, p);
69#endif
70		if (error)
71			panic("idle_setup: kthread_create error %d\n", error);
72
73		p->p_flag |= P_NOLOAD;
74		p->p_stat = SRUN;
75#ifdef SMP
76	}
77#endif
78}
79
80/*
81 * idle process context
82 */
83static void
84idle_proc(void *dummy)
85{
86#ifdef DIAGNOSTIC
87	int count;
88#endif
89
90	for (;;) {
91		mtx_assert(&Giant, MA_NOTOWNED);
92
93#ifdef DIAGNOSTIC
94		count = 0;
95
96		while (count >= 0 && procrunnable() == 0) {
97#else
98		while (procrunnable() == 0) {
99#endif
100		/*
101		 * This is a good place to put things to be done in
102		 * the background, including sanity checks.
103		 */
104
105#ifdef DIAGNOSTIC
106			if (count++ < 0)
107				CTR0(KTR_PROC, "idle_proc: timed out waiting"
108				    " for a process");
109#endif
110
111#if 0
112			if (vm_page_zero_idle() != 0)
113				continue;
114#endif
115
116#ifdef __i386__
117			cpu_idle();
118#endif
119		}
120
121		mtx_lock_spin(&sched_lock);
122		curproc->p_stats->p_ru.ru_nvcsw++;
123		mi_switch();
124		mtx_unlock_spin(&sched_lock);
125	}
126}
127