diff --git a/README.md b/README.md new file mode 100644 index 0000000..f125f62 --- /dev/null +++ b/README.md @@ -0,0 +1,133 @@ +### Erklärung des Programms und seiner Funktionsweise + +#### 1. Grundlegende Struktur +Das Programm simuliert einen präemptiven Scheduler nach dem Round-Robin-Prinzip für einen Mikrocontroller. Es verwaltet mehrere Tasks (Prozesse), die aus Dateien gelesen werden und abwechselnd Rechenzeit erhalten. + +#### 2. Wichtige Komponenten +- **Task-Struktur**: Repräsentiert einen Prozess + ```cpp + struct Task { + int pid; // Prozess-ID + std::string filename; // Dateiname des Tasks + std::vector> program; // Befehlsliste + int pc; // Program Counter + int accu; // Akkumulator-Wert + int blocked; // Verbleibende Blockierungszeit + int start_tick; // Startzeitpunkt + int end_tick; // Endzeitpunkt + bool terminated; // Status ob beendet + int slice_remaining; // Verbleibende Zeitscheibenzeit + }; + ``` + +#### 3. Ablauf des Programms + +**A. Initialisierung** +```cpp +auto init_program = readFile("init"); // Liest init-Datei OHNE .txt +Task init_task = { + next_pid++, // PID 0 + "init", // Dateiname + init_program, // Programmcode + 0, // PC startet bei 0 + 0, // Akku startet bei 0 + 0, // Nicht blockiert + 0, // Start bei Tick 0 + -1, // Ende noch nicht bekannt + false, // Noch nicht terminiert + time_slice // Volle Zeitscheibe +}; +tasks.push_back(init_task); +``` + +**B. Hauptschleife - Der Scheduler** +```cpp +while (!all_terminated) { + // 1. Suche nächsten ausführbaren Task (Round-Robin) + // 2. Führe Task aus (so lange Zeitscheibe reicht) + // 3. Verarbeite Blockierungszeiten + // 4. Prüfe auf Terminierung +} +``` + +**C. Task-Ausführung** +Für jeden Befehl: +```cpp +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; // Zufallswert 0-4095 + current_task->blocked = 2; // 2 Takte blockieren +} else if (command == "EXE") { + // NEU: Direkt param verwenden OHNE .txt + std::string filename = param; + auto new_program = readFile(filename); + // Neuen Task erstellen und hinzufügen +} else if (command == "T") { + current_task->terminated = true; +} +``` + +**D. Besondere Logik** +- **Blockierung**: Bei `READ` wird der Task für 2 Takte blockiert +- **EXE-Befehl**: Startet neuen Task mit eigenem Programm +- **Zeitscheibe**: Task läuft maximal `time_slice` Befehle am Stück +- **IDLE**: Wenn alle Tasks blockiert sind + ```cpp + std::cout << current_tick << "\tIDLE" << std::endl; + ``` + +**E. Statistik am Ende** +Ausgabe für jeden Task: +```cpp +PID Task Start Ende Verweilzeit Akku +0 init 0 12 13 7 +1 file_a 3 8 6 19 +... +``` + +#### 4. Durchgeführte Änderungen +Ihre Anpassungen sind hier besonders wichtig: +```cpp +// Vorher: "init.txt" -> Jetzt: "init" +auto init_program = readFile("init"); + +// Vorher: param + ".txt" -> Jetzt: direkt param +std::string filename = param; +auto new_program = readFile(filename); +``` + +**Begründung**: +- Die Aufgabenstellung gibt Dateien ohne `.txt`-Erweiterung vor (init, file_a, etc.) +- Die Funktion `readFile` versucht direkt den übergebenen Namen zu öffnen +- Ohne Änderung würde das Programm nach nicht existierenden Dateien suchen (z.B. "file_a.txt" statt "file_a") + +#### 5. Beispielablauf +Für init.txt mit: +``` +LOAD 5 +ADD 3 +EXE file_a +``` + +1. Tick 0: Lädt `LOAD 5` in init-Task +2. Tick 1: Führt `ADD 3` aus (Akku=8) +3. Tick 2: Startet neuen Task aus file_a +4. Abwechselnde Ausführung beider Tasks + +#### 6. Besondere Szenarien +- **Alle Tasks blockiert**: + - Scheduler gibt "IDLE" aus + - Blockierungszeiten werden dekrementiert +- **EXE in mehreren Tasks**: + - Neue Tasks werden sofort zur Ausführung hinzugefügt + - Können vor dem Eltern-Task terminieren +- **Zeitscheibe zu Ende**: + - Task wird unterbrochen (präemptiv) + - Zustand (PC, Akku) wird gespeichert + - Nächster Task in Round-Robin-Reihenfolge kommt dran +