Skip to content

Commit 2957225

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 75b4eeb commit 2957225

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
@@ -386,16 +386,34 @@ static void sched_enqueue_task(tcb_t *task)
386386
return;
387387
}
388388

389-
/* Remove task from ready queues - state-based approach for compatibility */
390-
void sched_dequeue_task(tcb_t *task)
389+
/* Remove task from ready queue; return removed ready queue node */
390+
static __attribute__((unused)) list_node_t *sched_dequeue_task(tcb_t *task)
391391
{
392392
if (unlikely(!task))
393-
return;
393+
return NULL;
394394

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

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

0 commit comments

Comments
 (0)