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