1515static int32_t noop_rtsched (void );
1616void _timer_tick_handler (void );
1717
18+ /* hart 0 scheduler */
19+ static sched_t hart0_sched = {
20+ .ready_bitmap = 0 ,
21+ .ready_queues = {NULL },
22+ .rr_cursors = {NULL },
23+ .quantum_cycles = {0 },
24+ .last_selected_prio = 0 ,
25+ .local_switches = 0 ,
26+ .current_task = NULL ,
27+ .hart_id = 0 ,
28+ };
29+
1830/* Kernel-wide control block (KCB) */
1931static kcb_t kernel_state = {
2032 .tasks = NULL ,
@@ -25,6 +37,7 @@ static kcb_t kernel_state = {
2537 .task_count = 0 ,
2638 .ticks = 0 ,
2739 .preemptive = true, /* Default to preemptive mode */
40+ .harts = & hart0_sched ,
2841};
2942kcb_t * kcb = & kernel_state ;
3043
@@ -344,7 +357,6 @@ static void sched_enqueue_task(tcb_t *task)
344357 /* Ensure task has appropriate time slice for its priority */
345358 task -> time_slice = get_priority_timeslice (task -> prio_level );
346359 task -> state = TASK_READY ;
347-
348360 /* Task selection is handled directly through the master task list */
349361}
350362
@@ -418,34 +430,32 @@ uint16_t sched_select_next_task(void)
418430
419431 /* Mark current task as ready if it was running */
420432 if (current_task -> state == TASK_RUNNING )
433+ {
421434 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+ }
422438
423439 /* Round-robin search: find next ready task in the master task list */
424- list_node_t * start_node = kcb -> task_current ;
425- list_node_t * node = start_node ;
426- int iterations = 0 ; /* Safety counter to prevent infinite loops */
427-
428- do {
429- /* Move to next task (circular) */
430- node = list_cnext (kcb -> tasks , node );
431- if (!node || !node -> data )
432- continue ;
433-
434- tcb_t * task = node -> data ;
435-
436- /* Skip non-ready tasks */
437- if (task -> state != TASK_READY )
438- continue ;
439-
440- /* Found a ready task */
441- kcb -> task_current = node ;
442- task -> state = TASK_RUNNING ;
443- task -> time_slice = get_priority_timeslice (task -> prio_level );
444-
445- return task -> id ;
446-
447- } while (node != start_node && ++ iterations < SCHED_IMAX );
448440
441+ /* Find highest priority task queue */
442+ uint32_t bitmap = kcb -> harts -> ready_bitmap ;
443+ int highest_prio_level = 0 ;
444+ for (;!(bitmap & 1U ); highest_prio_level ++ , bitmap >>= 1 );
445+
446+ /* 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 ;
448+ list_pop (kcb -> harts -> ready_queues [highest_prio_level ]);
449+ ((tcb_t * )node -> data )-> state = TASK_RUNNING ;
450+ kcb -> task_current = node ;
451+
452+ /* Check popped queue is empty or not */
453+ if (kcb -> harts -> ready_queues [highest_prio_level ]-> length == 0 )
454+ kcb -> harts -> ready_bitmap &= ~(1U << highest_prio_level );
455+
456+ if (node )
457+ return 1 ;
458+
449459 /* No ready tasks found - this should not happen in normal operation */
450460 panic (ERR_NO_TASKS );
451461 return 0 ;
@@ -603,6 +613,12 @@ int32_t mo_task_spawn(void *task_entry, uint16_t stack_size_req)
603613 }
604614 }
605615
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+ }
621+
606622 list_node_t * node = list_pushback (kcb -> tasks , tcb );
607623 if (!node ) {
608624 CRITICAL_LEAVE ();
@@ -615,8 +631,16 @@ int32_t mo_task_spawn(void *task_entry, uint16_t stack_size_req)
615631 tcb -> id = kcb -> next_tid ++ ;
616632 kcb -> task_count ++ ; /* Cached count of active tasks for quick access */
617633
618- if (!kcb -> task_current )
634+ /* If tcb is the first task, turn it into TASK_RUNNING state and does not put into ready queue */
635+ if (!kcb -> task_current ) {
619636 kcb -> task_current = node ;
637+ tcb -> state = TASK_RUNNING ;
638+ }
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+ }
620644
621645 CRITICAL_LEAVE ();
622646
@@ -630,8 +654,10 @@ int32_t mo_task_spawn(void *task_entry, uint16_t stack_size_req)
630654
631655 /* Add to cache and mark ready */
632656 cache_task (tcb -> id , tcb );
633- sched_enqueue_task (tcb );
634657
658+ /* Active task from TASK_STOPPED state */
659+ if (tcb -> state == TASK_STOPPED )
660+ sched_enqueue_task (tcb );
635661 return tcb -> id ;
636662}
637663
0 commit comments