@@ -76,7 +76,7 @@ static const uint8_t priority_timeslices[TASK_PRIORITY_LEVELS] = {
7676 TASK_TIMESLICE_IDLE /* Priority 7: Idle */
7777};
7878
79- /* Mark task as ready (state-based) */
79+ /* Enqueue task into ready queue */
8080static void sched_enqueue_task (tcb_t * task );
8181
8282/* Utility and Validation Functions */
@@ -343,29 +343,67 @@ void _yield(void) __attribute__((weak, alias("yield")));
343343 * practical performance with strong guarantees for fairness and reliability.
344344 */
345345
346- /* Add task to ready state - simple state-based approach */
346+ /* Enqueue task into ready queue */
347347static void sched_enqueue_task (tcb_t * task )
348348{
349349 if (unlikely (!task ))
350350 return ;
351351
352+ uint8_t prio_level = task -> prio_level ;
353+
352354 /* Ensure task has appropriate time slice for its priority */
353- task -> time_slice = get_priority_timeslice (task -> prio_level );
355+ task -> time_slice = get_priority_timeslice (prio_level );
354356 task -> state = TASK_READY ;
355357
356- /* Task selection is handled directly through the master task list */
358+ list_t * * rq = & kcb -> ready_queues [prio_level ];
359+ list_node_t * * cursor = & kcb -> rr_cursors [prio_level ];
360+
361+ if (!* rq )
362+ * rq = list_create ();
363+
364+ list_pushback_node (* rq , & task -> rq_node );
365+
366+ /* Update task count in ready queue */
367+ kcb -> queue_counts [prio_level ]++ ;
368+
369+ /* Setup first rr_cursor */
370+ if (!* cursor )
371+ * cursor = & task -> rq_node ;
372+
373+ /* Advance cursor when cursor same as running task */
374+ if (* cursor == kcb -> task_current )
375+ * cursor = & task -> rq_node ;
376+
377+ BITMAP_SET (task -> prio_level );
378+ return ;
357379}
358380
359- /* Remove task from ready queues - state-based approach for compatibility */
360- void sched_dequeue_task (tcb_t * task )
381+ /* Remove task from ready queue; return removed ready queue node */
382+ static __attribute__(( unused )) void sched_dequeue_task (tcb_t * task )
361383{
362- if (unlikely (!task ))
384+ if (unlikely (!task || !( & task -> rq_node ) ))
363385 return ;
364386
365- /* For tasks that need to be removed from ready state (suspended/cancelled),
366- * we rely on the state change. The scheduler will skip non-ready tasks
367- * when it encounters them during the round-robin traversal.
368- */
387+ uint8_t prio_level = task -> prio_level ;
388+
389+ /* For task that need to be removed from ready/running state, it need be
390+ * removed from corresponding ready queue. */
391+ list_t * rq = kcb -> ready_queues [prio_level ];
392+ list_node_t * * cursor = & kcb -> rr_cursors [prio_level ];
393+
394+ /* Safely move cursor to next task node. */
395+ if (& task -> rq_node == * cursor )
396+ * cursor = list_cnext (rq , * cursor );
397+
398+ /* Remove ready queue node */
399+ list_remove_node (rq , & task -> rq_node );
400+
401+ /* Update task count in ready queue */
402+ if (!-- kcb -> queue_counts [prio_level ]) {
403+ * cursor = NULL ;
404+ BITMAP_CLEAN (task -> prio_level );
405+ }
406+ return ;
369407}
370408
371409/* Handle time slice expiration for current task */
@@ -386,20 +424,15 @@ void sched_tick_current_task(void)
386424 }
387425}
388426
389- /* Task wakeup - simple state transition approach */
427+ /* Task wakeup and enqueue into ready queue */
390428void sched_wakeup_task (tcb_t * task )
391429{
392430 if (unlikely (!task ))
393431 return ;
394432
395- /* Mark task as ready - scheduler will find it during round-robin traversal
396- */
397- if (task -> state != TASK_READY ) {
398- task -> state = TASK_READY ;
399- /* Ensure task has time slice */
400- if (task -> time_slice == 0 )
401- task -> time_slice = get_priority_timeslice (task -> prio_level );
402- }
433+ /* Enqueue task into ready queue */
434+ if (task -> state != TASK_READY && task -> state != TASK_RUNNING )
435+ sched_enqueue_task (task );
403436}
404437
405438/* Efficient Round-Robin Task Selection with O(n) Complexity
@@ -673,6 +706,10 @@ int32_t mo_task_cancel(uint16_t id)
673706 }
674707 }
675708
709+ /* Remove from ready queue */
710+ if (tcb -> state == TASK_READY )
711+ sched_dequeue_task (tcb );
712+
676713 CRITICAL_LEAVE ();
677714
678715 /* Free memory outside critical section */
@@ -703,7 +740,9 @@ void mo_task_delay(uint16_t ticks)
703740
704741 tcb_t * self = kcb -> task_current -> data ;
705742
706- /* Set delay and blocked state - scheduler will skip blocked tasks */
743+ /* Set delay and blocked state, dequeue from ready queue */
744+ sched_dequeue_task (self );
745+
707746 self -> delay = ticks ;
708747 self -> state = TASK_BLOCKED ;
709748 NOSCHED_LEAVE ();
@@ -730,8 +769,13 @@ int32_t mo_task_suspend(uint16_t id)
730769 return ERR_TASK_CANT_SUSPEND ;
731770 }
732771
772+ /* Remove task node from ready queue if task is in ready queue
773+ * (TASK_RUNNING/TASK_READY).*/
774+ if (task -> state == TASK_READY || task -> state == TASK_RUNNING )
775+ sched_dequeue_task (task );
776+
733777 task -> state = TASK_SUSPENDED ;
734- bool is_current = (kcb -> task_current == node );
778+ bool is_current = (kcb -> task_current -> data == task );
735779
736780 CRITICAL_LEAVE ();
737781
@@ -758,9 +802,8 @@ int32_t mo_task_resume(uint16_t id)
758802 CRITICAL_LEAVE ();
759803 return ERR_TASK_CANT_RESUME ;
760804 }
761-
762- /* mark as ready - scheduler will find it */
763- task -> state = TASK_READY ;
805+ /* Enqueue resumed task into ready queue */
806+ sched_enqueue_task (task );
764807
765808 CRITICAL_LEAVE ();
766809 return ERR_OK ;
@@ -874,6 +917,9 @@ void _sched_block(queue_t *wait_q)
874917
875918 tcb_t * self = kcb -> task_current -> data ;
876919
920+ /* Remove node from ready queue */
921+ sched_dequeue_task (self );
922+
877923 if (queue_enqueue (wait_q , self ) != 0 )
878924 panic (ERR_SEM_OPERATION );
879925
0 commit comments