Skip to content

Commit 79fe681

Browse files
committed
Implement sched_dequeue_task() to dequeue task from ready queue
Previously, mo_task_dequeue() was only a stub and returned immediately without performing any operation. As a result, tasks remained in the ready queue after being dequeued, leading to potential scheduler inconsistencies. This change implements the full dequeue process: - Searches for the task node in the ready queue by task ID. - Maintains RR cursor consistency: the RR cursor should always point to a valid task node in the ready queue. When removing a task node, the cursor is advanced circularly to the next node. - Unlinks the task node using list_unlink(), which removes the node from the ready queue without freeing it. list_unlink() is used instead of list_remove() to avoid accidentally freeing kcb->task_current when the current running task is dequeued. - Updates and checks queue_counts: if the ready queue becomes empty, the RR cursor is set to NULL and the bitmap is cleared until a new task is enqueued.
1 parent 6f9412e commit 79fe681

File tree

1 file changed

+25
-7
lines changed

1 file changed

+25
-7
lines changed

kernel/task.c

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -381,16 +381,34 @@ static void sched_enqueue_task(tcb_t *task)
381381
return;
382382
}
383383

384-
/* Remove task from ready queues - state-based approach for compatibility */
385-
void sched_dequeue_task(tcb_t *task)
384+
/* Remove task from ready queue; return removed ready queue node */
385+
static list_node_t *sched_dequeue_task(tcb_t *task)
386386
{
387387
if (unlikely(!task))
388-
return;
388+
return NULL;
389389

390-
/* For tasks that need to be removed from ready state (suspended/cancelled),
391-
* we rely on the state change. The scheduler will skip non-ready tasks
392-
* when it encounters them during the round-robin traversal.
393-
*/
390+
uint8_t prio_level = task->prio_level;
391+
392+
/* For task that need to be removed from ready/running state, it need be
393+
* removed from corresponding ready queue. */
394+
list_t *rq = kcb->harts->ready_queues[prio_level];
395+
list_node_t *rq_node = list_foreach(rq, idcmp, (void *) (size_t) task->id);
396+
list_node_t **cursor = &kcb->harts->rr_cursors[prio_level];
397+
if (!rq_node)
398+
return NULL;
399+
400+
/* Safely move cursor to next task node. */
401+
if (rq_node == *cursor)
402+
*cursor = list_cnext(rq, *cursor);
403+
404+
list_unlink(rq, rq_node);
405+
406+
/* Update task count in ready queue */
407+
if (!--kcb->harts->queue_counts[prio_level]) {
408+
*cursor = NULL;
409+
BITMAP_CLEAN(task->prio_level);
410+
}
411+
return rq_node;
394412
}
395413

396414
/* Handle time slice expiration for current task */

0 commit comments

Comments
 (0)