diff options
author | Richard Braun <rbraun@sceen.net> | 2013-05-15 02:11:48 +0200 |
---|---|---|
committer | Richard Braun <rbraun@sceen.net> | 2013-05-15 02:11:48 +0200 |
commit | b6555e76c36170e60e09125c0bcd7b997f68e4a9 (patch) | |
tree | 2f3eef6d34bbed106d3d468ad9d9109714fb1dff | |
parent | ec41b64a5b5601db55946d18fc00ede44d242d63 (diff) |
kern/thread: rework idle loop
The upcoming lockless synchronization implementation requires the idle loop
to report when it's about to enter/leave the idle state. Preemption must be
disabled to accomplish that.
-rw-r--r-- | kern/thread.c | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/kern/thread.c b/kern/thread.c index ba9bb54e..fa61976f 100644 --- a/kern/thread.c +++ b/kern/thread.c @@ -1622,10 +1622,28 @@ thread_setup_balancer(struct thread_runq *runq) static void thread_idle(void *arg) { - (void)arg; + struct thread *self; + unsigned int cpu; + + self = thread_self(); + cpu = thread_runq_id(arg); + + for (;;) { + thread_preempt_disable(); + + for (;;) { + cpu_intr_disable(); - for (;;) - cpu_idle(); + if (thread_test_flag(self, THREAD_RESCHEDULE)) { + cpu_intr_enable(); + break; + } + + cpu_idle(); + } + + thread_preempt_enable(); + } } static void __init @@ -1650,7 +1668,7 @@ thread_setup_idler(struct thread_runq *runq) attr.task = kernel_task; attr.name = name; attr.policy = THREAD_SCHED_POLICY_IDLE; - thread_init(idler, stack, &attr, thread_idle, NULL); + thread_init(idler, stack, &attr, thread_idle, runq); /* An idler thread needs special tuning */ idler->state = THREAD_RUNNING; |