3 - Aufgabe 4: Threadumschaltung [ID:36121]
50 von 167 angezeigt

Bis jetzt hatten wir in unserem Stubs einen festen Faden pro CPU, haben also für jede

Anwendung einen Kern exklusiv verwendet.

Das wollen wir in dieser Aufgabe mittels kooperativen Scheduling so ändern, dass wir quasi beliebig

viele Anwendungen gleichzeitig laufen lassen können.

Im Beispiel laufen nur 9 Zähleranwendungen parallel.

Dabei wird in der Ausgabe für jeden Kern eine eigene Farbe verwendet, um das Durchwechseln

zu verdeutlichen.

Externe Geräte wie die Tastatur bleiben natürlich auch weiterhin aktiv.

Für die Umsetzung müssen wir nun erstmal down the rabbit hole und sowohl tiefer in

die x86 Architektur als auch die System5 API einarbeiten, um in Assembler einen Kontextwechsel

implementieren zu können.

Im Anschluss sollen die Anwendungen so umgebaut werden, dass diese als Threads in einem Scheduler

verwaltet werden können.

Diese Verwaltung soll im Ordner thread bereitgestellt werden.

Der systemneue Kontextwechsel wird in machine implementiert.

Der Scheduler erlaubt Threads zur Ausführung dynamisch hinzuzufügen und wieder zu entfernen,

mittels einer Liste von Zeigern auf Thread-Objekten.

Mit guarded Scheduler gibt es eine einfache Systemaufruf Schnittstelle, damit dies auch

von Anwendungen selbst gesteuert werden kann, zum Beispiel das Beenden einer anderen Anwendung.

Die Anwendungen selbst sind von der Klasse thread-abgeleitet und werden in der Methode

Action implementiert.

Diese Methode ist in thread als pure virtual deklariert, muss also zwingend in jeder Ableitung

implementiert werden.

Eine Anwendung, welche das erste Mal per Kontextswitch eingelastet wird, soll ihre Ausführung bei

der Methode Action beginnen.

Wir bräuchten also die Adresse dieser Methode als Einsprungsfunktion.

Allerdings ist diese Adresse gar nicht zu trivial zu ermitteln, wenn wir nur den Pointer

zum thread-Objekt haben.

Sie ist ein virtueller Member, die tatsächliche Adresse der Funktion wird also dynamisch zur

Laufzeit durch die Vtable der Tabelle virtueller Methoden ermittelt, abhängig von welcher

Anwendung das Objekt tatsächlich ist.

Und wie so eine Vtable aufgebaut ist, ist natürlich wieder nicht im C++-Standard spezifiziert,

sondern abhängig vom jeweiligen Übersetzer.

Wir wollen aber eine generische Lösung, versuchen also gar nicht erst selbst diese Struktur

nachzulaufen, sondern lassen den Übersetzer den entsprechenden Code generieren, mittels

der Hilfsfunktion kickoff.

Diese bekommt als Parameter den Zeiger auf den thread und ruft damit dann Action auf.

Der Übersetzer muss für diesen Aufruf in kickoff entsprechend selbst die Auflösung

mittels der Vtable einbauen.

Unsere Einsprungsfunktion ist somit nun also nicht die Methode Action selbst, sondern kickoff,

welches dann eben diese Methode aufruft.

Und entsprechend müssen wir auch den Stack vorbereiten, was wir über die Funktion prepare

context erledigen.

Diese erhält als ersten Parameter die Adresse des Top of Stack, also das obere Ende des

jeweiligen Stacks.

Dazu soll für jeden Thread ein 4096 Byte großer Speicher reserviert werden.

Der zweite Parameter ist der Funktionszeiger zur eben erwähnten kickoff-Funktion, welcher

mit den in param spezifizierten Parameter aufgerufen wird.

Der Rückkabewert ist die Adresse des letzten Eintrags, die auf diesem Stack hinzugefügt

wurde, somit also der initiale Stackpointer für den Thread.

Teil einer Videoserie :
Teil eines Kapitels:
Threadumschaltung

Zugänglich über

Offener Zugang

Dauer

00:11:58 Min

Aufnahmedatum

2020-08-12

Hochgeladen am

2021-09-20 19:16:12

Sprache

de-DE

Tags

betriebssysteme operating systems stubs
Einbetten
Wordpress FAU Plugin
iFrame
Teilen