kern_idle.c revision 131243
1/*-
2 * Copyright (c) 2000, All rights reserved.  See /usr/src/COPYRIGHT
3 *
4 */
5
6#include <sys/cdefs.h>
7__FBSDID("$FreeBSD: head/sys/kern/kern_idle.c 131243 2004-06-28 16:19:50Z jhb $");
8
9#include <sys/param.h>
10#include <sys/systm.h>
11#include <sys/kernel.h>
12#include <sys/kthread.h>
13#include <sys/lock.h>
14#include <sys/mutex.h>
15#include <sys/proc.h>
16#include <sys/resourcevar.h>
17#include <sys/sched.h>
18#include <sys/unistd.h>
19
20static void idle_setup(void *dummy);
21SYSINIT(idle_setup, SI_SUB_SCHED_IDLE, SI_ORDER_FIRST, idle_setup, NULL)
22
23static void idle_proc(void *dummy);
24
25/*
26 * Set up per-cpu idle process contexts.  The AP's shouldn't be running or
27 * accessing their idle processes at this point, so don't bother with
28 * locking.
29 */
30static void
31idle_setup(void *dummy)
32{
33#ifdef SMP
34	struct pcpu *pc;
35#endif
36	struct proc *p;
37	struct thread *td;
38	int error;
39
40#ifdef SMP
41	SLIST_FOREACH(pc, &cpuhead, pc_allcpu) {
42		error = kthread_create(idle_proc, NULL, &p,
43		    RFSTOPPED | RFHIGHPID, 0, "idle: cpu%d", pc->pc_cpuid);
44		pc->pc_idlethread = FIRST_THREAD_IN_PROC(p);
45		if (pc->pc_curthread == NULL) {
46			pc->pc_curthread = pc->pc_idlethread;
47			pc->pc_idlethread->td_critnest = 0;
48		}
49#else
50		error = kthread_create(idle_proc, NULL, &p,
51		    RFSTOPPED | RFHIGHPID, 0, "idle");
52		PCPU_SET(idlethread, FIRST_THREAD_IN_PROC(p));
53#endif
54		if (error)
55			panic("idle_setup: kthread_create error %d\n", error);
56
57		PROC_LOCK(p);
58		p->p_flag |= P_NOLOAD;
59		mtx_lock_spin(&sched_lock);
60		td = FIRST_THREAD_IN_PROC(p);
61		td->td_state = TDS_CAN_RUN;
62		td->td_flags |= TDF_IDLETD;
63		td->td_priority = PRI_MAX_IDLE;
64		mtx_unlock_spin(&sched_lock);
65		PROC_UNLOCK(p);
66#ifdef SMP
67	}
68#endif
69}
70
71/*
72 * The actual idle process.
73 */
74static void
75idle_proc(void *dummy)
76{
77	struct proc *p;
78	struct thread *td;
79
80	td = curthread;
81	p = td->td_proc;
82	for (;;) {
83		mtx_assert(&Giant, MA_NOTOWNED);
84
85		while (sched_runnable() == 0)
86			cpu_idle();
87
88		mtx_lock_spin(&sched_lock);
89		td->td_state = TDS_CAN_RUN;
90		mi_switch(SW_VOL);
91		mtx_unlock_spin(&sched_lock);
92	}
93}
94