kern_idle.c revision 65900
1/*-
2 * Copyright (c) 2000, All rights reserved.  See /usr/src/COPYRIGHT
3 *
4 * $FreeBSD: head/sys/kern/kern_idle.c 65900 2000-09-15 19:49:48Z jhb $
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/kthread.h>
20#include <sys/queue.h>
21#include <vm/vm.h>
22#include <vm/vm_extern.h>
23#ifdef KTRACE
24#include <sys/uio.h>
25#include <sys/ktrace.h>
26#endif
27
28#include <machine/cpu.h>
29#include <machine/ipl.h>
30#include <machine/mutex.h>
31#include <machine/smp.h>
32
33#include <machine/globaldata.h>
34#include <machine/globals.h>
35
36#ifdef SMP_DEBUG
37#include <sys/bus.h>
38#include <i386/isa/icu.h>
39#include <i386/isa/intr_machdep.h>
40#endif
41
42static void idle_setup(void *dummy);
43SYSINIT(idle_setup, SI_SUB_SCHED_IDLE, SI_ORDER_FIRST, idle_setup, NULL)
44
45static void idle_proc(void *dummy);
46
47/*
48 * setup per-cpu idle process contexts
49 */
50static void
51idle_setup(void *dummy)
52{
53	struct globaldata *gd;
54	int error;
55
56	SLIST_FOREACH(gd, &cpuhead, gd_allcpu) {
57#ifdef SMP
58		error = kthread_create(idle_proc, NULL, &gd->gd_idleproc,
59				       RFSTOPPED|RFHIGHPID, "idle: cpu%d",
60				       gd->gd_cpuid);
61#else
62		error = kthread_create(idle_proc, NULL, &gd->gd_idleproc,
63				       RFSTOPPED|RFHIGHPID, "idle");
64#endif
65		if (error)
66			panic("idle_setup: kthread_create error %d\n", error);
67
68		gd->gd_idleproc->p_stat = SRUN;
69	}
70}
71
72/*
73 * idle process context
74 */
75static void
76idle_proc(void *dummy)
77{
78	int count;
79
80	for (;;) {
81		/*
82		 * Clear switchtime, which prevents the idle process's time
83		 * from being counted.
84		switchtime.tv_usec = 0;
85		switchtime.tv_sec = 0;
86		 */
87
88		mtx_assert(&Giant, MA_NOTOWNED);
89
90		count = 0;
91
92		while (count >= 0 && procrunnable() == 0) {
93		/*
94		 * This is a good place to put things to be done in
95		 * the background, including sanity checks.
96		 */
97			if (count++ < 0)
98				CTR0(KTR_PROC, "idle_proc: timed out waiting"
99				    " for a process");
100		}
101
102		mtx_enter(&sched_lock, MTX_SPIN);
103		mi_switch();
104		mtx_exit(&sched_lock, MTX_SPIN);
105		spl0();
106	}
107}
108