@@ -357,7 +357,15 @@ static void sched_enqueue_task(tcb_t *task)
357357 /* Ensure task has appropriate time slice for its priority */
358358 task -> time_slice = get_priority_timeslice (task -> prio_level );
359359 task -> state = TASK_READY ;
360- /* Task selection is handled directly through the master task list */
360+
361+ /* Push task into corresponding ready queue and setup bitmap */
362+ CRITICAL_ENTER ();
363+ if (!kcb -> harts -> ready_queues [task -> prio_level ])
364+ kcb -> harts -> ready_queues [task -> prio_level ] = list_create ();
365+
366+ list_pushback (kcb -> harts -> ready_queues [task -> prio_level ], task );
367+ bitmap_set (task -> prio_level );
368+ CRITICAL_LEAVE ();
361369}
362370
363371/* Remove task from ready queues - state-based approach for compatibility */
@@ -367,9 +375,20 @@ void sched_dequeue_task(tcb_t *task)
367375 return ;
368376
369377 /* For tasks that need to be removed from ready state (suspended/cancelled),
370- * we rely on the state change. The scheduler will skip non-ready tasks
371- * when it encounters them during the round-robin traversal.
378+ * we rely on the state change. The scheduler will remove it from
379+ * corresponding priority ready queue and setup bitmap by checking remaining
380+ * task count in this queue.
381+ *
382+ * The state of task will be modified by `mo_task_suspended` or
383+ * `mo_task_cancel`.
372384 */
385+ CRITICAL_ENTER ();
386+ list_node_t * node = find_task_node_by_id (task -> id );
387+ list_remove (kcb -> harts -> ready_queues [task -> prio_level ], node );
388+
389+ if (!kcb -> harts -> ready_queues [task -> prio_level ]-> length )
390+ bitmap_clean (task -> prio_level );
391+ CRITICAL_LEAVE ();
373392}
374393
375394/* Handle time slice expiration for current task */
@@ -430,32 +449,30 @@ uint16_t sched_select_next_task(void)
430449
431450 /* Mark current task as ready if it was running */
432451 if (current_task -> state == TASK_RUNNING )
433- {
434- current_task -> state = TASK_READY ;
435- list_pushback (kcb -> harts -> ready_queues [current_task -> prio_level ], current_task );
436- kcb -> harts -> ready_bitmap |= (1U << current_task -> prio_level );
437- }
452+ sched_enqueue_task (current_task );
438453
439454 /* Round-robin search: find next ready task in the master task list */
440455
441456 /* Find highest priority task queue */
442457 uint32_t bitmap = kcb -> harts -> ready_bitmap ;
443458 int highest_prio_level = 0 ;
444- for (;!(bitmap & 1U ); highest_prio_level ++ , bitmap >>= 1 );
459+ for (; !(bitmap & 1U ); highest_prio_level ++ , bitmap >>= 1 )
460+ ;
445461
446462 /* Pop out from corresponding queue and mark it as TASK_RUNNING */
447- list_node_t * node = kcb -> harts -> ready_queues [highest_prio_level ]-> head -> next ;
463+ list_node_t * node =
464+ kcb -> harts -> ready_queues [highest_prio_level ]-> head -> next ;
448465 list_pop (kcb -> harts -> ready_queues [highest_prio_level ]);
449- ((tcb_t * )node -> data )-> state = TASK_RUNNING ;
466+ ((tcb_t * ) node -> data )-> state = TASK_RUNNING ;
450467 kcb -> task_current = node ;
451468
452469 /* Check popped queue is empty or not */
453470 if (kcb -> harts -> ready_queues [highest_prio_level ]-> length == 0 )
454- kcb -> harts -> ready_bitmap &= ~( 1U << highest_prio_level );
455-
471+ bitmap_clean ( highest_prio_level );
472+
456473 if (node )
457- return 1 ;
458-
474+ return (( tcb_t * ) node -> data ) -> id ;
475+
459476 /* No ready tasks found - this should not happen in normal operation */
460477 panic (ERR_NO_TASKS );
461478 return 0 ;
@@ -613,11 +630,6 @@ int32_t mo_task_spawn(void *task_entry, uint16_t stack_size_req)
613630 }
614631 }
615632
616- /* Create corresponding ready queue */
617- if (!kcb -> harts -> ready_queues [tcb -> prio_level ]) {
618- kcb -> harts -> ready_queues [tcb -> prio_level ] = list_create ();
619- kcb -> tasks = list_create ();
620- }
621633
622634 list_node_t * node = list_pushback (kcb -> tasks , tcb );
623635 if (!node ) {
@@ -631,16 +643,12 @@ int32_t mo_task_spawn(void *task_entry, uint16_t stack_size_req)
631643 tcb -> id = kcb -> next_tid ++ ;
632644 kcb -> task_count ++ ; /* Cached count of active tasks for quick access */
633645
634- /* If tcb is the first task, turn it into TASK_RUNNING state and does not put into ready queue */
646+ /* If tcb is the first task, turn it into TASK_RUNNING state and does not
647+ * put into ready queue */
635648 if (!kcb -> task_current ) {
636649 kcb -> task_current = node ;
637650 tcb -> state = TASK_RUNNING ;
638651 }
639- else {
640- /* Setup bitmap and put into corresponding ready queue */
641- kcb -> harts -> ready_bitmap |= (1U << tcb -> prio_level );
642- list_pushback (kcb -> harts -> ready_queues [tcb -> prio_level ], tcb );
643- }
644652
645653 CRITICAL_LEAVE ();
646654
@@ -747,7 +755,6 @@ int32_t mo_task_suspend(uint16_t id)
747755 CRITICAL_LEAVE ();
748756 return ERR_TASK_CANT_SUSPEND ;
749757 }
750-
751758 task -> state = TASK_SUSPENDED ;
752759 bool is_current = (kcb -> task_current == node );
753760
0 commit comments