Musterlösung oder so
This commit is contained in:
parent
469ad9bb65
commit
03ec564fa1
3 changed files with 245 additions and 11 deletions
30
.gitignore
vendored
Normal file
30
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
# Build-Verzeichnisse
|
||||||
|
build/
|
||||||
|
bin/
|
||||||
|
lib/
|
||||||
|
|
||||||
|
# CMake-Dateien
|
||||||
|
CMakeFiles/
|
||||||
|
CMakeCache.txt
|
||||||
|
cmake_install.cmake
|
||||||
|
Makefile
|
||||||
|
|
||||||
|
# Compiled Object files
|
||||||
|
*.o
|
||||||
|
*.obj
|
||||||
|
|
||||||
|
# Shared objects
|
||||||
|
*.so
|
||||||
|
*.dylib
|
||||||
|
*.dll
|
||||||
|
|
||||||
|
# Executables
|
||||||
|
*.exe
|
||||||
|
*.out
|
||||||
|
*.app
|
||||||
|
|
||||||
|
# IDE-spezifische Dateien
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.swp
|
||||||
|
*~
|
||||||
25
CMakeLists.txt
Normal file
25
CMakeLists.txt
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
cmake_minimum_required(VERSION 3.10)
|
||||||
|
project(BS_Praktikum5 VERSION 0.1.0 LANGUAGES CXX)
|
||||||
|
|
||||||
|
# Compiler-Optionen
|
||||||
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
|
|
||||||
|
# Warnungen und Debug-Informationen bei Entwicklung aktivieren
|
||||||
|
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wpedantic -g")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Aktuelles Verzeichnis als Include-Pfad hinzufügen
|
||||||
|
include_directories(.)
|
||||||
|
|
||||||
|
# Quellen sammeln
|
||||||
|
file(GLOB SOURCES *.cpp)
|
||||||
|
file(GLOB HEADERS *.h *.hpp)
|
||||||
|
|
||||||
|
# Ausführbare Datei erstellen
|
||||||
|
add_executable(${PROJECT_NAME} ${SOURCES})
|
||||||
|
|
||||||
|
# Installation konfigurieren
|
||||||
|
install(TARGETS ${PROJECT_NAME} DESTINATION bin)
|
||||||
201
einlesen.cpp
201
einlesen.cpp
|
|
@ -4,9 +4,26 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <ctime>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
std::vector<std::pair<std::string, std::string> > readFile(const std::string &filename) {
|
struct Task {
|
||||||
std::vector<std::pair<std::string, std::string> > instructions;
|
int pid;
|
||||||
|
std::string filename;
|
||||||
|
std::vector<std::pair<std::string, std::string>> program;
|
||||||
|
int pc;
|
||||||
|
int accu;
|
||||||
|
int blocked;
|
||||||
|
int start_tick;
|
||||||
|
int end_tick;
|
||||||
|
bool terminated;
|
||||||
|
int slice_remaining;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<std::pair<std::string, std::string>> readFile(const std::string &filename) {
|
||||||
|
std::vector<std::pair<std::string, std::string>> instructions;
|
||||||
std::ifstream file(filename);
|
std::ifstream file(filename);
|
||||||
if(!file.is_open()) {
|
if(!file.is_open()) {
|
||||||
std::cerr << "Fehler: Datei " << filename << " konnte nicht geöffnet werden.\n";
|
std::cerr << "Fehler: Datei " << filename << " konnte nicht geöffnet werden.\n";
|
||||||
|
|
@ -15,7 +32,6 @@ std::vector<std::pair<std::string, std::string> > readFile(const std::string &fi
|
||||||
|
|
||||||
std::string line;
|
std::string line;
|
||||||
while (std::getline(file, line)) {
|
while (std::getline(file, line)) {
|
||||||
// Entferne führende oder trailing Whitespace
|
|
||||||
if (line.empty()) continue;
|
if (line.empty()) continue;
|
||||||
|
|
||||||
std::istringstream iss(line);
|
std::istringstream iss(line);
|
||||||
|
|
@ -23,13 +39,10 @@ std::vector<std::pair<std::string, std::string> > readFile(const std::string &fi
|
||||||
std::string param;
|
std::string param;
|
||||||
|
|
||||||
if (!(iss >> command)) {
|
if (!(iss >> command)) {
|
||||||
// Keine gültige Eingabe in dieser Zeile
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Optionalen Parameter einlesen, falls vorhanden
|
|
||||||
if (!(iss >> param)) {
|
if (!(iss >> param)) {
|
||||||
// Kein Parameter vorhanden
|
|
||||||
param = "";
|
param = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -39,11 +52,177 @@ std::vector<std::pair<std::string, std::string> > readFile(const std::string &fi
|
||||||
return instructions;
|
return instructions;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Beispiel zur Nutzung
|
int main(int argc, char* argv[]) {
|
||||||
int main() {
|
if (argc < 2) {
|
||||||
auto result = readFile("init");
|
std::cerr << "Verwendung: " << argv[0] << " <Zeitscheibenlänge>" << std::endl;
|
||||||
for (const auto &inst : result) {
|
return 1;
|
||||||
std::cout << "Befehl: " << inst.first << " | Parameter: " << inst.second << "\n";
|
}
|
||||||
|
int time_slice = std::stoi(argv[1]);
|
||||||
|
srand(time(0));
|
||||||
|
|
||||||
|
std::vector<Task> 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;
|
return 0;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue