kern_idle.c revision 131473
165557Sjasone/*-
265557Sjasone * Copyright (c) 2000, All rights reserved.  See /usr/src/COPYRIGHT
365557Sjasone *
465557Sjasone */
565557Sjasone
6116182Sobrien#include <sys/cdefs.h>
7116182Sobrien__FBSDID("$FreeBSD: head/sys/kern/kern_idle.c 131473 2004-07-02 19:09:50Z jhb $");
8116182Sobrien
965557Sjasone#include <sys/param.h>
1065557Sjasone#include <sys/systm.h>
1165557Sjasone#include <sys/kernel.h>
1276440Sjhb#include <sys/kthread.h>
1376166Smarkm#include <sys/lock.h>
1476166Smarkm#include <sys/mutex.h>
1576166Smarkm#include <sys/proc.h>
1676440Sjhb#include <sys/resourcevar.h>
17104964Sjeff#include <sys/sched.h>
1865557Sjasone#include <sys/unistd.h>
1965557Sjasone
2065557Sjasonestatic void idle_setup(void *dummy);
2165557SjasoneSYSINIT(idle_setup, SI_SUB_SCHED_IDLE, SI_ORDER_FIRST, idle_setup, NULL)
2265557Sjasone
2365557Sjasonestatic void idle_proc(void *dummy);
2465557Sjasone
2565557Sjasone/*
26121238Speter * Set up per-cpu idle process contexts.  The AP's shouldn't be running or
2772222Sjhb * accessing their idle processes at this point, so don't bother with
2872222Sjhb * locking.
2965557Sjasone */
3065557Sjasonestatic void
3165557Sjasoneidle_setup(void *dummy)
3265557Sjasone{
3376078Sjhb#ifdef SMP
3487702Sjhb	struct pcpu *pc;
3576078Sjhb#endif
3676078Sjhb	struct proc *p;
3799072Sjulian	struct thread *td;
3865557Sjasone	int error;
3965557Sjasone
4076078Sjhb#ifdef SMP
4187702Sjhb	SLIST_FOREACH(pc, &cpuhead, pc_allcpu) {
4276078Sjhb		error = kthread_create(idle_proc, NULL, &p,
43104354Sscottl		    RFSTOPPED | RFHIGHPID, 0, "idle: cpu%d", pc->pc_cpuid);
4490361Sjulian		pc->pc_idlethread = FIRST_THREAD_IN_PROC(p);
4588088Sjhb		if (pc->pc_curthread == NULL) {
4687702Sjhb			pc->pc_curthread = pc->pc_idlethread;
4788088Sjhb			pc->pc_idlethread->td_critnest = 0;
4888088Sjhb		}
4965557Sjasone#else
5076078Sjhb		error = kthread_create(idle_proc, NULL, &p,
51104354Sscottl		    RFSTOPPED | RFHIGHPID, 0, "idle");
5290361Sjulian		PCPU_SET(idlethread, FIRST_THREAD_IN_PROC(p));
5365557Sjasone#endif
5465557Sjasone		if (error)
5565557Sjasone			panic("idle_setup: kthread_create error %d\n", error);
5665557Sjasone
57113629Sjhb		PROC_LOCK(p);
5876078Sjhb		p->p_flag |= P_NOLOAD;
59113629Sjhb		mtx_lock_spin(&sched_lock);
6099072Sjulian		td = FIRST_THREAD_IN_PROC(p);
61131473Sjhb		TD_SET_CAN_RUN(td);
62114471Sjulian		td->td_flags |= TDF_IDLETD;
63131243Sjhb		td->td_priority = PRI_MAX_IDLE;
64113629Sjhb		mtx_unlock_spin(&sched_lock);
65113629Sjhb		PROC_UNLOCK(p);
6676078Sjhb#ifdef SMP
6765557Sjasone	}
6876078Sjhb#endif
6965557Sjasone}
7065557Sjasone
7165557Sjasone/*
72121238Speter * The actual idle process.
7365557Sjasone */
7465557Sjasonestatic void
7565557Sjasoneidle_proc(void *dummy)
7665557Sjasone{
77121238Speter	struct proc *p;
7899072Sjulian	struct thread *td;
7965557Sjasone
8099072Sjulian	td = curthread;
8199072Sjulian	p = td->td_proc;
8265557Sjasone	for (;;) {
8365557Sjasone		mtx_assert(&Giant, MA_NOTOWNED);
8465557Sjasone
85121238Speter		while (sched_runnable() == 0)
8667308Sjhb			cpu_idle();
8765557Sjasone
8872200Sbmilekic		mtx_lock_spin(&sched_lock);
89131473Sjhb		mi_switch(SW_VOL, NULL);
9072200Sbmilekic		mtx_unlock_spin(&sched_lock);
9165557Sjasone	}
9265557Sjasone}
93