- Auffrischen der Assemblerkenntnisse (siehe auch Assembler-Crashkurs)
- Verständnis der Abläufe beim Prozesswechsel
- Unterscheidung von aktiven und passiven Objekten
Es soll eine einfache Prozessverwaltung implementiert werden, bei der die Benutzerprozesse die Prozessorabgabe im Sinne des Koroutinenkonzepts selbst regeln.
Dazu müssen einige Funktionen zum Zugriff auf die Struktur toc, die Klassen Coroutine, Dispatcher, Entrant und Scheduler, sowie die Funktion kickoff() implementiert werden. Außerdem soll OOStuBS/MPStuBS nun spätestens jetzt mit Application eine Anwendung erhalten.
Um die Prozessumschaltung überall in OOStuBS/MPStuBS ansprechen zu können, soll in Aufgabenteil B eine globale Instanz des Dispatchers angelegt und in Teil C durch eine globale Instanz scheduler des Schedulers ersetzt werden.
Klassenübersicht für Aufgabe 4
Die Funktionsfähigkeit der genannten Klassen soll mit Hilfe eines aussagefähigen Testprogramms gezeigt werden. Dazu soll in
main.cc nun zusätzlich eine globale Instanz scheduler der Klasse
Scheduler angelegt und ein erster Benutzerprozess application (ein Objekt der Klasse
Application) erzeugt werden, der seinerseits weitere Benutzerprozesse erzeugt. Testet auch die Methoden
Scheduler::exit() und
Scheduler::kill(Entrant& item).
Zum Testen empfiehlt es sich, die Gesamtaufgabe in drei Teile zu teilen und mit Teil B und C erst zu beginnen, wenn Teil A (bzw. B) fertig implementiert und ausreichend getestet wurden. Für diese Aufgabe könnt ihr die Interrupts wieder deaktivieren. Es laufen also nur die Coroutinen auf den/der CPU(s) und ihr braucht euch so nicht um Synchronisation zwischen Coroutinenkontrollfluss und Interrupthandlern zu kümmern. Interrupts kommen erst wieder in Aufgabe 5 ins Spiel.
Hier wird der Koroutinenwechsel realisiert. Es müssen also zunächst nur die Zugriffsfunktionen auf die Struktur
toc und die Klasse
Coroutine implementiert werden. Zum Testen der Lösung sollten in
Application (hier noch als Spezialisierung der Klasse
Coroutine) mehrere Benutzerprozesse (die ebenfalls von
Coroutine abgeleitet werden müssen) erzeugt werden, welche jeweils nach einigen Anweisungen den Prozessor an die nächste Koroutine abgeben.
Als nächstes kann der
Dispatcher implementiert werden. Im Testprogramm sollte der Koroutinenwechsel nun über den
Dispatcher laufen können.
Zum Schluss sollte der
Scheduler hinzugefügt werden, der die Prozessabstraktion
Entrant benötigt. Im Testprogramm müssen die Anwendung und Benutzerprozesse (nun als Spezialisierungen der Klasse
Entrant) beim
Scheduler angemeldet werden. Dafür brauchen sie sich nicht länger gegenseitig zu kennen, denn die Auswahl des nächsten Prozesses kann nun der
Scheduler übernehmen.
Die Implementierung für MPStuBS ist analog zur Uniprozessorimplementierung aufgebaut. Die Prozesse werden in einer einzigen Bereitliste verwaltet. Jedoch kann es vorkommen, dass verschiedene Prozessoren zur gleichen Zeit auf die Datenstruktur des Schedulers zugreifen. Aufrufe des Schedulers müssen deswegen in MPStuBS auch bei kooperativem Scheduling synchronisiert werden.
Grundsätzlich ist es für MPStuBS sinnvoll die Implementierung schrittweise wie oben beschrieben durchzuführen, dabei das Scheduling jedoch zuerst nur auf einer CPU zu starten. Erst wenn dies problemlos funktioniert, sollte das Scheduling auch auf den Applikationsprozessoren gestartet werden. Dies vereinfacht das Debugging enorm.
Es darf bei der Implementierung angenommen werden, dass immer genug Prozesse vorhanden sind, um alle Prozessoren zu beschäftigen. Diese Vorraussetzung müsst ihr dann aber natürlich auch in euerem Testprogramm erfüllen.