src/kernel/task/scheduler.c
/*
 * @note: this is the core function of
 *        scheduler.
 *        Must invoked with preempt closed.
 */
@note: this is the core function of
scheduler.
Must invoked with preempt closed.
@note : this is the core function of scheduler . Must invoked with preempt closed .
void __scheduler_core(){
    BUG(GET_RUNNING_THREAD()->preempt_cnt!=0,"scheduler 0!\n");
    threads_clear_resched();
    thread_t * prev = GET_RUNNING_THREAD();
    link_t * cpu_ready_queue = get_cpu_var_no_preempt(ready_queues);
    node_t * node = link_find_node_by_data(cpu_ready_queue, prev);
    if(node==NULL){
        node = cpu_ready_queue->head;
        if(node==NULL){
            return;
        }
    }
    thread_status_t status = threads_get_status(node->data);
    node_t *new_node = NULL;
    if(status==THREADS_RUNNABLE||status==THREADS_CREATED){
        new_node = node;
    }
    else{
        new_node = link_get_runnable_thread(cpu_ready_queue, node);
    }
    if(new_node==NULL){
        if(threads_get_status(prev) == THREADS_SLEEPING){
            PANIC("scheduler","can`t find thread to schedule when sleeping thread!\n");
        }
        goto no_swtch_out;
    }
    else{
        if(prev->status==THREADS_RUNNING){
            threads_set_status(prev, THREADS_RUNNABLE);
        }
        thread_t * next = new_node->data;
        thread_status_t  previous_status = threads_set_status(next, THREADS_RUNNING);
        if(next->ttype == TTYPE_USER){
            load_satp(next->vmm_pool->pagetable);
        }
        context_t * prev_context = &prev->context;
        context_t * next_context = &next->context;
        #ifdef CONFIG_RISCV_EXTENSION_F
        swtch_F(prev_context,next_context);
        #else
        swtch(prev_context, next_context);
        #endif
    }
    success_out:
    return;
    no_swtch_out:
    return;
}
void __scheduler_core ( ) { BUG ( GET_RUNNING_THREAD ( ) -> preempt_cnt != 0 , " \n " ) ; threads_clear_resched ( ) ; thread_t * prev = GET_RUNNING_THREAD ( ) ; link_t * cpu_ready_queue = get_cpu_var_no_preempt ( ready_queues ) ; node_t * node = link_find_node_by_data ( cpu_ready_queue , prev ) ; if ( node == NULL ) { node = cpu_ready_queue -> head ; if ( node == NULL ) { return ; } } thread_status_t status = threads_get_status ( node -> data ) ; node_t * new_node = NULL ; if ( status == THREADS_RUNNABLE || status == THREADS_CREATED ) { new_node = node ; } else { new_node = link_get_runnable_thread ( cpu_ready_queue , node ) ; } if ( new_node == NULL ) { if ( threads_get_status ( prev ) == THREADS_SLEEPING ) { PANIC ( " " , " \n " ) ; } goto no_swtch_out ; } else { if ( prev -> status == THREADS_RUNNING ) { threads_set_status ( prev , THREADS_RUNNABLE ) ; } thread_t * next = new_node -> data ; thread_status_t previous_status = threads_set_status ( next , THREADS_RUNNING ) ; if ( next -> ttype == TTYPE_USER ) { load_satp ( next -> vmm_pool -> pagetable ) ; } context_t * prev_context = & prev -> context ; context_t * next_context = & next -> context ; #ifdef CONFIG_RISCV_EXTENSION_F swtch_F ( prev_context , next_context ) ; #else swtch ( prev_context , next_context ) ; #endif } success_out : return ; no_swtch_out : return ; }
@note: this is the core function of
        scheduler.
@note : this is the core function of scheduler .
// get a runnable thread to switch // node is not in the ready queue. // can`t find node // Run Switch From Hear! // change the page table if switch to other user task //        if(next->ttype == TTYPE_KERNEL ){ //            DEBUG("SCHEDULER","Switch to kernel next!"); //            printk("0x%h\n",next); //        } //        else{ //            DEBUG("SCHEDULER","Switch to user next!"); //            printk("0x%h\n",next); //        } // if the platform RISC-V F extension // switch must save float register