1#include <asm.h>
2#include <enforce.h>
3#include <irq/idt.h>
4#include <sch/sched.h>
5#include <smp/core.h>
6#include <smp/smp.h>
7#include <sync/rcu.h>
8#include <thread/dpc.h>
9#include <thread/workqueue.h>
10
11void scheduler_idle_main(void *nop) {
12 cc_ignore(nop);
13 struct scheduler *sched = global.schedulers[smp_id_raw()];
14
15 bool woken = false;
16
17 while (true) {
18 irq_disable();
19
20 smp_boot_fence_park();
21
22 rcu_idle_exit(); /* For potential NMI events */
23
24 if (scheduler_mark_self_needs_resched(false) ||
25 sched->total_thread_count > 0 ||
26 sched->completed_rbt.root != NULL) {
27 irq_enable();
28 scheduler_yield();
29 continue;
30 }
31
32 /* Go yield to try to pick up some work */
33 if (woken && atomic_load(&scheduler_data.total_threads) > 0) {
34 woken = false;
35 irq_enable();
36 scheduler_yield();
37 continue;
38 }
39
40 rcu_idle_enter();
41 cpu_idle();
42 woken = true;
43 }
44}
45