kern_idle.c revision 82757
1/*-
2 * Copyright (c) 2000, All rights reserved.  See /usr/src/COPYRIGHT
3 *
4 * $FreeBSD: head/sys/kern/kern_idle.c 82757 2001-09-01 20:17:43Z jhb $
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 globaldata *gd;
41#endif
42	struct proc *p;
43	int error;
44
45#ifdef SMP
46	SLIST_FOREACH(gd, &cpuhead, gd_allcpu) {
47		error = kthread_create(idle_proc, NULL, &p,
48		    RFSTOPPED | RFHIGHPID, "idle: cpu%d", gd->gd_cpuid);
49		gd->gd_idleproc = p;
50		if (gd->gd_curproc == NULL)
51			gd->gd_curproc = p;
52#else
53		error = kthread_create(idle_proc, NULL, &p,
54		    RFSTOPPED | RFHIGHPID, "idle");
55		PCPU_SET(idleproc, p);
56#endif
57		if (error)
58			panic("idle_setup: kthread_create error %d\n", error);
59
60		p->p_flag |= P_NOLOAD;
61		p->p_stat = SRUN;
62#ifdef SMP
63	}
64#endif
65}
66
67/*
68 * idle process context
69 */
70static void
71idle_proc(void *dummy)
72{
73#ifdef DIAGNOSTIC
74	int count;
75#endif
76
77	for (;;) {
78		mtx_assert(&Giant, MA_NOTOWNED);
79
80#ifdef DIAGNOSTIC
81		count = 0;
82
83		while (count >= 0 && procrunnable() == 0) {
84#else
85		while (procrunnable() == 0) {
86#endif
87		/*
88		 * This is a good place to put things to be done in
89		 * the background, including sanity checks.
90		 */
91
92#ifdef DIAGNOSTIC
93			if (count++ < 0)
94				CTR0(KTR_PROC, "idle_proc: timed out waiting"
95				    " for a process");
96#endif
97
98#ifdef __i386__
99			cpu_idle();
100#endif
101		}
102
103		mtx_lock_spin(&sched_lock);
104		curproc->p_stats->p_ru.ru_nvcsw++;
105		mi_switch();
106		mtx_unlock_spin(&sched_lock);
107	}
108}
109