Autor Thema: Spezialisierter GC  (Gelesen 8251 mal)

scanish

  • Beiträge: 11
    • Profil anzeigen
Gespeichert
« am: 06. November 2009, 20:16 »
Hallo,

Ich wollte mal ein paar Experten dazu befragen, bevor ich mich an die Konzipierung mache.
Mein Kernel hat bisher Keyboard und einen einfachen Bildschirm-Support (also das einfachste). Was ich wollte, war, den Kernel sofort in einen Interpreter für meinen LISP-Dialekt überzuleiten, so dass die Konsole praktisch der Interpreter ist. Dann sind die Befehle praktisch LISP-Funktionen.

Alle LISP-Daten sind natürlich Listen, die ich mit einen GC verwalten wollte. Dieser alleine Wäre kein Problem, da alle Elemente der verketteten Liste gleich groß sind und ich daher die Elemente aus einem großen Array picken kann, verwaltet mit einer Bitmap.

Aber ich brauche auch String-Daten - eben für strings, symbolnamen und die Closures. Ich weiß nicht genau, wie ich diese verwalten soll.

Sollte ich vielleicht 2 GCs basteln, einer für listen und einer für "sonstiges"? Oder einen komplizierten, der alle Datentypen verwalten kann (auch wenn ich nicht genau weiß, wie dieser aussehen sollte). Ich wollte nur fragen, ob ihr dazu professionelle Meinungen habt, die mir helfen könnten.

Danke.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 09. November 2009, 09:40 »
Erstmal willkommen im Forum. :)

Wenn ich es richtig verstehe, hat dein Problem noch gar nichts mit dem Garbage Collector zu tun, sondern einfach nur damit, den freien Speicher zu verwalten und unterschiedlich große Objekte zuzulassen. Du solltest dir dazu mal anschauen, wie malloc/free üblicherweise implementiert werden. Das entscheidende Stichwort ist die Freispeicherliste: Am Anfang von jedem freien Speicherbereich schreibst du einen kleinen Header, der enthält, wie groß der freie Bereich ist, und ein Pointer auf den nächsten freien Bereich (also einfach eine verkettete Liste aller freien Bereiche). Beim Reservieren von Speicher gehst du einfach die Liste durch und nimmst den ersten Bereich, der groß genug ist (es gibt natürlich auch andere Strategien, aber first-fit ist gar nicht so schlecht).

Wenn du sehr viele Objekte vom gleichen Typ hast, dürfte es sich trotzdem lohnen, einen gesonderten Speicherpool dafür herzunehmen. Bei gleich großen Objekten fragmentiert der Speicher nicht und die Allokation geht wesentlich schneller (der erste freie Speicherblock passt sofort).
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

scanish

  • Beiträge: 11
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 09. November 2009, 11:27 »
Danke, ist mir auch irgendwie aufgefallen, dass ich eigentlich einen Memory Manager meine. Aber ich will eben auch, dass während der Interpretation speicher wieder freigelegt wird.

Außerdem weiß ich noch nicht, ob nun die String-Daten oder die Listen-Daten überwiegen, daher wären ja die Speicherpools mit fester Größe keine so gute Idee, oder? Natürlich könnte ich ja die LISP-Strings als Listen aus char darstellen...

Aber danke für die Antwort, ich sehe mir erstmal ein klassisches malloc an.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 09. November 2009, 11:29 »
Du kannst doch einfach gleichzeitig zwei verschiedene Speicherpools haben? Einer gibt die konstant großen Objekte für die Listen raus und der andere macht ein dynamisches malloc.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

scanish

  • Beiträge: 11
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 09. November 2009, 11:53 »
Müssten die denn nicht konstant groß sein während der gesamten laufzeit, damit die sich nicht untereinander stören? Wenn ein Pool über den speicher fragmentiert ist, ist der vorteil dahin.

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 09. November 2009, 11:58 »
Du verwaltest einfach mehrere Pools für den Speicher fester Größe, und wenn alle voll sind, holst du dir einen weiteren vom Allokator (notfalls von dem anderen für dynamischen Speicher).
Dieser Text wird unter jedem Beitrag angezeigt.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 09. November 2009, 12:57 »
Ich bin davon ausgegangen, dass sich jeder Pool bei zusätzlichen Bedarf ein ordentliches Stückchen Speicher holt - also in Einheiten von der Größe mindestens einer Page, bei entsprechendem Bedarf gern auch mehr.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

scanish

  • Beiträge: 11
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 09. November 2009, 21:38 »
Ich wollte ohne paging auskommen, aber wäre dass dann nicht besser? Ein pool ist immer zusammenhängend mit den pages, das klingt doch verlockend.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 09. November 2009, 22:30 »
Hm, das hat eigentlich nichtmal zwingend mit Paging zu tun, nimm einfach große Speicherbereiche von vielleicht 4k bis 32k. Die Pools müssen ja nicht unbedingt zusammenhängend sein.

Andererseits wird es mühsam, Multitasking ohne Paging umzusetzen. Willst du da voll auf Segmentierung gehen oder was sind deine Pläne?
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

scanish

  • Beiträge: 11
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 09. November 2009, 22:51 »
Mein Plan ist - auch wenn es jetzt absolut unnütz klingt - eine Art LISP-Machine. Der Kernel ist praktisch nur ein Interpreter, und die Interpreter eben eine Prozedur. Erstmal soll es single-tasked sein, aber es spricht eben nichts dagegen, dass mehrere Instanzen des Interpreters laufen (die praktisch vom interpreter gestartet werden). Diese würden dann alle auf den selben Pool zugreifen für die Daten, und weil die Programme alle LISP sind, ist eigentlich egal, woher die Daten kommen - sind ja alles listen und pointer gibt es nicht.

--Aber vorerst muss das alles liegen bleiben. Seid dem Update spuckt der ld nur noch einen 1 MB kernel aus, und ich weiß nicht warum. Es hat wohl damit zu tun, dass ich eben 1 MB als Grenze angebe beim Linken, aber vor dem Update hat das super funtioniert. Ich hab das linkerscript ein paar mal umgestellt, aber er kompiliert die 0x100000 in alle Addressen mit ein. Das wiederum lädt der GRUB nicht mehr, also totalverlust  :-P

scanish

  • Beiträge: 11
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 11. November 2009, 20:26 »
Ich glaub dazu muss ich gleich mal einen neuen Thread aufmachen... ich krieg meinen Kernel nicht mehr gestartet bie gleichem code und setup!  :cry:

scanish

  • Beiträge: 11
    • Profil anzeigen
Gespeichert
« Antwort #11 am: 14. November 2009, 14:34 »
Noch ne Frage:

Ein absolut simpler Memory Manager wäre doch einfach einfach ein Pointer, der auf das ende des kernels zeigt. Wenn man zB 8 byte haben will, wird der pointer zurückgegeben und um 8 byte erhöht.
Natürlich ist das absolut unpraktisch, aber wäre doch für den anfang einfach genug.

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #12 am: 14. November 2009, 14:42 »
Ja, der würde für den Anfang durchaus reichen. So ein einfacher Allokator kann es später auch erleichtern einen komplizierteren Allokator zum Laufen zu bringen.
Dieser Text wird unter jedem Beitrag angezeigt.

 

Einloggen