Skip to content

Commit b00f4b3

Browse files
committed
Integrate enqueue/dequeue logic into task control APIs
This commit integrates the refactored ready-queue enqueue and dequeue logic into all task state transition APIs, completing the scheduler behavior for runnable <-> non-runnable transitions. APIs with dequeue logic added: - _sched_block(): TASK_RUNNING -> TASK_BLOCKED - mo_task_delay(): TASK_RUNNING -> TASK_BLOCKED - mo_task_cancel(): dequeue if the task is currently in the ready queue; the ready-queue node is now released inside the same critical section as the dequeue to avoid race conditions where a dequeued task would never return and its node would never be freed. - mo_task_suspend(): dequeue if the task is currently runnable APIs with enqueue logic added: - sched_wakeup_task(): enqueue the task when it becomes runnable - mo_task_resume(): enqueue the task when transitioning from suspended to runnable These updates ensure the task control APIs properly drive ready- queue updates and maintain correct scheduler semantics across all state transitions.
1 parent 6a8d8aa commit b00f4b3

File tree

1 file changed

+28
-13
lines changed

1 file changed

+28
-13
lines changed

kernel/task.c

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -434,20 +434,16 @@ void sched_tick_current_task(void)
434434
}
435435
}
436436

437-
/* Task wakeup - simple state transition approach */
437+
/* Task wakeup and enqueue into ready queue */
438438
void sched_wakeup_task(tcb_t *task)
439439
{
440440
if (unlikely(!task))
441441
return;
442442

443-
/* Mark task as ready - scheduler will find it during round-robin traversal
443+
/* Enqueue task into ready queue for scheduler selection by rr_cursor.
444444
*/
445-
if (task->state != TASK_READY) {
446-
task->state = TASK_READY;
447-
/* Ensure task has time slice */
448-
if (task->time_slice == 0)
449-
task->time_slice = get_priority_timeslice(task->prio_level);
450-
}
445+
if (task->state != TASK_READY && task->state != TASK_RUNNING)
446+
sched_enqueue_task(task);
451447
}
452448

453449
/* Efficient Round-Robin Task Selection with O(n) Complexity
@@ -721,6 +717,12 @@ int32_t mo_task_cancel(uint16_t id)
721717
}
722718
}
723719

720+
/* Remove from ready queue */
721+
if (tcb->state == TASK_READY) {
722+
list_node_t *rq_node = sched_dequeue_task(tcb);
723+
free(rq_node);
724+
}
725+
724726
CRITICAL_LEAVE();
725727

726728
/* Free memory outside critical section */
@@ -751,7 +753,10 @@ void mo_task_delay(uint16_t ticks)
751753

752754
tcb_t *self = kcb->task_current->data;
753755

754-
/* Set delay and blocked state - scheduler will skip blocked tasks */
756+
/* Set delay and blocked state, dequeue from ready queue */
757+
list_node_t *rq_node = sched_dequeue_task(self);
758+
free(rq_node);
759+
755760
self->delay = ticks;
756761
self->state = TASK_BLOCKED;
757762
NOSCHED_LEAVE();
@@ -778,8 +783,15 @@ int32_t mo_task_suspend(uint16_t id)
778783
return ERR_TASK_CANT_SUSPEND;
779784
}
780785

786+
/* Remove task node from ready queue if task is in ready queue
787+
* (TASK_RUNNING/TASK_READY).*/
788+
if (task->state == TASK_READY || task->state == TASK_RUNNING) {
789+
list_node_t *rq_node = sched_dequeue_task(task);
790+
free(rq_node);
791+
}
792+
781793
task->state = TASK_SUSPENDED;
782-
bool is_current = (kcb->task_current == node);
794+
bool is_current = (kcb->task_current->data == task);
783795

784796
CRITICAL_LEAVE();
785797

@@ -806,9 +818,8 @@ int32_t mo_task_resume(uint16_t id)
806818
CRITICAL_LEAVE();
807819
return ERR_TASK_CANT_RESUME;
808820
}
809-
810-
/* mark as ready - scheduler will find it */
811-
task->state = TASK_READY;
821+
/* Enqueue resumed task into ready queue */
822+
sched_enqueue_task(task);
812823

813824
CRITICAL_LEAVE();
814825
return ERR_OK;
@@ -922,6 +933,10 @@ void _sched_block(queue_t *wait_q)
922933

923934
tcb_t *self = kcb->task_current->data;
924935

936+
/* Remove node from ready queue and free it */
937+
list_node_t *node = sched_dequeue_task(self);
938+
free(node);
939+
925940
if (queue_enqueue(wait_q, self) != 0)
926941
panic(ERR_SEM_OPERATION);
927942

0 commit comments

Comments
 (0)