]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/kern/kern_idle.c
- Heavyweight interrupt threads on the alpha for device I/O interrupts.
[FreeBSD/FreeBSD.git] / sys / kern / kern_idle.c
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/queue.h>
22 #include <sys/eventhandler.h>
23 #include <vm/vm.h>
24 #include <vm/vm_extern.h>
25 #ifdef KTRACE
26 #include <sys/uio.h>
27 #include <sys/ktrace.h>
28 #endif
29
30 #include <machine/cpu.h>
31 #include <machine/mutex.h>
32 #include <machine/smp.h>
33
34 #include <machine/globaldata.h>
35 #include <machine/globals.h>
36
37 #ifdef SMP_DEBUG
38 #include <sys/bus.h>
39 #include <i386/isa/icu.h>
40 #include <i386/isa/intr_machdep.h>
41 #endif
42
43 static void idle_setup(void *dummy);
44 SYSINIT(idle_setup, SI_SUB_SCHED_IDLE, SI_ORDER_FIRST, idle_setup, NULL)
45
46 static void idle_proc(void *dummy);
47
48 EVENTHANDLER_FAST_DEFINE(idle_event, idle_eventhandler_t);
49
50 /*
51  * setup per-cpu idle process contexts
52  */
53 static void
54 idle_setup(void *dummy)
55 {
56         struct globaldata *gd;
57         int error;
58
59         SLIST_FOREACH(gd, &cpuhead, gd_allcpu) {
60 #ifdef SMP
61                 error = kthread_create(idle_proc, NULL, &gd->gd_idleproc,
62                                        RFSTOPPED|RFHIGHPID, "idle: cpu%d",
63                                        gd->gd_cpuid);
64 #else
65                 error = kthread_create(idle_proc, NULL, &gd->gd_idleproc,
66                                        RFSTOPPED|RFHIGHPID, "idle");
67 #endif
68                 if (error)
69                         panic("idle_setup: kthread_create error %d\n", error);
70
71                 gd->gd_idleproc->p_flag |= P_NOLOAD;
72                 gd->gd_idleproc->p_stat = SRUN;
73         }
74 }
75
76 /*
77  * idle process context
78  */
79 static void
80 idle_proc(void *dummy)
81 {
82         int count;
83
84         for (;;) {
85                 mtx_assert(&Giant, MA_NOTOWNED);
86
87                 count = 0;
88
89                 while (count >= 0 && procrunnable() == 0) {
90                 /*
91                  * This is a good place to put things to be done in
92                  * the background, including sanity checks.
93                  */
94
95                         if (count++ < 0)
96                                 CTR0(KTR_PROC, "idle_proc: timed out waiting"
97                                     " for a process");
98
99                         /* call out to any cpu-becoming-idle events */
100                         EVENTHANDLER_FAST_INVOKE(idle_event, count);
101                 }
102
103                 mtx_enter(&sched_lock, MTX_SPIN);
104                 mi_switch();
105                 mtx_exit(&sched_lock, MTX_SPIN);
106         }
107 }