[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] minios: simplify schedule()



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1208336794 -3600
# Node ID 6cd0d4d1baa3ac9484733f2defa928d347fa6cc9
# Parent  e35a379e7fe977627fb50f5ea694d6f940674180
minios: simplify schedule()
- Merge the search, wakeup, and timeout loops.
- Avoid unnecessarily switching to the idle thread.
- Perform stack release _after_ we get out of it.

Signed-off-by: Samuel Thibault <samuel.thibault@xxxxxxxxxxxxx>
---
 extras/mini-os/sched.c |  136 +++++++++++++++----------------------------------
 1 files changed, 44 insertions(+), 92 deletions(-)

diff -r e35a379e7fe9 -r 6cd0d4d1baa3 extras/mini-os/sched.c
--- a/extras/mini-os/sched.c    Wed Apr 16 10:06:19 2008 +0100
+++ b/extras/mini-os/sched.c    Wed Apr 16 10:06:34 2008 +0100
@@ -70,62 +70,15 @@ void inline print_runqueue(void)
     printk("\n");
 }
 
-/* Find the time when the next timeout expires. If this is more than
-   10 seconds from now, return 10 seconds from now. */
-static s_time_t blocking_time(void)
-{
-    struct thread *thread;
-    struct list_head *iterator;
-    s_time_t min_wakeup_time;
-    unsigned long flags;
-    local_irq_save(flags);
-    /* default-block the domain for 10 seconds: */
-    min_wakeup_time = NOW() + SECONDS(10);
-
-    /* Thread list needs to be protected */
-    list_for_each(iterator, &idle_thread->thread_list)
-    {
-        thread = list_entry(iterator, struct thread, thread_list);
-        if(!is_runnable(thread) && thread->wakeup_time != 0LL)
-        {
-            if(thread->wakeup_time < min_wakeup_time)
-            {
-                min_wakeup_time = thread->wakeup_time;
-            }
-        }
-    }
-    local_irq_restore(flags);
-    return(min_wakeup_time);
-}
-
-/* Wake up all threads with expired timeouts. */
-static void wake_expired(void)
-{
-    struct thread *thread;
-    struct list_head *iterator;
-    s_time_t now = NOW();
-    unsigned long flags;
-    local_irq_save(flags);
-    /* Thread list needs to be protected */
-    list_for_each(iterator, &idle_thread->thread_list)
-    {
-        thread = list_entry(iterator, struct thread, thread_list);
-        if(!is_runnable(thread) && thread->wakeup_time != 0LL)
-        {
-            if(thread->wakeup_time <= now)
-                wake(thread);
-        }
-    }
-    local_irq_restore(flags);
-}
-
 void schedule(void)
 {
     struct thread *prev, *next, *thread;
     struct list_head *iterator;
     unsigned long flags;
+
     prev = current;
     local_irq_save(flags); 
+
     if (in_callback) {
         printk("Must not call schedule() from a callback\n");
         BUG();
@@ -134,6 +87,45 @@ void schedule(void)
         printk("Must not call schedule() with IRQs disabled\n");
         BUG();
     }
+
+    do {
+        /* Examine all threads.
+           Find a runnable thread, but also wake up expired ones and find the
+           time when the next timeout expires, else use 10 seconds. */
+        s_time_t now = NOW();
+        s_time_t min_wakeup_time = now + SECONDS(10);
+        next = NULL;   
+        list_for_each(iterator, &idle_thread->thread_list)
+        {
+            thread = list_entry(iterator, struct thread, thread_list);
+            if (!is_runnable(thread) && thread->wakeup_time != 0LL)
+            {
+                if (thread->wakeup_time <= now)
+                    wake(thread);
+                else if (thread->wakeup_time < min_wakeup_time)
+                    min_wakeup_time = thread->wakeup_time;
+            }
+            if(is_runnable(thread)) 
+            {
+                next = thread;
+                /* Put this thread on the end of the list */
+                list_del(&thread->thread_list);
+                list_add_tail(&thread->thread_list, &idle_thread->thread_list);
+                break;
+            }
+        }
+        if (next)
+            break;
+        /* block until the next timeout expires, or for 10 secs, whichever 
comes first */
+        block_domain(min_wakeup_time);
+        /* handle pending events if any */
+        force_evtchn_callback();
+    } while(1);
+    local_irq_restore(flags);
+    /* Interrupting the switch is equivalent to having the next thread
+       inturrupted at the return instruction. And therefore at safe point. */
+    if(prev != next) switch_threads(prev, next);
+
     list_for_each(iterator, &exited_threads)
     {
         thread = list_entry(iterator, struct thread, thread_list);
@@ -144,24 +136,6 @@ void schedule(void)
             xfree(thread);
         }
     }
-    next = idle_thread;   
-    /* Thread list needs to be protected */
-    list_for_each(iterator, &idle_thread->thread_list)
-    {
-        thread = list_entry(iterator, struct thread, thread_list);
-        if(is_runnable(thread)) 
-        {
-            next = thread;
-            /* Put this thread on the end of the list */
-            list_del(&thread->thread_list);
-            list_add_tail(&thread->thread_list, &idle_thread->thread_list);
-            break;
-        }
-    }
-    local_irq_restore(flags);
-    /* Interrupting the switch is equivalent to having the next thread
-       inturrupted at the return instruction. And therefore at safe point. */
-    if(prev != next) switch_threads(prev, next);
 }
 
 struct thread* create_thread(char *name, void (*function)(void *), void *data)
@@ -267,32 +241,10 @@ void wake(struct thread *thread)
 
 void idle_thread_fn(void *unused)
 {
-    s_time_t until;
     threads_started = 1;
-    unsigned long flags;
-    struct list_head *iterator;
-    struct thread *next, *thread;
-    for(;;)
-    {
-        schedule();
-        next = NULL;
-        local_irq_save(flags);
-        list_for_each(iterator, &idle_thread->thread_list)
-        {
-            thread = list_entry(iterator, struct thread, thread_list);
-            if(is_runnable(thread)) 
-            {
-                next = thread;
-                break;
-            }
-        }
-        if (!next) {
-            /* block until the next timeout expires, or for 10 secs, whichever 
comes first */
-            until = blocking_time();
-            block_domain(until);
-        }
-        local_irq_restore(flags);
-        wake_expired();
+    while (1) {
+        block(current);
+        schedule();
     }
 }
 

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.