kern_idle.c revision 90361
1/*-
2 * Copyright (c) 2000, All rights reserved.  See /usr/src/COPYRIGHT
3 *
4 * $FreeBSD: head/sys/kern/kern_idle.c 90361 2002-02-07 20:58:47Z 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	int error;
44
45#ifdef SMP
46	SLIST_FOREACH(pc, &cpuhead, pc_allcpu) {
47		error = kthread_create(idle_proc, NULL, &p,
48		    RFSTOPPED | RFHIGHPID, "idle: cpu%d", pc->pc_cpuid);
49		pc->pc_idlethread = FIRST_THREAD_IN_PROC(p);
50		if (pc->pc_curthread == NULL) {
51			pc->pc_curthread = pc->pc_idlethread;
52			pc->pc_idlethread->td_critnest = 0;
53		}
54#else
55		error = kthread_create(idle_proc, NULL, &p,
56		    RFSTOPPED | RFHIGHPID, "idle");
57		PCPU_SET(idlethread, FIRST_THREAD_IN_PROC(p));
58#endif
59		if (error)
60			panic("idle_setup: kthread_create error %d\n", error);
61
62		p->p_flag |= P_NOLOAD;
63		p->p_stat = SRUN;
64#ifdef SMP
65	}
66#endif
67}
68
69/*
70 * idle process context
71 */
72static void
73idle_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#ifdef __i386__
101			cpu_idle();
102#endif
103		}
104
105		mtx_lock_spin(&sched_lock);
106		curproc->p_stats->p_ru.ru_nvcsw++;
107		mi_switch();
108		mtx_unlock_spin(&sched_lock);
109	}
110}
111