summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Braun <rbraun@sceen.net>2013-05-15 02:11:48 +0200
committerRichard Braun <rbraun@sceen.net>2013-05-15 02:11:48 +0200
commitb6555e76c36170e60e09125c0bcd7b997f68e4a9 (patch)
tree2f3eef6d34bbed106d3d468ad9d9109714fb1dff
parentec41b64a5b5601db55946d18fc00ede44d242d63 (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.c26
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;