74 lines
2.1 KiB
C
74 lines
2.1 KiB
C
/*
|
|
* implementing the scheduler
|
|
*/
|
|
|
|
#include "sched.h"
|
|
#include "spike_interface/spike_utils.h"
|
|
|
|
process* ready_queue_head = NULL;
|
|
|
|
//
|
|
// insert a process, proc, into the END of ready queue.
|
|
//
|
|
void insert_to_ready_queue( process* proc ) {
|
|
sprint( "going to insert process %d to ready queue.\n", proc->pid );
|
|
// if the queue is empty in the beginning
|
|
if( ready_queue_head == NULL ){
|
|
proc->status = READY;
|
|
proc->queue_next = NULL;
|
|
ready_queue_head = proc;
|
|
return;
|
|
}
|
|
|
|
// ready queue is not empty
|
|
process *p;
|
|
// browse the ready queue to see if proc is already in-queue
|
|
for( p=ready_queue_head; p->queue_next!=NULL; p=p->queue_next )
|
|
if( p == proc ) return; //already in queue
|
|
|
|
// p points to the last element of the ready queue
|
|
if( p==proc ) return;
|
|
p->queue_next = proc;
|
|
proc->status = READY;
|
|
proc->queue_next = NULL;
|
|
|
|
return;
|
|
}
|
|
|
|
//
|
|
// choose a proc from the ready queue, and put it to run.
|
|
// note: schedule() does not take care of previous current process. If the current
|
|
// process is still runnable, you should place it into the ready queue (by calling
|
|
// ready_queue_insert), and then call schedule().
|
|
//
|
|
extern process procs[NPROC];
|
|
void schedule() {
|
|
if ( !ready_queue_head ){
|
|
// by default, if there are no ready process, and all processes are in the status of
|
|
// FREE and ZOMBIE, we should shutdown the emulated RISC-V machine.
|
|
int should_shutdown = 1;
|
|
|
|
for( int i=0; i<NPROC; i++ )
|
|
if( (procs[i].status != FREE) && (procs[i].status != ZOMBIE) ){
|
|
should_shutdown = 0;
|
|
sprint( "ready queue empty, but process %d is not in free/zombie state:%d\n",
|
|
i, procs[i].status );
|
|
}
|
|
|
|
if( should_shutdown ){
|
|
sprint( "no more ready processes, system shutdown now.\n" );
|
|
shutdown( 0 );
|
|
}else{
|
|
panic( "Not handled: we should let system wait for unfinished processes.\n" );
|
|
}
|
|
}
|
|
|
|
current = ready_queue_head;
|
|
assert( current->status == READY );
|
|
ready_queue_head = ready_queue_head->queue_next;
|
|
|
|
current->status == RUNNING;
|
|
sprint( "going to schedule process %d to run.\n", current->pid );
|
|
switch_to( current );
|
|
}
|