kernel scheduling now working better with ecalls, not resetting the time slice

master
Anton Lydike 3 years ago
parent d7b5a1b8d0
commit ab19abe12b

@ -31,15 +31,3 @@ void write_mtimecmp(unsigned long long int mtimecmp) {
} }
#endif #endif
unsigned long long int read_time() {
unsigned int lower, higher;
__asm__(
"csrr %0, %2\n"
"csrr %1, %3\n"
: "=r"(lower), "=r"(higher)
: "i"(CSR_TIME), "i"(CSR_TIMEH)
);
return (unsigned long long) higher << 32 | lower;
}

@ -36,7 +36,17 @@
} }
void write_mtimecmp(unsigned long long int mtimecmp); void write_mtimecmp(unsigned long long int mtimecmp);
unsigned long long int read_time();
inline __attribute__((always_inline)) unsigned long long int read_time() {
unsigned int lower, higher;
__asm__(
"csrr %0, %2\n"
"csrr %1, %3\n"
: "=r"(lower), "=r"(higher)
: "i"(CSR_TIME), "i"(CSR_TIMEH)
);
return (unsigned long long) higher << 32 | lower;
}
#endif #endif

@ -48,6 +48,10 @@ int ecall_handle_exit(int* args, ProcessControlBlock* pcb)
} }
void trap_handle_ecall() { void trap_handle_ecall() {
{
mark_ecall_entry();
};
ProcessControlBlock* pcb = get_current_process(); ProcessControlBlock* pcb = get_current_process();
int *regs = pcb->regs; int *regs = pcb->regs;
int code = regs[16]; int code = regs[16];
@ -73,19 +77,39 @@ void trap_handle(int interrupt_bit, int code, int mtval)
{ {
if (interrupt_bit) { if (interrupt_bit) {
switch (code) { switch (code) {
// timer interrupts
case 4:
case 5:
case 6:
case 7: case 7:
scheduler_run_next(); scheduler_run_next();
break; break;
default: default:
// impossible // impossible
HALT(12) HALT(12);
break; break;
} }
} else { } else {
switch (code) { switch (code) {
case 8: // user ecall // any known exception code:
case 0:
case 1:
case 2:
case 4:
case 5:
case 6:
case 7:
case 12:
case 13:
case 15:
handle_exception(code, mtval);
break;
// user or supervisor ecall
case 8:
case 9:
trap_handle_ecall(); trap_handle_ecall();
break; break;
// unknown code
default: default:
HALT(13); HALT(13);
} }
@ -101,4 +125,9 @@ void init_ecall_table()
ecall_table[ECALL_JOIN] = ecall_handle_join; ecall_table[ECALL_JOIN] = ecall_handle_join;
ecall_table[ECALL_KILL] = ecall_handle_kill; ecall_table[ECALL_KILL] = ecall_handle_kill;
ecall_table[ECALL_EXIT] = ecall_handle_exit; ecall_table[ECALL_EXIT] = ecall_handle_exit;
} }
void handle_exception(int ecode, int mtval)
{
}

@ -33,6 +33,7 @@ int ecall_handle_join(int*, ProcessControlBlock*);
int ecall_handle_kill(int*, ProcessControlBlock*); int ecall_handle_kill(int*, ProcessControlBlock*);
int ecall_handle_exit(int*, ProcessControlBlock*); int ecall_handle_exit(int*, ProcessControlBlock*);
void handle_exception(int ecode, int mtval);
void __attribute__((__noreturn__)) trap_handle(int interrupt_bit, int code, int mtval); void __attribute__((__noreturn__)) trap_handle(int interrupt_bit, int code, int mtval);

@ -6,13 +6,14 @@
// scheduling data: // scheduling data:
ProcessControlBlock processes[PROCESS_COUNT]; ProcessControlBlock processes[PROCESS_COUNT];
int current_process_index = 1; int current_process_index = 1;
unsigned long long int scheduling_interrupted_start;
unsigned long long int next_interrupt_scheduled_for;
void scheduler_run_next () void scheduler_run_next ()
{ {
current_process_index = scheduler_select_free(); current_process_index = scheduler_select_free();
// set up timer interrupt // set up timer interrupt
unsigned long long int mtimecmp = read_time() + TIME_SLICE_LEN; set_next_interrupt();
write_mtimecmp(mtimecmp);
scheduler_switch_to(current_process_index); scheduler_switch_to(current_process_index);
} }
@ -22,9 +23,9 @@ void scheduler_try_return_to(ProcessControlBlock* pcb)
scheduler_run_next(); scheduler_run_next();
} else { } else {
current_process_index = scheduler_index_from_pid(pcb->pid); current_process_index = scheduler_index_from_pid(pcb->pid);
//FIXME: this refreshes the processes time slice which we actually don't want! // add time spent in ecall handler to the processes time slice
unsigned long long int mtimecmp = read_time() + TIME_SLICE_LEN; next_interrupt_scheduled_for = next_interrupt_scheduled_for + (read_time() - scheduling_interrupted_start);
write_mtimecmp(mtimecmp); write_mtimecmp(next_interrupt_scheduled_for);
scheduler_switch_to(current_process_index); scheduler_switch_to(current_process_index);
} }
} }
@ -135,3 +136,14 @@ ProcessControlBlock* get_current_process()
{ {
return &processes[current_process_index]; return &processes[current_process_index];
} }
void set_next_interrupt()
{
next_interrupt_scheduled_for = read_time() + TIME_SLICE_LEN;
write_mtimecmp(next_interrupt_scheduled_for);
}
void mark_ecall_entry()
{
scheduling_interrupted_start = read_time();
}

@ -29,11 +29,12 @@ extern ProcessControlBlock processes[PROCESS_COUNT];
// scheduler methods // scheduler methods
int scheduler_select_free(); int scheduler_select_free();
int scheduler_create_process(int binid); int scheduler_create_process(int binid);
void set_next_interrupt();
void __attribute__((noreturn)) scheduler_run_next(); void __attribute__((noreturn)) scheduler_run_next();
void __attribute__((noreturn)) scheduler_try_return_to(ProcessControlBlock*); void __attribute__((noreturn)) scheduler_try_return_to(ProcessControlBlock*);
void __attribute__((noreturn)) scheduler_switch_to(int proc_index); void __attribute__((noreturn)) scheduler_switch_to(int proc_index);
int scheduler_index_from_pid(int pid); int scheduler_index_from_pid(int pid);
int* get_current_process_registers(); int* get_current_process_registers();
ProcessControlBlock* get_current_process(); ProcessControlBlock* get_current_process();
void mark_ecall_entry();
#endif #endif
Loading…
Cancel
Save