BS_Praktikum5/README.md

4.2 KiB

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
    struct Task {
        int pid;              // Prozess-ID
        std::string filename; // Dateiname des Tasks
        std::vector<std::pair<std::string, std::string>> 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

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

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:

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
    std::cout << current_tick << "\tIDLE" << std::endl;
    

E. Statistik am Ende Ausgabe für jeden Task:

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:

// 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