@@ -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