#include #include #include #include #include #include #include #include #include #include struct Task { int pid; std::string filename; std::vector> program; int pc; int accu; int blocked; int start_tick; int end_tick; bool terminated; int slice_remaining; }; std::vector> readFile(const std::string &filename) { std::vector> instructions; std::ifstream file(filename); if(!file.is_open()) { std::cerr << "Fehler: Datei " << filename << " konnte nicht geöffnet werden.\n"; return instructions; } std::string line; while (std::getline(file, line)) { if (line.empty()) continue; std::istringstream iss(line); std::string command; std::string param; if (!(iss >> command)) { continue; } if (!(iss >> param)) { param = ""; } instructions.push_back(std::make_pair(command, param)); } return instructions; } int main(int argc, char* argv[]) { if (argc < 2) { std::cerr << "Verwendung: " << argv[0] << " " << std::endl; return 1; } int time_slice = std::stoi(argv[1]); srand(time(0)); std::vector tasks; int next_pid = 0; int current_tick = 0; // Initialen Task aus init erstellen auto init_program = readFile("init"); if (init_program.empty()) { std::cerr << "Fehler: init konnte nicht gelesen werden." << std::endl; return 1; } Task init_task = { next_pid++, "init", init_program, 0, 0, 0, 0, -1, false, time_slice }; tasks.push_back(init_task); // Header ausgeben std::cout << "Tick\tPID\tTask\tPC\tAccu\tInstr" << std::endl; int last_executed_index = -1; bool all_terminated = false; while (!all_terminated) { all_terminated = true; bool found_runnable = false; int start_index = (last_executed_index + 1) % tasks.size(); int current_index = start_index; Task* current_task = nullptr; do { Task& task = tasks[current_index]; if (!task.terminated && task.blocked == 0) { current_task = &task; found_runnable = true; last_executed_index = current_index; break; } current_index = (current_index + 1) % tasks.size(); } while (current_index != start_index); if (found_runnable) { while (current_task->slice_remaining > 0 && !current_task->terminated && current_task->blocked == 0) { // Hole Befehl auto& instruction = current_task->program[current_task->pc]; std::string command = instruction.first; std::string param = instruction.second; // Ausgabe des aktuellen Zustands std::cout << current_tick << "\t" << current_task->pid << "\t" << current_task->filename << "\t" << current_task->pc << "\t" << current_task->accu << "\t" << command; if (!param.empty()) { std::cout << " " << param; } std::cout << std::endl; // Führe Befehl aus if (command == "LOAD") { current_task->accu = std::stoi(param); } else if (command == "ADD") { current_task->accu += std::stoi(param); } else if (command == "SUB") { current_task->accu -= std::stoi(param); } else if (command == "READ") { current_task->accu = rand() % 4096; current_task->blocked = 2; } else if (command == "EXE") { std::string filename = param; auto new_program = readFile(filename); if (!new_program.empty()) { Task new_task = { next_pid++, param, new_program, 0, 0, 0, current_tick + 1, -1, false, time_slice }; tasks.push_back(new_task); } } else if (command == "T") { current_task->terminated = true; current_task->end_tick = current_tick; } // PC erhöhen, außer bei Terminierung if (command != "T") { current_task->pc++; if (current_task->pc >= current_task->program.size()) { current_task->terminated = true; current_task->end_tick = current_tick; } } // Blockierungszeit für andere Tasks dekrementieren for (auto& task : tasks) { if (task.blocked > 0) { if (&task == current_task && command == "READ") { // Nicht dekrementieren } else { task.blocked--; } } } // Zeitscheibe verbrauchen current_task->slice_remaining--; current_tick++; // Bei Blockierung oder Terminierung Schleife verlassen if (current_task->blocked > 0 || current_task->terminated) { break; } } // Zeitscheibe zurücksetzen current_task->slice_remaining = time_slice; } else { // Kein lauffähiger Task (IDLE) std::cout << current_tick << "\tIDLE" << std::endl; for (auto& task : tasks) { if (task.blocked > 0) { task.blocked--; } } current_tick++; } // Prüfen, ob noch aktive Tasks existieren for (const auto& task : tasks) { if (!task.terminated) { all_terminated = false; break; } } } // Statistik ausgeben std::cout << "\nStatistik:" << std::endl; std::cout << "PID\tTask\tStart\tEnde\tVerweilzeit\tAccu" << std::endl; for (const auto& task : tasks) { int turnaround = task.end_tick - task.start_tick + 1; std::cout << task.pid << "\t" << task.filename << "\t" << task.start_tick << "\t" << task.end_tick << "\t" << turnaround << "\t\t" << task.accu << std::endl; } return 0; }