Safer scheduler

This commit is contained in:
Baptiste Wicht 2014-03-31 23:09:11 +02:00
parent 380db5f28d
commit a13033a071
2 changed files with 36 additions and 15 deletions

View File

@ -40,7 +40,9 @@ scheduler::process_t& get_process(pid_t pid);
void irq_register_tasklet(const tasklet& task); void irq_register_tasklet(const tasklet& task);
void block_process(pid_t pid); sleep_queue_ptr* queue_ptr(pid_t pid);
void block_process();
void unblock_process(pid_t pid); void unblock_process(pid_t pid);
int64_t exec(const std::string& path, const std::vector<std::string>& params); int64_t exec(const std::string& path, const std::vector<std::string>& params);

View File

@ -39,6 +39,7 @@ namespace {
struct process_control_t { struct process_control_t {
scheduler::process_t process; scheduler::process_t process;
scheduler::process_state state; scheduler::process_state state;
scheduler::sleep_queue_ptr queue_ptr;
size_t rounds; size_t rounds;
size_t sleep_timeout; size_t sleep_timeout;
std::vector<std::vector<std::string>> handles; std::vector<std::vector<std::string>> handles;
@ -82,7 +83,7 @@ void idle_task(){
void tasklet_task(){ void tasklet_task(){
while(true){ while(true){
//Wait until there is something to do //Wait until there is something to do
scheduler::block_process(scheduler::get_pid()); scheduler::block_process();
while(true){ while(true){
size_t rflags; size_t rflags;
@ -106,7 +107,7 @@ void tasklet_task(){
void gc_task(){ void gc_task(){
while(true){ while(true){
//Wait until there is something to do //Wait until there is something to do
scheduler::block_process(scheduler::get_pid()); scheduler::block_process();
//2. Clean up each killed process //2. Clean up each killed process
@ -855,19 +856,32 @@ scheduler::process_t& scheduler::get_process(pid_t pid){
return pcb[pid].process; return pcb[pid].process;
} }
void scheduler::block_process(pid_t pid){ scheduler::sleep_queue_ptr* scheduler::queue_ptr(scheduler::pid_t pid){
thor_assert(pid < scheduler::MAX_PROCESS, "pid out of bounds");
thor_assert(pid != idle_pid, "No reason to block the idle task");
thor_assert(is_started(), "The scheduler is not started"); thor_assert(is_started(), "The scheduler is not started");
thor_assert(pcb[pid].state == process_state::RUNNING, "Can only block RUNNING processes"); thor_assert(pid < scheduler::MAX_PROCESS, "pid out of bounds");
if(DEBUG_SCHEDULER){ return &pcb[pid].queue_ptr;
printf("Block process %u\n", pid); }
}
pcb[pid].state = process_state::BLOCKED; void scheduler::block_process(){
thor_assert(current_pid != idle_pid, "No reason to block the idle task");
thor_assert(is_started(), "The scheduler is not started");
k_print_line(current_pid);
k_print_line(static_cast<size_t>(pcb[current_pid].state));
size_t rflags;
arch::disable_hwint(rflags);
//TODO Perhaps not true to block it unconditionally
auto& state = pcb[current_pid].state;
state = process_state::BLOCKED;
reschedule(); reschedule();
arch::enable_hwint(rflags);
} }
void scheduler::unblock_process(pid_t pid){ void scheduler::unblock_process(pid_t pid){
@ -876,11 +890,16 @@ void scheduler::unblock_process(pid_t pid){
thor_assert(is_started(), "The scheduler is not started"); thor_assert(is_started(), "The scheduler is not started");
thor_assert(pcb[pid].state == process_state::BLOCKED || pcb[pid].state == process_state::WAITING, "Can only unblock BLOCKED/WAITING processes"); thor_assert(pcb[pid].state == process_state::BLOCKED || pcb[pid].state == process_state::WAITING, "Can only unblock BLOCKED/WAITING processes");
if(DEBUG_SCHEDULER){ size_t rflags;
printf("Unblock process %u\n", pid); arch::disable_hwint(rflags);
auto& state = pcb[pid].state;
if(state == process_state::BLOCKED){
state = process_state::READY;
} }
pcb[pid].state = process_state::READY; arch::enable_hwint(rflags);
} }
void scheduler::sleep_ms(pid_t pid, size_t time){ void scheduler::sleep_ms(pid_t pid, size_t time){