Ist jetzt von dir abgeschaut bluecode. Wenn man das so machen sollte, warum?
Sollen/Müssen tut man garnichts. Es gibt natürlich noch andere (mögliche und vllt sogar andere sinnvolle
) Möglichkeiten. Meine Kriterien waren folgende:
* möglichst wenig Speicherverbrauch für die Datenstrukturen zur Verwaltung
* möglichst effizienter Algorithmus zur Allokation/Deallokation von Speicherbereichen
Deshalb die verschiedenen Stacks für alles >16MB, da ein Stack eine konstante Zeit zur Allokation/Deallokation [einer Page] (aka O(1) in
Landau-Notation) und geringen Speicherverbraucht (bzw. kein Speicherverbrauch, da man den Stack selbst langsam deallozieren kann, er besteht ja selbst aus Pages), außerdem ist m.E. ein Stack am einfachsten zu Erstellen, da man einfach die freien Pages die man draufpusht dazu verwendet den Speicherplatz für den Stack herzubekommen.
Eine Bitmap ist meiner Erfahrung nach ein ziemliches Gefrickel, da man da meistens statischen einen relativ großen Teil des physischen RAM für selbige verwendet (Mag sein, dass es da bessere Implementationen gibt, das will ich an dieser Stelle nicht ausschließen, aber ich habe glaub ich noch keine gesehen). Mit einer Bitmap bekommt man auch nur lineare Zeit zur Allokation [einer Page] hin (also O(n) in Landau-Notation) [trotzdem aber konstante Zeit zur Deallokation, nur um das auch zu erwähnen]. Außerdem ist dann der Speicherverbrauch größer als bei einem Stack, da man die Bitmap nicht mit der Zeit deallozieren kann.
So, warum nun 3 verschiedene Stacks. Das hat folgenden Grund: Teilweise braucht man Speicherseiten, die eben bestimmten Bedingungen an die Größe der Adresse genügen müssen. Beispielsweise braucht man einem 32bit PCI Gerät keine 36 oder gar 64bit Adressen andrehen. Auch kann man bei PAE für Page Directories keine 36bit Adressen verwenden, da Cr3 trotz allem nur 32bit hat. Deshalb sind m.E. drei Stacks dafür sinnvoll. Bei jeder Allokation wird dann angegeben welchen Bedingungen die Speicherseite genügen muss.
Die drei Stacks decken nun Allokationen ab, welche
nicht physisch kontinuierliche Pages brauchen, da dies mit einem Stack nicht effizient implementierbar ist.
Deshalb nun die zwei (ich nenn es mal) "Range-Lists" (also Liste mit Startadresse und Größe eines Speicherbereichs), welche die Speicherbereiche <1MB bzw zwischen 1MB und 16MB verwalten und physisch zusammenhängende Speicherallokationen ermöglichen. Warum solche Rangelists? Weil die solche Allokationen selten sind und damit die Fragmentierung (und damit die Größe der Rangelist) gering ist und außerdem ist die Allokation linear (also O(n), aber mit kleinem n, da es wenig Einträge in der Liste hat). Bei der Komplexität der Deallokation bin ich mir grad nicht ganz sicher, aber ich glaube die ist bei mir auch linear (da Speicherbereiche welche zusammenhängen in einen EIntrage in der Liste gemergt werden). Bei einer Bitmap hingegen hat man eine langsamere Allokation (zwar auch O(n) afaik, aber eben größeres n, da n die Anzahl der verwalteten Pages ist) und die benötigt für meinen bzw. den Verwendungszweck auch mehr Speicher als die Rangelist (gefühlt/geschätzt!).
Warum 2 Rangelist? Teilweise braucht man Speicher <1MB, zB. wenn man über VBE (VESA BIOS Extensions) eine Modiliste bekommen möchte. Außerdem möchte man dann natürlich nicht, dass andere Geräte denen <16MB ausreichen würde <1MB bekommen, sonst geht einem evtl. im entscheidenden Moment der Speicher aus.
Ob sich das alles am Ende bewährt ist eine andere Frage, die ich noch nicht beantworten kann, da das für sich genommen natürlich alles toll klingt, aber fraglich ist zB. was passiert wenn einem zB die >16MB Speicherseiten ausgehen, obwohl noch einige in den Rangelists wären. Da muss man sich dann natürlich zu gegebener Zeit nochmal Gedanken machen.
Also die Idee mit den 4 voneinander abhängigen Listen ist sicherlich nicht schlecht, allerdings leider immer sehr unüberschaubar, da ich Listen ja schon vorher immer wieder Programmiert habe
Wenn du deine Funktionen zur Listenmanipulation sehr allgemein fasst (wie zB die Listenimplementation von LOST für CDI [= Common Driver Interface] bzw. meine C++ Template Implementation für pedigree), dann brauchst du nicht mehrmals das gleiche wieder programmieren.
Und generell gesehen ist die Liste mit dem dynamischen Array aka Vector eine der einfachsten Datenstrukturen überhaupt. Ich denke, dass man das schon hinkriegen sollte
Ich hoffe das war ein bisschen holfreich
btw. das sind die Gründe warum
ich das so mache wie ich es eben mache. Ich erhebe da natürlich keinen Anspruch auf Vollständigkeit & Fehler-/Problemfreiheit.