ia64/xen-unstable
changeset 17473:6cd0d4d1baa3
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@eu.citrix.com>
- 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@eu.citrix.com>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Wed Apr 16 10:06:34 2008 +0100 (2008-04-16) |
parents | e35a379e7fe9 |
children | 774e38a40d01 |
files | extras/mini-os/sched.c |
line diff
1.1 --- a/extras/mini-os/sched.c Wed Apr 16 10:06:19 2008 +0100 1.2 +++ b/extras/mini-os/sched.c Wed Apr 16 10:06:34 2008 +0100 1.3 @@ -70,62 +70,15 @@ void inline print_runqueue(void) 1.4 printk("\n"); 1.5 } 1.6 1.7 -/* Find the time when the next timeout expires. If this is more than 1.8 - 10 seconds from now, return 10 seconds from now. */ 1.9 -static s_time_t blocking_time(void) 1.10 -{ 1.11 - struct thread *thread; 1.12 - struct list_head *iterator; 1.13 - s_time_t min_wakeup_time; 1.14 - unsigned long flags; 1.15 - local_irq_save(flags); 1.16 - /* default-block the domain for 10 seconds: */ 1.17 - min_wakeup_time = NOW() + SECONDS(10); 1.18 - 1.19 - /* Thread list needs to be protected */ 1.20 - list_for_each(iterator, &idle_thread->thread_list) 1.21 - { 1.22 - thread = list_entry(iterator, struct thread, thread_list); 1.23 - if(!is_runnable(thread) && thread->wakeup_time != 0LL) 1.24 - { 1.25 - if(thread->wakeup_time < min_wakeup_time) 1.26 - { 1.27 - min_wakeup_time = thread->wakeup_time; 1.28 - } 1.29 - } 1.30 - } 1.31 - local_irq_restore(flags); 1.32 - return(min_wakeup_time); 1.33 -} 1.34 - 1.35 -/* Wake up all threads with expired timeouts. */ 1.36 -static void wake_expired(void) 1.37 -{ 1.38 - struct thread *thread; 1.39 - struct list_head *iterator; 1.40 - s_time_t now = NOW(); 1.41 - unsigned long flags; 1.42 - local_irq_save(flags); 1.43 - /* Thread list needs to be protected */ 1.44 - list_for_each(iterator, &idle_thread->thread_list) 1.45 - { 1.46 - thread = list_entry(iterator, struct thread, thread_list); 1.47 - if(!is_runnable(thread) && thread->wakeup_time != 0LL) 1.48 - { 1.49 - if(thread->wakeup_time <= now) 1.50 - wake(thread); 1.51 - } 1.52 - } 1.53 - local_irq_restore(flags); 1.54 -} 1.55 - 1.56 void schedule(void) 1.57 { 1.58 struct thread *prev, *next, *thread; 1.59 struct list_head *iterator; 1.60 unsigned long flags; 1.61 + 1.62 prev = current; 1.63 local_irq_save(flags); 1.64 + 1.65 if (in_callback) { 1.66 printk("Must not call schedule() from a callback\n"); 1.67 BUG(); 1.68 @@ -134,6 +87,45 @@ void schedule(void) 1.69 printk("Must not call schedule() with IRQs disabled\n"); 1.70 BUG(); 1.71 } 1.72 + 1.73 + do { 1.74 + /* Examine all threads. 1.75 + Find a runnable thread, but also wake up expired ones and find the 1.76 + time when the next timeout expires, else use 10 seconds. */ 1.77 + s_time_t now = NOW(); 1.78 + s_time_t min_wakeup_time = now + SECONDS(10); 1.79 + next = NULL; 1.80 + list_for_each(iterator, &idle_thread->thread_list) 1.81 + { 1.82 + thread = list_entry(iterator, struct thread, thread_list); 1.83 + if (!is_runnable(thread) && thread->wakeup_time != 0LL) 1.84 + { 1.85 + if (thread->wakeup_time <= now) 1.86 + wake(thread); 1.87 + else if (thread->wakeup_time < min_wakeup_time) 1.88 + min_wakeup_time = thread->wakeup_time; 1.89 + } 1.90 + if(is_runnable(thread)) 1.91 + { 1.92 + next = thread; 1.93 + /* Put this thread on the end of the list */ 1.94 + list_del(&thread->thread_list); 1.95 + list_add_tail(&thread->thread_list, &idle_thread->thread_list); 1.96 + break; 1.97 + } 1.98 + } 1.99 + if (next) 1.100 + break; 1.101 + /* block until the next timeout expires, or for 10 secs, whichever comes first */ 1.102 + block_domain(min_wakeup_time); 1.103 + /* handle pending events if any */ 1.104 + force_evtchn_callback(); 1.105 + } while(1); 1.106 + local_irq_restore(flags); 1.107 + /* Interrupting the switch is equivalent to having the next thread 1.108 + inturrupted at the return instruction. And therefore at safe point. */ 1.109 + if(prev != next) switch_threads(prev, next); 1.110 + 1.111 list_for_each(iterator, &exited_threads) 1.112 { 1.113 thread = list_entry(iterator, struct thread, thread_list); 1.114 @@ -144,24 +136,6 @@ void schedule(void) 1.115 xfree(thread); 1.116 } 1.117 } 1.118 - next = idle_thread; 1.119 - /* Thread list needs to be protected */ 1.120 - list_for_each(iterator, &idle_thread->thread_list) 1.121 - { 1.122 - thread = list_entry(iterator, struct thread, thread_list); 1.123 - if(is_runnable(thread)) 1.124 - { 1.125 - next = thread; 1.126 - /* Put this thread on the end of the list */ 1.127 - list_del(&thread->thread_list); 1.128 - list_add_tail(&thread->thread_list, &idle_thread->thread_list); 1.129 - break; 1.130 - } 1.131 - } 1.132 - local_irq_restore(flags); 1.133 - /* Interrupting the switch is equivalent to having the next thread 1.134 - inturrupted at the return instruction. And therefore at safe point. */ 1.135 - if(prev != next) switch_threads(prev, next); 1.136 } 1.137 1.138 struct thread* create_thread(char *name, void (*function)(void *), void *data) 1.139 @@ -267,32 +241,10 @@ void wake(struct thread *thread) 1.140 1.141 void idle_thread_fn(void *unused) 1.142 { 1.143 - s_time_t until; 1.144 threads_started = 1; 1.145 - unsigned long flags; 1.146 - struct list_head *iterator; 1.147 - struct thread *next, *thread; 1.148 - for(;;) 1.149 - { 1.150 + while (1) { 1.151 + block(current); 1.152 schedule(); 1.153 - next = NULL; 1.154 - local_irq_save(flags); 1.155 - list_for_each(iterator, &idle_thread->thread_list) 1.156 - { 1.157 - thread = list_entry(iterator, struct thread, thread_list); 1.158 - if(is_runnable(thread)) 1.159 - { 1.160 - next = thread; 1.161 - break; 1.162 - } 1.163 - } 1.164 - if (!next) { 1.165 - /* block until the next timeout expires, or for 10 secs, whichever comes first */ 1.166 - until = blocking_time(); 1.167 - block_domain(until); 1.168 - } 1.169 - local_irq_restore(flags); 1.170 - wake_expired(); 1.171 } 1.172 } 1.173