xref: /freebsd/sys/kern/kern_idle.c (revision bf0acc273a119b831959adba75a1c1de8ade7c51)
10384fff8SJason Evans /*-
20384fff8SJason Evans  * Copyright (c) 2000, All rights reserved.  See /usr/src/COPYRIGHT
30384fff8SJason Evans  *
40384fff8SJason Evans  */
50384fff8SJason Evans 
6677b542eSDavid E. O'Brien #include <sys/cdefs.h>
7677b542eSDavid E. O'Brien __FBSDID("$FreeBSD$");
8677b542eSDavid E. O'Brien 
90384fff8SJason Evans #include <sys/param.h>
100384fff8SJason Evans #include <sys/systm.h>
110384fff8SJason Evans #include <sys/kernel.h>
12ba228f6dSJohn Baldwin #include <sys/kthread.h>
13fb919e4dSMark Murray #include <sys/lock.h>
14fb919e4dSMark Murray #include <sys/mutex.h>
15fb919e4dSMark Murray #include <sys/proc.h>
160384fff8SJason Evans #include <sys/resourcevar.h>
17b43179fbSJeff Roberson #include <sys/sched.h>
180384fff8SJason Evans #include <sys/unistd.h>
190384fff8SJason Evans 
200384fff8SJason Evans static void idle_setup(void *dummy);
210384fff8SJason Evans SYSINIT(idle_setup, SI_SUB_SCHED_IDLE, SI_ORDER_FIRST, idle_setup, NULL)
220384fff8SJason Evans 
230384fff8SJason Evans static void idle_proc(void *dummy);
240384fff8SJason Evans 
250384fff8SJason Evans /*
267ecfc090SJohn Baldwin  * Set up per-cpu idle process contexts.  The AP's shouldn't be running or
277ecfc090SJohn Baldwin  * accessing their idle processes at this point, so don't bother with
287ecfc090SJohn Baldwin  * locking.
290384fff8SJason Evans  */
300384fff8SJason Evans static void
310384fff8SJason Evans idle_setup(void *dummy)
320384fff8SJason Evans {
336caa8a15SJohn Baldwin #ifdef SMP
340bbc8826SJohn Baldwin 	struct pcpu *pc;
356caa8a15SJohn Baldwin #endif
366caa8a15SJohn Baldwin 	struct proc *p;
37e602ba25SJulian Elischer 	struct thread *td;
380384fff8SJason Evans 	int error;
390384fff8SJason Evans 
400384fff8SJason Evans #ifdef SMP
410bbc8826SJohn Baldwin 	SLIST_FOREACH(pc, &cpuhead, pc_allcpu) {
426caa8a15SJohn Baldwin 		error = kthread_create(idle_proc, NULL, &p,
43316ec49aSScott Long 		    RFSTOPPED | RFHIGHPID, 0, "idle: cpu%d", pc->pc_cpuid);
44079b7badSJulian Elischer 		pc->pc_idlethread = FIRST_THREAD_IN_PROC(p);
457e1f6dfeSJohn Baldwin 		if (pc->pc_curthread == NULL) {
460bbc8826SJohn Baldwin 			pc->pc_curthread = pc->pc_idlethread;
477e1f6dfeSJohn Baldwin 			pc->pc_idlethread->td_critnest = 0;
487e1f6dfeSJohn Baldwin 		}
490384fff8SJason Evans #else
506caa8a15SJohn Baldwin 		error = kthread_create(idle_proc, NULL, &p,
51316ec49aSScott Long 		    RFSTOPPED | RFHIGHPID, 0, "idle");
52079b7badSJulian Elischer 		PCPU_SET(idlethread, FIRST_THREAD_IN_PROC(p));
530384fff8SJason Evans #endif
540384fff8SJason Evans 		if (error)
550384fff8SJason Evans 			panic("idle_setup: kthread_create error %d\n", error);
560384fff8SJason Evans 
57e674d807SJohn Baldwin 		PROC_LOCK(p);
586caa8a15SJohn Baldwin 		p->p_flag |= P_NOLOAD;
59e674d807SJohn Baldwin 		mtx_lock_spin(&sched_lock);
60e602ba25SJulian Elischer 		td = FIRST_THREAD_IN_PROC(p);
61bf0acc27SJohn Baldwin 		TD_SET_CAN_RUN(td);
62b1ac98d8SJulian Elischer 		td->td_flags |= TDF_IDLETD;
63c086588fSJohn Baldwin 		td->td_priority = PRI_MAX_IDLE;
64e674d807SJohn Baldwin 		mtx_unlock_spin(&sched_lock);
65e674d807SJohn Baldwin 		PROC_UNLOCK(p);
666caa8a15SJohn Baldwin #ifdef SMP
670384fff8SJason Evans 	}
686caa8a15SJohn Baldwin #endif
690384fff8SJason Evans }
700384fff8SJason Evans 
710384fff8SJason Evans /*
7268d86cf1SPeter Wemm  * The actual idle process.
730384fff8SJason Evans  */
740384fff8SJason Evans static void
750384fff8SJason Evans idle_proc(void *dummy)
760384fff8SJason Evans {
77e602ba25SJulian Elischer 	struct proc *p;
7868d86cf1SPeter Wemm 	struct thread *td;
790384fff8SJason Evans 
80e602ba25SJulian Elischer 	td = curthread;
81e602ba25SJulian Elischer 	p = td->td_proc;
820384fff8SJason Evans 	for (;;) {
830384fff8SJason Evans 		mtx_assert(&Giant, MA_NOTOWNED);
840384fff8SJason Evans 
8568d86cf1SPeter Wemm 		while (sched_runnable() == 0)
86dc13e6dfSJohn Baldwin 			cpu_idle();
870384fff8SJason Evans 
889ed346baSBosko Milekic 		mtx_lock_spin(&sched_lock);
89bf0acc27SJohn Baldwin 		mi_switch(SW_VOL, NULL);
909ed346baSBosko Milekic 		mtx_unlock_spin(&sched_lock);
910384fff8SJason Evans 	}
920384fff8SJason Evans }
93