Diff markup
001 001
002 002
003 003
004 004
005 005
006 006
007 007
008 008
009 009
010 010
011 011
012 012
013 013
014 014
015 015
016 016
017 017
018 018
019 #include <sos/errno.h> 019 #include <sos/errno.h>
020 #include <sos/klibc.h> 020 #include <sos/klibc.h>
021 #include <sos/assert.h> 021 #include <sos/assert.h>
022 #include <sos/list.h> 022 #include <sos/list.h>
023 #include <sos/calcload.h> <<
024 023
025 #include "sched.h" 024 #include "sched.h"
026 025
027 026
028 027
029 028
030 !! 029
031 !! 030
032 !! 031
033 !! 032
034 !! 033
035 <<
036 034
037 struct sos_sched_queue !! 035 static struct
038 { 036 {
039 unsigned int nr_threads; 037 unsigned int nr_threads;
040 struct sos_thread *thread_list[SOS_SCHED_NUM !! 038 struct sos_thread *thread_list;
041 }; !! 039 } ready_queue;
042 <<
043 <<
044 <<
045 <<
046 <<
047 <<
048 <<
049 static struct sos_sched_queue *active_queue, * <<
050 <<
051 <<
052 <<
053 <<
054 <<
055 static struct sos_sched_queue sched_queue[2]; <<
056 <<
057 <<
058 <<
059 <<
060 <<
061 struct sos_time time_slice[SOS_SCHED_NUM_PRIO] <<
062 040
063 041
064 sos_ret_t sos_sched_subsystem_setup() 042 sos_ret_t sos_sched_subsystem_setup()
065 { 043 {
066 sos_sched_priority_t prio; !! 044 memset(& ready_queue, 0x0, sizeof(ready_queue));
067 <<
068 memset(sched_queue, 0x0, sizeof(sched_queue) <<
069 active_queue = & sched_queue[0]; <<
070 expired_queue = & sched_queue[1]; <<
071 <<
072 <<
073 for (prio = SOS_SCHED_PRIO_TS_HIGHEST ; <<
074 prio <= SOS_SCHED_PRIO_TS_LOWEST ; <<
075 prio ++) <<
076 { <<
077 unsigned int ms; <<
078 ms = SOS_TIME_SLICE_MIN <<
079 + (SOS_TIME_SLICE_MAX - SOS_TIME_SL <<
080 * (prio - SOS_SCHED_PRIO_TS_HIGHE <<
081 / (SOS_SCHED_PRIO_TS_LOWEST - SOS <<
082 time_slice[prio].sec = ms / 1000; <<
083 time_slice[prio].nanosec = 1000000UL * ( <<
084 } <<
085 045
086 return SOS_OK; 046 return SOS_OK;
087 } 047 }
088 048
089 049
090 050
091 051
092 052
093 053
094 054
095 055
096 056
097 static sos_ret_t add_in_ready_queue(struct sos !! 057 static sos_ret_t add_in_ready_queue(struct sos_thread *thr,
098 struct sos <<
099 sos_bool_t 058 sos_bool_t insert_at_tail)
100 { 059 {
101 sos_sched_priority_t prio; <<
102 060
103 SOS_ASSERT_FATAL( (SOS_THR_CREATED == thr->s 061 SOS_ASSERT_FATAL( (SOS_THR_CREATED == thr->state)
104 || (SOS_THR_RUNNING == thr 062 || (SOS_THR_RUNNING == thr->state)
105 || (SOS_THR_BLOCKED == thr 063 || (SOS_THR_BLOCKED == thr->state) );
106 064
107 065
108 prio = sos_thread_get_priority(thr); <<
109 if (insert_at_tail) 066 if (insert_at_tail)
110 list_add_tail_named(q->thread_list[prio], !! 067 list_add_tail_named(ready_queue.thread_list, thr,
111 ready.rdy_prev, ready. 068 ready.rdy_prev, ready.rdy_next);
112 else 069 else
113 list_add_head_named(q->thread_list[prio], !! 070 list_add_head_named(ready_queue.thread_list, thr,
114 ready.rdy_prev, ready. 071 ready.rdy_prev, ready.rdy_next);
115 thr->ready.rdy_queue = q; !! 072 ready_queue.nr_threads ++;
116 q->nr_threads ++; <<
117 073
118 074
119 thr->state = SOS_THR_READY; 075 thr->state = SOS_THR_READY;
120 076
121 return SOS_OK; 077 return SOS_OK;
122 } 078 }
123 079
124 080
125 sos_ret_t sos_sched_set_ready(struct sos_threa 081 sos_ret_t sos_sched_set_ready(struct sos_thread *thr)
126 { 082 {
127 sos_ret_t retval; 083 sos_ret_t retval;
128 084
129 085
130 if (SOS_THR_READY == thr->state) 086 if (SOS_THR_READY == thr->state)
131 return SOS_OK; 087 return SOS_OK;
132 088
133 !! 089
134 memset(& thr->running.user_time_spent_in_sli !! 090 retval = add_in_ready_queue(thr, TRUE);
135 <<
136 if (SOS_SCHED_PRIO_IS_RT(sos_thread_get_prio <<
137 { <<
138 <<
139 retval = add_in_ready_queue(active_queue <<
140 } <<
141 else <<
142 { <<
143 <<
144 retval = add_in_ready_queue(expired_queu <<
145 } <<
146 091
147 return retval; 092 return retval;
148 } 093 }
149 094
150 095
151 sos_ret_t sos_sched_change_priority(struct sos <<
152 sos_sched_ <<
153 { <<
154 struct sos_thread *thread_list; <<
155 SOS_ASSERT_FATAL(SOS_THR_READY == thr->state <<
156 <<
157 <<
158 thread_list <<
159 = thr->ready.rdy_queue->thread_list[sos_th <<
160 <<
161 list_delete_named(thread_list, thr, ready.rd <<
162 <<
163 <<
164 thread_list = thr->ready.rdy_queue->thread_l <<
165 list_add_tail_named(thread_list, thr, ready. <<
166 thr->ready.rdy_queue->thread_list[priority] <<
167 <<
168 return SOS_OK; <<
169 } <<
170 <<
171 <<
172 <<
173 <<
174 <<
175 <<
176 static sos_bool_t <<
177 thread_expired_its_quantuum(struct sos_thread <<
178 { <<
179 sos_sched_priority_t prio = sos_thread_get_p <<
180 <<
181 <<
182 if (SOS_SCHED_PRIO_IS_RT(prio)) <<
183 return FALSE; <<
184 <<
185 <<
186 <<
187 <<
188 if (sos_time_cmp(& thr->running.user_time_sp <<
189 & time_slice[prio]) >= 0) <<
190 return TRUE; <<
191 <<
192 return FALSE; <<
193 } <<
194 <<
195 <<
196 struct sos_thread * sos_reschedule(struct sos_ 096 struct sos_thread * sos_reschedule(struct sos_thread *current_thread,
197 sos_bool_t 097 sos_bool_t do_yield)
198 { 098 {
199 sos_sched_priority_t prio; <<
200 <<
201 <<
202 <<
203 if (thread_expired_its_quantuum(current_thre <<
204 { <<
205 <<
206 memset(& current_thread->running.user_ti <<
207 0x0, sizeof(struct sos_time)); <<
208 <<
209 do_yield = TRUE; <<
210 } <<
211 099
212 if (SOS_THR_ZOMBIE == current_thread->state) 100 if (SOS_THR_ZOMBIE == current_thread->state)
213 { 101 {
214 102
215 103
216 104
217 } 105 }
218 else if (SOS_THR_BLOCKED != current_thread-> 106 else if (SOS_THR_BLOCKED != current_thread->state)
219 { 107 {
220 108
221 109
222 if (do_yield) 110 if (do_yield)
223 { !! 111
224 !! 112 add_in_ready_queue(current_thread, TRUE);
225 if (SOS_SCHED_PRIO_IS_RT(sos_thread_ <<
226 add_in_ready_queue(active_queue, c <<
227 else <<
228 add_in_ready_queue(expired_queue, <<
229 } <<
230 else 113 else
231 { !! 114
232 !! 115 add_in_ready_queue(current_thread, FALSE);
233 add_in_ready_queue(active_queue, cur <<
234 } <<
235 } 116 }
236 117
237 !! 118
238 !! 119 if (ready_queue.nr_threads > 0)
239 if (active_queue->nr_threads <= 0) <<
240 { <<
241 <<
242 struct sos_sched_queue *q; <<
243 q = active_queue; <<
244 active_queue = expired_queue; <<
245 expired_queue = q; <<
246 } <<
247 <<
248 <<
249 <<
250 for (prio = SOS_SCHED_PRIO_HIGHEST ; prio <= <<
251 { 120 {
252 struct sos_thread *next_thr; 121 struct sos_thread *next_thr;
253 122
254 if (list_is_empty_named(active_queue->th <<
255 ready.rdy_prev, <<
256 continue; <<
257 <<
258 123
259 next_thr = list_pop_head_named(active_qu !! 124 next_thr = list_pop_head_named(ready_queue.thread_list,
260 ready.rdy 125 ready.rdy_prev, ready.rdy_next);
261 active_queue->nr_threads --; !! 126 ready_queue.nr_threads --;
262 127
263 return next_thr; 128 return next_thr;
264 } 129 }
265 130
266 <<
267 SOS_FATAL_ERROR("No kernel thread ready ?!") 131 SOS_FATAL_ERROR("No kernel thread ready ?!");
268 return NULL; 132 return NULL;
269 } <<
270 <<
271 <<
272 sos_ret_t sos_sched_do_timer_tick() <<
273 { <<
274 struct sos_thread *interrupted_thread = sos_ <<
275 struct sos_time tick_duration; <<
276 sos_bool_t cur_is_user; <<
277 sos_ui32_t nb_user_ready = 0; <<
278 sos_ui32_t nb_kernel_ready = 0; <<
279 int prio; <<
280 <<
281 sos_time_get_tick_resolution(& tick_duration <<
282 <<
283 <<
284 if (sos_cpu_context_is_in_user_mode(interrup <<
285 { <<
286 cur_is_user = TRUE; <<
287 <<
288 <<
289 sos_time_inc(& interrupted_thread->rusag <<
290 & tick_duration); <<
291 <<
292 <<
293 sos_time_inc(& interrupted_thread->runni <<
294 & tick_duration); <<
295 } <<
296 else <<
297 { <<
298 cur_is_user = FALSE; <<
299 <<
300 <<
301 sos_time_inc(& interrupted_thread->rusag <<
302 & tick_duration); <<
303 } <<
304 <<
305 <<
306 <<
307 for (prio = SOS_SCHED_PRIO_HIGHEST ; prio <= <<
308 { <<
309 struct sos_thread *thr; <<
310 int nb_thrs; <<
311 <<
312 list_foreach_forward_named(active_queue- <<
313 thr, nb_thrs, <<
314 ready.rdy_pre <<
315 { <<
316 if (sos_cpu_context_is_in_user_mode( <<
317 nb_user_ready ++; <<
318 else <<
319 nb_kernel_ready ++; <<
320 } <<
321 <<
322 list_foreach_forward_named(expired_queue <<
323 thr, nb_thrs, <<
324 ready.rdy_pre <<
325 { <<
326 if (sos_cpu_context_is_in_user_mode( <<
327 nb_user_ready ++; <<
328 else <<
329 nb_kernel_ready ++; <<
330 } <<
331 } <<
332 <<
333 sos_load_do_timer_tick(cur_is_user, <<
334 nb_user_ready, <<
335 nb_kernel_ready); <<
336 <<
337 return SOS_OK; <<
338 } 133 }