void Simulator::handleIO( const Operation& operation, int pid ) { string startMsg = "I/O: process " + to_string(pid) + " starting "; string endMsg = "Interrupt: process " + to_string(pid) + " done with "; if( operation.parameters().description == "hard drive" ) { string type = operation.parameters().id == 'I' ? "input" : "output"; display( startMsg + "hard drive " + type ); wait( operation.parameters().duration ); display( startMsg + "hard drive " + type ); } else if( operation.parameters().description == "keyboard" ) { display( startMsg + "keyboard input" ); wait( operation.parameters().duration ); display( endMsg + "keyboard input" ); } else if( operation.parameters().description == "printer" ) { display( startMsg + "printer output" ); wait( operation.parameters().duration ); display( endMsg + "printer output" ); } else if( operation.parameters().description == "monitor" ) { display( startMsg + "monitor output" ); wait( operation.parameters().duration ); display( endMsg + "monitor output" ); } interrupts_.push(pid); }
void Simulator::executeProgram( Program *program ) { int pid = program->process_control_block().processID; Operation* operation = program->step(); char operationType = operation->parameters().id; // Create thread lambda auto ThreadStart = [this, operation, pid]() { handleIO(*operation, pid); }; program->run(); // Start if( operationType == 'A' && operation->parameters().description == "start") { display("OS: starting process " + to_string(pid)); operation = program->step(); } // I/O if( operationType == 'I' || operationType == 'O') { display("Process: " + to_string(pid) + ": starting I/O"); thread IO_thread(ThreadStart); IO_thread.detach(); // async, do not block program->suspend(); suspendedPrograms_[pid] = *program; } // Processing else if( operationType == 'P' ) { display("Process " + to_string(pid) + ": processing action"); int quantum = 0; while( !operation->completed() && interrupts_.empty() ) { quantum++; operation = program->step(); wait( operation->parameters().cycleTime ); if( quantum == configurationData.quantum ) { // Launch a quantum interrupt to stop execution of the program interrupts_.push(0); display("Interrupt: quantum expired"); } } if( operation->completed() ) { display("Process " + to_string(pid) + ": end processing action"); } } // The last operation in a program is an exit operation if( program->operations_left() <= 1 && program->process_control_block().state != SUSPENDED) { program->exit(); display("OS: removing process " + to_string(pid)); } }