static void scheduler(void *dummy) { struct scheduler_info info; struct proc *p; KKASSERT(!IN_CRITICAL_SECT(curthread)); loop: scheduler_notify = 0; /* * Don't try to swap anything in if we are low on memory. */ if (vm_page_count_severe()) { vm_wait(0); goto loop; } /* * Look for a good candidate to wake up * * XXX we should make the schedule thread pcpu and then use a * segmented allproc scan. */ info.pp = NULL; info.ppri = INT_MIN; allproc_scan(scheduler_callback, &info, 0); /* * Nothing to do, back to sleep for at least 1/10 of a second. If * we are woken up, immediately process the next request. If * multiple requests have built up the first is processed * immediately and the rest are staggered. */ if ((p = info.pp) == NULL) { tsleep(&proc0, 0, "nowork", hz / 10); if (scheduler_notify == 0) tsleep(&scheduler_notify, 0, "nowork", 0); goto loop; } /* * Fault the selected process in, then wait for a short period of * time and loop up. * * XXX we need a heuristic to get a measure of system stress and * then adjust our stagger wakeup delay accordingly. */ lwkt_gettoken(&p->p_token); faultin(p); p->p_swtime = 0; lwkt_reltoken(&p->p_token); PRELE(p); tsleep(&proc0, 0, "swapin", hz / 10); goto loop; }
kprintf("%s", (char *)data); } SYSINIT(announce, SI_BOOT1_COPYRIGHT, SI_ORDER_FIRST, print_caddr_t, copyright) /* * Leave the critical section that protected us from spurious interrupts * so device probes work. */ static void leavecrit(void *dummy __unused) { MachIntrABI.stabilize(); cpu_enable_intr(); MachIntrABI.cleanup(); crit_exit(); KKASSERT(!IN_CRITICAL_SECT(curthread)); if (bootverbose) kprintf("Leaving critical section, allowing interrupts\n"); } SYSINIT(leavecrit, SI_BOOT2_LEAVE_CRIT, SI_ORDER_ANY, leavecrit, NULL) /* * This is called after the threading system is up and running, * including the softclock, clock interrupts, and SMP. */ static void tsleepworks(void *dummy __unused) { tsleep_now_works = 1; }