OOStuBS/MPStuBS
Aufgabe 4: Threadumschaltung für OOStuBS/MPStuBS

Lernziele

  • Auffrischen der Assemblerkenntnisse (siehe auch Assembler-Crashkurs)
  • Verständnis der Abläufe beim Threadwechsel
  • Unterscheidung von aktiven und passiven Objekten

Aufgabenbeschreibung

In Aufgabe 4 soll eine einfache Threadverwaltung implementiert werden. Die Prozessorabgabe soll dabei von den Threads selbst übernommen werden, d.h., dass kooperativ umgeschaltet werden soll.

Dazu müssen einige Funktionen zum Zugriff auf die Struktur toc (Thread of Context), die Klassen Dispatcher, Thread und Scheduler, sowie die Funktion Dispatcher::kickoff() implementiert werden. Außerdem soll StuBS spätestens jetzt mit Application eine Anwendung erhalten. Die Applikationen sollen jeweils auf einer eigenen Bildschirmposition einen Zähler ausgeben, der hochgezählt wird. Weiter sollen die Methoden Scheduler::exit() und Scheduler::kill(Thread *item) getestet werden.

Es empfiehlt sich die Aufgabe in drei Teile einzuteilen. Weiter sollen die Interrupts wieder deaktiviert werden, damit nicht zwischen Interrupts und normalem Kontrollfluss synchronisiert werden muss.

  • Threadwechsel-Mechanismus implementieren (Zugriffsfunktionen auf toc)
  • Dispatcher implementieren
  • Scheduling-Strategie (Klasse Scheduler) implementieren

(A) Threadwechsel

Der Threadwechsel-Mechanismus greift auf die toc Struktur zu, um den Threadkontext zu sichern bzw. wiederherzustellen. Dafür werden die Funktionen toc_switch(), toc_go(), toc_settle() und die Klasse Thread implementiert. Die toc-Funktionen müssen in Assembler implementiert werden. Es müssen lediglich die Instruktionen mov und ret verwendet werden.

Die Stacks für Threads sollen global im Speicherabbild bereitgestellt werden. Die Testanwendungen sollen nach einigen Anweisungen in den nächsten Thread wechseln, indem sie toc_switch() mit bekanntem Nachfolger aufrufen.

(B) Dispatcher

Der Dispatcher ist ein Interface auf die toc-Zugriffsfunktionen und ermöglicht einen angenehmeren Umgang mit der toc-Struktur. Die Threads sollen nun den Threadwechsel mit dem Dispatcher ausführen, immer noch mit bekanntem Nachfolger.

(C) Scheduler

Als Letztes soll der Scheduling-Algorithmus implementiert werden. Ausreichend für die Aufgabe ist hierbei eine einfache First-Come-First-Served (FCFS)-Strategie, bei der die Threads in eine Queue angehängt werden und beim Wechsel auf den nächsten Thread immer der Erste in der Queue ausgewählt wird. Der Scheduler implementiert die Policy und soll die Mechanismen des Dispatchers verwenden. Die Threads müssen nun dem Scheduler bekannt gemacht werden. Beim kooperativen Umschalten in den Threads werden nun die Methoden des Schedulers verwendet, sodass sich die Threads nicht mehr gegenseitig kennen müssen.

In der Mehrkern-Variante werden die Threads ebenfalls alle in eine einzige Ready-Queue eingereiht, analog zum Einkern-Pendant. Allerdings müssen die Aufrufe an den Scheduler zwischen den Prozessoren synchronisiert werden, damit zwei Prozessoren nicht gleichzeitig die Datenstrukturen des Schedulers modifizieren. Wichtig ist, dass ein gerade laufender Thread auf dem einen Prozessor nicht vorzeitig für die Ausführung auf einem anderen bereitgestellt werden darf.

Beim Testen sollte die Mehrkern-Variante zunächst nur auf einem Prozessorkern ausgeführt werden. Erst wenn das problemlos funktioniert, sollten die Applikationsprozessoren hinzu genommen werden.

In Aufgabe 4 nehmen wir an, dass immer genügend Threads zur Verfügung stehen, d.h., dass die Ready-List niemals leer sein kann. Diese Voraussetzung muss dann in den Testanwendungen auch immer erfüllt sein! Es empfiehlt sich dabei, den Threadwechsel intensiv mit verschieden vielen Threads zu testen.

Klassenübersicht

dot_a4.png
Klassenübersicht für Aufgabe 4

Hilfen und Dokumentation