@@ -98,6 +98,7 @@ static inline struct task *edf_get_next(uint64_t current,
9898 struct list_item * clist ;
9999 struct list_item * tlist ;
100100 uint64_t next_delta = UINT64_MAX ;
101+ int next_priority = TASK_PRI_LOW ;
101102 uint64_t delta ;
102103 uint64_t deadline ;
103104 int reschedule = 0 ;
@@ -126,23 +127,31 @@ static inline struct task *edf_get_next(uint64_t current,
126127 /* include the length of task in deadline calc */
127128 deadline = task -> deadline - task -> max_rtime ;
128129
129- /* get earliest deadline */
130130 if (current < deadline ) {
131131 delta = deadline - current ;
132132
133- if (delta < next_delta ) {
133+ /* get highest priority */
134+ if (task -> priority < next_priority ) {
135+ next_priority = task -> priority ;
134136 next_delta = delta ;
135137 next_task = task ;
138+ } else if (task -> priority == next_priority ) {
139+ /* get earliest deadline */
140+ if (delta < next_delta ) {
141+ next_delta = delta ;
142+ next_task = task ;
143+ }
136144 }
137-
138145 } else {
139146 /* missed scheduling - will be rescheduled */
140147 trace_pipe ("ed!" );
141148
142149 /* have we already tried to rescheule ? */
143- if (reschedule ++ )
150+ if (!reschedule ) {
151+ reschedule ++ ;
152+ trace_pipe ("edr" );
144153 edf_reschedule (task , current );
145- else {
154+ } else {
146155 /* reschedule failed */
147156 list_item_del (& task -> list );
148157 task -> state = TASK_STATE_CANCEL ;
@@ -170,9 +179,11 @@ static uint64_t sch_work(void *data, uint64_t delay)
170179 */
171180static struct task * schedule_edf (void )
172181{
182+ struct schedule_data * sch = * arch_schedule_get ();
173183 struct task * task ;
174184 struct task * future_task = NULL ;
175185 uint64_t current ;
186+ uint32_t flags ;
176187
177188 tracev_pipe ("edf" );
178189
@@ -195,42 +206,46 @@ static struct task *schedule_edf(void)
195206 } else {
196207 /* yes, run current task */
197208 task -> start = current ;
209+
210+ /* init task for running */
211+ wait_init (& task -> complete );
212+ spin_lock_irq (& sch -> lock , flags );
198213 task -> state = TASK_STATE_RUNNING ;
214+ list_item_del (& task -> list );
215+ spin_unlock_irq (& sch -> lock , flags );
216+
217+ /* now run task at correct run level */
199218 run_task (task );
200219 }
201220
202221 /* tell caller about future task */
203222 return future_task ;
204223}
205224
206- #if 0 /* FIXME: is this needed ? */
207- /* delete task from scheduler */
208- static int schedule_task_del (struct task * task )
225+ /* cancel and delete task from scheduler - won't stop it if already running */
226+ int schedule_task_cancel (struct task * task )
209227{
210228 struct schedule_data * sch = * arch_schedule_get ();
211229 uint32_t flags ;
212230 int ret = 0 ;
213231
214232 tracev_pipe ("del" );
215233
216- /* add task to list */
217234 spin_lock_irq (& sch -> lock , flags );
218235
219- /* is task already running ? */
220- if (task -> state == TASK_STATE_RUNNING ) {
221- ret = - EAGAIN ;
222- goto out ;
236+ /* check current task state, delete it if it is queued
237+ * if it is already running, nothing we can do about it atm
238+ */
239+ if (task -> state == TASK_STATE_QUEUED ) {
240+ /* delete task */
241+ task -> state = TASK_STATE_CANCEL ;
242+ list_item_del (& task -> list );
223243 }
224244
225- list_item_del (& task -> list );
226- task -> state = TASK_STATE_COMPLETED ;
227-
228- out :
229245 spin_unlock_irq (& sch -> lock , flags );
246+
230247 return ret ;
231248}
232- #endif
233-
234249
235250static int _schedule_task (struct task * task , uint64_t start , uint64_t deadline )
236251{
@@ -249,6 +264,13 @@ static int _schedule_task(struct task *task, uint64_t start, uint64_t deadline)
249264 return 0 ;
250265 }
251266
267+ /* is task already running ? - not enough MIPS to complete ? */
268+ if (task -> state == TASK_STATE_QUEUED ) {
269+ trace_pipe ("tsq" );
270+ spin_unlock_irq (& sch -> lock , flags );
271+ return 0 ;
272+ }
273+
252274 /* get the current time */
253275 current = platform_timer_get (platform_timer );
254276
@@ -312,9 +334,11 @@ void schedule_task_complete(struct task *task)
312334 tracev_pipe ("com" );
313335
314336 spin_lock_irq (& sch -> lock , flags );
315- list_item_del (& task -> list );
316337 task -> state = TASK_STATE_COMPLETED ;
317338 spin_unlock_irq (& sch -> lock , flags );
339+
340+ /* tell any waiter that task has completed */
341+ wait_completed (& task -> complete );
318342}
319343
320344static void scheduler_run (void * unused )
0 commit comments