@@ -174,6 +174,7 @@ static struct task *schedule_edf(void)
174174 struct task * task ;
175175 struct task * future_task = NULL ;
176176 uint64_t current ;
177+ uint32_t flags ;
177178
178179 tracev_pipe ("edf" );
179180
@@ -196,41 +197,59 @@ static struct task *schedule_edf(void)
196197 } else {
197198 /* yes, run current task */
198199 task -> start = current ;
200+
201+ /* init task for running */
202+ wait_init (& task -> complete );
203+ spin_lock_irq (& sch -> lock , flags );
199204 task -> state = TASK_STATE_RUNNING ;
205+ list_item_del (& task -> list );
206+ spin_unlock_irq (& sch -> lock , flags );
207+
208+ /* now run task at correct run level */
200209 arch_run_task (task );
201210 }
202211
203212 /* tell caller about future task */
204213 return future_task ;
205214}
206215
207- #if 0 /* FIXME: is this needed ? */
208- /* delete task from scheduler */
209- static int schedule_task_del (struct task * task )
216+ /* cancel and delete task from scheduler - won't stop it if already running */
217+ int schedule_task_cancel (struct task * task , int wait )
210218{
211219 uint32_t flags ;
212220 int ret = 0 ;
213221
214222 tracev_pipe ("del" );
215223
216- /* add task to list */
217224 spin_lock_irq (& sch -> lock , flags );
218225
219- /* is task already running ? */
220- if (task -> state == TASK_STATE_RUNNING ) {
221- ret = - EAGAIN ;
222- goto out ;
226+ /* check current task state */
227+ switch (task -> state ) {
228+ case TASK_STATE_QUEUED :
229+ /* delete task */
230+ task -> state = TASK_STATE_CANCEL ;
231+ list_item_del (& task -> list );
232+ break ;
233+ case TASK_STATE_RUNNING :
234+ /* already running, nothing we can do about it atm */
235+ if (wait ) {
236+ task -> complete .timeout = SCHEDULE_TASK_MAX_TIME_SLICE ;
237+ spin_unlock_irq (& sch -> lock , flags );
238+ ret = wait_for_completion_timeout (& task -> complete );
239+ goto out ;
240+ } else {
241+ ret = - EBUSY ;
242+ }
243+ break ;
244+ default :
245+ break ;
223246 }
224247
225- list_item_del (& task -> list );
226- task -> state = TASK_STATE_COMPLETED ;
248+ spin_unlock_irq (& sch -> lock , flags );
227249
228250out :
229- spin_unlock_irq (& sch -> lock , flags );
230251 return ret ;
231252}
232- #endif
233-
234253
235254static int _schedule_task (struct task * task , uint64_t start , uint64_t deadline )
236255{
@@ -310,9 +329,11 @@ void schedule_task_complete(struct task *task)
310329 tracev_pipe ("com" );
311330
312331 spin_lock_irq (& sch -> lock , flags );
313- list_item_del (& task -> list );
314332 task -> state = TASK_STATE_COMPLETED ;
315333 spin_unlock_irq (& sch -> lock , flags );
334+
335+ /* tell any waiter that task has completed */
336+ wait_completed (& task -> complete );
316337}
317338
318339static void scheduler_run (void * unused )
0 commit comments