Moin Moin liebe Leute, willkommen zum nächsten Video zur Vollesusreihe Betriebssysteme.
Weiter soll es gehen mit CoRotinen, Fäden und zwar in diesem Kapitel, wie man die jetzt
implementiert.
Wir haben uns angeguckt, was CoRotinen so grob sind.
Jetzt schauen wir mal, wie man sie dann auch wirklich verwirklichen kann.
Also Idee erstmal, um mit euch reden zu können, eine kleine Benamung.
Also worum es hier gehen soll, sind sogenannte Fortsetzungen bzw. im englischen Continuations.
In dem Sinne, dass man sagt, das ist etwas, was man sich merken muss, wenn man dann ein
Unterprogramm, eine CoRotine, ein Prozess oder was auch immer fortsetzen will.
Also was braucht man typischerweise?
Man braucht einen Programmzähler, logischerweise, sonst weiß man nicht, wo es weitergeht.
Man hat vielleicht schon in irgendwelchen Registern Zwischenergebnisse gespeichert,
also braucht man auch die Werte wieder.
Vielleicht andere lokale Variablen auf dem Stack, die braucht man wieder.
Also der Kontrollflusszustand sozusagen.
Das ist das, was man sich irgendwie merken muss.
Da gibt es Sprachen, die kennen sowas als eigenes Sprachmittel.
Haskell beispielsweise, Schieben gibt es auch sowas.
In C, C++ gibt es das in dem Sinne nicht.
Müssen wir uns also selber bauen.
Gucken wir uns das mal an, wie das mit den Continuations, mit den Fortsetzungen bei normalen
Unterprogrammen gemacht ist.
Also bei Routinen, jetzt nicht bei CoRotinen, sondern ganz normalen Routinen.
Ihr erinnert euch, hoffe ich, an den Stackaufbau, den wir euch zum Beispiel mal in den SP gezeigt
haben.
Auf dem Stack liegen immer typischerweise die Aufrufparameter der aktuell laufenden Funktionen.
Der Rückkehrprogrammcounter, die Returnadresse.
Ja, je nach Architektur häufig noch ein sogenannter Framepointer, der immer auf diesen sogenannten
Rahmen hier zeigt.
Und die laufende Funktion hat vielleicht noch lokale Variablen.
Nehmen wir mal das als Beispiel und F läuft jetzt gerade noch, also F läuft und hat hier
diese Umgebung.
Man kann diesen Stackframe benutzen.
Was passiert jetzt, wenn die Funktion F jetzt beispielsweise G aufruft?
Es werden auf den Stack gelegt, typischerweise die Parameter für die Funktion.
Und bevor die Verzweigung nach G passiert, muss die Rückkehradresse von F auf den Stack
gepusht werden.
Damit, wenn G später mal zurückkehrt, klar ist, wo G hinspringen soll, nämlich zu der
Adresse, die hier gespeichert wurde.
Die Funktion G, die jetzt losläuft, die wird jetzt den Framepointer, den alten Framepointer
sichern und den neuen Framepointer auf den neuen Stackerrahmen zeigen lassen.
Und der Stackpointer, ihr seht, der zeigt immer weiter auf niedrigere Adressen.
Jetzt vielleicht im letzten Schritt, das G ruft jetzt noch H auf.
Dann kommen erst mal die Parameter auf den Stack, Rückkehradresse auf den Stack und
das laufende G pusht sich noch den alten Framepointer, damit es den ändern kann und pusht sich ggf.
noch lokale Variablen.
Das Ganze entsprechend wieder rückwärts.
Also wenn H jetzt einen Return aufruft, dann muss es erst mal seine lokalen Variablen abräumen,
den Framepointer restaurieren.
Das ist das, was jetzt H selber noch machen muss.
Presenters
Zugänglich über
Offener Zugang
Dauer
00:26:28 Min
Aufnahmedatum
2020-12-04
Hochgeladen am
2020-12-04 17:40:17
Sprache
de-DE
8. Kapitel der Vorlesung Betriebssysteme.