Skip to content

Commit 202b115

Browse files
committed
Add enqueue and dequeue paths to task operation APIs
Previously, task operation APIs such as sched_wakeup_task() only updated the task state, which was sufficient when scheduling relied on the global task list. With the scheduler now selecting runnable tasks from ready_queue[] per priority level, state changes alone are insufficient. To support the new scheduler and to prevent selection of tasks that have already left the runnable set, explicit enqueue and dequeue paths are required when task state transitions cross the runnable boundary: In ready-queue set: {TASK_RUNNING, TASK_READY} Not in ready-queue set: {all other states} This change updates task operation APIs to include queue insertion and removal logic according to their semantics. In general, queue operations are performed by invoking existing helper functions sched_enqueue_task() and sched_dequeue_task(). The modified APIs include: - sched_wakeup_task(): avoid enqueueing a task that is already running by treating TASK_RUNNING as part of the runnable set complement. - mo_task_cancel(): dequeue TASK_READY tasks from ready_queue[] before cancelling, ensuring removed tasks are not scheduled again. - mo_task_delay(): runnable boundary transition only ("TASK_RUNNING → TASK_BLOCKED"), no queue insertion for non-runnable tasks. - mo_task_suspend(): supports both TASK_RUNNING and TASK_READY ("TASK_RUNNING/TASK_READY → TASK_SUSPENDED"), dequeue before suspend when necessary. - mo_task_resume(): only for suspended tasks ("TASK_SUSPENDED → TASK_READY"), enqueue into ready_queue[] on resume. - _sched_block(): runnable boundary transition only ("TASK_RUNNING → TASK_BLOCKED"), dequeue without memory free. This change keeps task state transition consistent to the ready queue semantic.
1 parent 95d9f81 commit 202b115

File tree

1 file changed

+21
-13
lines changed

1 file changed

+21
-13
lines changed

kernel/task.c

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -439,20 +439,15 @@ void sched_tick_current_task(void)
439439
}
440440
}
441441

442-
/* Task wakeup - simple state transition approach */
442+
/* Task wakeup and enqueue into ready queue */
443443
void sched_wakeup_task(tcb_t *task)
444444
{
445445
if (unlikely(!task))
446446
return;
447447

448-
/* Mark task as ready - scheduler will find it during round-robin traversal
449-
*/
450-
if (task->state != TASK_READY) {
451-
task->state = TASK_READY;
452-
/* Ensure task has time slice */
453-
if (task->time_slice == 0)
454-
task->time_slice = get_priority_timeslice(task->prio_level);
455-
}
448+
/* Enqueue task into ready queue */
449+
if (task->state != TASK_READY && task->state != TASK_RUNNING)
450+
sched_enqueue_task(task);
456451
}
457452

458453
/* Efficient Round-Robin Task Selection with O(n) Complexity
@@ -864,6 +859,10 @@ int32_t mo_task_cancel(uint16_t id)
864859
}
865860
}
866861

862+
/* Remove from ready queue */
863+
if (tcb->state == TASK_READY)
864+
sched_dequeue_task(tcb);
865+
867866
CRITICAL_LEAVE();
868867

869868
/* Free memory outside critical section */
@@ -893,7 +892,9 @@ void mo_task_delay(uint16_t ticks)
893892

894893
tcb_t *self = kcb->task_current->data;
895894

896-
/* Set delay and blocked state - scheduler will skip blocked tasks */
895+
/* Set delay and blocked state, dequeue from ready queue */
896+
sched_dequeue_task(self);
897+
897898
self->delay = ticks;
898899
self->state = TASK_BLOCKED;
899900
NOSCHED_LEAVE();
@@ -920,6 +921,11 @@ int32_t mo_task_suspend(uint16_t id)
920921
return ERR_TASK_CANT_SUSPEND;
921922
}
922923

924+
/* Remove task node from ready queue if task is in ready queue
925+
* (TASK_RUNNING/TASK_READY).*/
926+
if (task->state == TASK_READY || task->state == TASK_RUNNING)
927+
sched_dequeue_task(task);
928+
923929
task->state = TASK_SUSPENDED;
924930
bool is_current = (kcb->task_current->data == task);
925931

@@ -948,9 +954,8 @@ int32_t mo_task_resume(uint16_t id)
948954
CRITICAL_LEAVE();
949955
return ERR_TASK_CANT_RESUME;
950956
}
951-
952-
/* mark as ready - scheduler will find it */
953-
task->state = TASK_READY;
957+
/* Enqueue resumed task into ready queue */
958+
sched_enqueue_task(task);
954959

955960
CRITICAL_LEAVE();
956961
return ERR_OK;
@@ -1072,6 +1077,9 @@ void _sched_block(queue_t *wait_q)
10721077

10731078
tcb_t *self = kcb->task_current->data;
10741079

1080+
/* Remove node from ready queue */
1081+
sched_dequeue_task(self);
1082+
10751083
if (queue_enqueue(wait_q, self) != 0)
10761084
panic(ERR_SEM_OPERATION);
10771085

0 commit comments

Comments
 (0)