Autor Thema: Nicht unterbrechbarer Kernel  (Gelesen 13344 mal)

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #20 am: 11. October 2011, 22:12 »
Hallo,


Ist das ein Widerspruch? Syscalls laufen doch in der Regel auch durch ein bisschen Assemblercode?
Ja, natürlich, der Compiler erzeugt ja nicht direkt den Syscall-Befehl. Warum eigentlich nicht? Das wäre doch mal ne colle Sache.
In meinem Fall ist bei allen normalen Syscall-Funktionen (in der libOS) ein Stück Inline-Assembler drin das eben den SYSCALL-Befehl enthält und dafür sorgt das die Aufrufkonvention passt, in der Yield-Funktion ist dagegen ein Stück Inline-Assembler drin das den YIELD-Befehl enthält. Ich hatte irgendwann mal die tolle Idee das wenn ich eh einen CPU-lokalen Timer habe der einen eigenen Exception-Vector hat und auch nicht über den IRQ-Controller o.ä. geht (also auch kein EOI o.ä. benötigt) dann kann ich diesen Mechanismus auch gleich mit einen extra Befehl verfügbar machen, wimre hab ich mich dabei von irgendeiner anderen CPU inspirieren lassen aber ich weiß nicht mehr von welcher CPU-Architektur (diese Idee ist also nicht ganz von mir aber ich finde die trotzdem toll und sehr zweckdienlich). Für meine CPU und auch den Scheduler macht es absolut keinen Unterschied ob die spezielle Yiel-Exception gekommen ist weil der Zeitscheiben-Counter abgelaufen ist oder ob ein YIELD-Befehl kam (das könnte der Kernel auch nur feststellen indem er sich den als letztes im User-Mode ausgeführten Befehl anschaut) so das ich damit auch nicht solche Probleme haben kann wie FlashBurn mit kämpft. Den richtigen Timer im Chipsatz (eine Art HPET, der auch über den IRQ-Controller läuft) wird nicht für die Zeitscheiben verwendet. Nebst dessen das es bei mir auch nur einen einzigen Befehl gibt der den Wechsel vom System-Mode in den User-Mode ermöglicht so das ich da auch keine Unterscheidung benötige (wie auf x86 mit SYSRET vs. IRET).

Oder anders gesagt: Was designst du anders und wieso ist ein Syscall falsch/nicht designt?
Naja, mein Vorteil ist das ich mir anschaue welche Probleme ich in der SW eventuell haben könnte und dann überlege ob es da nicht eine elegante Möglichkeit gibt das gleich in HW zu umgehen, das geht natürlich nicht wenn man für eine fest vorgegebene Architektur ein OS entwickelt. Mein RFS-Befehl (mit dem man vom System-Mode in den User-Mode kommt) ist auch absolut unabhängig vom Stack so das der auch innerhalb einer beliebig tiefen Unterfunktion funktioniert (der aktuelle System-Mode-Stack wird dann einfach verworfen) so das ich auch nicht diese typischen Assembler-Stubs, wie die 256 bei x86, benötige.
Meine Bemerkung mit dem "nicht gut designt" war auch nicht so ganz ernst gemeint, mir ist schon klar das keiner von Euch um die Probleme und Altlasten bei x86 einfach so drumherum designen kann. ;)


Grüße
Erik
Reality is that which, when you stop believing in it, doesn't go away.

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #21 am: 12. October 2011, 02:28 »
Zitat von: erik
Du kennst doch sicher das KISS-Prinzip.
Ja, aber ... ;)

Wie man das nun interpretiert ist so eine Sache, es liegt auch immer im Auge des Betrachters. Das hatten wir doch erst, wozu dann nen Baum nehmen, der ist nun wirklich nicht mehr KISS, sondern die Liste oder das Array.

Die ganzen technischen Sachen sind nicht mehr KISS. Wenn man mehr Effizienz will, muss man leider oft auf KISS verzichten. Denn KISS wäre bei einem OS mMn ganz eindeutig ein nicht unterbrechbarer Monolith, aber wirklich effizient und praktikabel ist das nicht.

Das ist, mit Verlaub, Blödsinn. Weiter sage ich dazu nichts.

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #22 am: 12. October 2011, 09:00 »
Zitat von: svenska
Das ist, mit Verlaub, Blödsinn. Weiter sage ich dazu nichts.
Wieso ;)

Für mich ist alles was irgendwie komplex ist nicht mehr KISS, also eigentlich fast alles moderne (vorallem technische). Es würde alles auch einfacher gehen, aber es wäre halt nicht so effizient (dazu sage ich nur Locking und lock-free Algos).

Zitat von: erik
Ja, natürlich, der Compiler erzeugt ja nicht direkt den Syscall-Befehl. Warum eigentlich nicht? Das wäre doch mal ne colle Sache.
Würde gehen, wenn man nicht erst noch bestimmt Dinge machen müsste (was ansich auch kein Problem ist), aber du würdest dich damit auf bestimmte CPUs festlegen (auch erstmal kein Problem), könntest dann eventuelle neue Opodes auf neueren CPUs nicht mehr nutzen und müsstest, zumindest unter 32bit 2 Varianten, einmal für Intel und einmal für AMD zur Verfügung stellen und wozu den Aufwand, wenn man auch ne mini-Funktion vom OS nutzen kann?

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #23 am: 12. October 2011, 10:18 »
Hallo


Wieso ;)
Du scheinst Simplizität immer als absolute Simplizität anzunehmen und nie in Relation zur Problemstellung zu setzen.
Wer einfach nur ein klein wenig elektrische Energie benötigt kommt mit einem Wasserrad (mit Generator) oder gar mit 2 unterschiedlichen Metaldräten (als Thermoelement) und etwas Feuer aus. Wer aber eine größere Menge an elektrischer Energie haben will und dazu noch unabhängig von der Umwelt sein muss und dazu auch noch eine hohe Effizienz benötigt der muss sich schon ein komplexes Kraftwerk zulegen. Absolut gesehen ist das Kraftwerk natürlich ungleich komplexer als das Wasserrad oder gar das Thermoelement aber in Relation zum Schwierigkeitsgrad der Aufgabenstellung kann das Kraftwerk immer noch im Rahmen von KISS sein.
Auch beim Vergleich zwischen Micro-Kernel und Monolith ist meiner persönlichen Meinung nach im Punkt Simplizität eher der Micro-Kernel der Gewinner, da wird die Komplexität aufgebrochen und auf mehrere unabhängige User-Mode-Prozesse verteilt, getreu dem Motto "Teile und Herrsche".

Wenn Du jede Form von Komplexität grundsätzlich ablehnen möchtest dann solltest Du Dir lieber ein schöne Hölle suchen und auf so komplexe Dinge wie Elektrizität verzichten. ;)
Auf der anderen Seite sind die Lösungen die Du hier propagierst oft reichlich komplex, vor allem deutlich komplexer als die Aufgabenstellung eigentlich erfordert. Ich verstehe z.B. nicht wozu Du verschiedene Arten von Threads mit unterschiedlichen Speicheranforderungen haben möchtest. Bei mir werden Threads nur Attribute haben, z.B. Dämon-Thread (die den Prozess-Tod nicht blockieren) oder PopUp-Thread (vom IPC-System), aber diese Attribute spielen nur in einer eng begrenzten Anzahl an Situationen eine Rolle (z.B. ein PopUp-Thread darf sich nicht einfach selbst killen, was sollte in so einer Situation das IPC-System dem Caller als Antwort geben?) und werden ansonsten ignoriert (weder der Scheduler noch die Exceptionhander oder der generische IRQ-Handler interessieren sich für die Thread-Attribute wenn sie einen Thread von der CPU schmeißen u.ä.).

Würde gehen, wenn man nicht erst noch bestimmt Dinge machen müsste (was ansich auch kein Problem ist), aber du würdest dich damit auf bestimmte CPUs festlegen (auch erstmal kein Problem), könntest dann eventuelle neue Opodes auf neueren CPUs nicht mehr nutzen und müsstest, zumindest unter 32bit 2 Varianten, einmal für Intel und einmal für AMD zur Verfügung stellen
Der Compiler weiß ganz genau für welche CPU er compiliert und optimiert, der gcc unterscheidet auch zwischen AMD und Intel. Solche Dinge wie ein SYSCALL-Befehl gehören natürlich in den CPU-spezifischen Teil des Compilers. Aber da der Syscall auch vom OS (eventuell sogar von der konkreten Version des OS) abhängig ist ist es natürlich Blödsinn sowas in den Compiler fest einzubauen.

wenn man auch ne mini-Funktion vom OS nutzen kann?
Hä? Du meinst ne Minifunktion aus der libOS? Also die die das kleine Stück Inline-Assembler enthält.


Grüße
Erik
Reality is that which, when you stop believing in it, doesn't go away.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #24 am: 12. October 2011, 10:19 »
Erik: Als was würdest du denn den YIELD-Befehl bezeichnen, wenn nicht als eine Art Sonder-Syscall? Für mich macht das die Sache nur uneinheitlicher, weil du nur noch fast alle Syscalls über dieselbe Instruktion abwickelst.

Wobei mir gerade auffällt, das ein Syscall auf neueren (und auch einigen älteren) CPUs wesentlich schneller als ein "int TIMER_IRQ" ist.
Falls dein OS den Timer benutzt, um seine Uhr zu aktualisieren, wäre ein manueller Aufruf des Timerinterrupts sowieso nicht so geschickt... (Auf Eriks Architektur geht das dann grundsätzlich nicht)

Zitat
Würde gehen, wenn man nicht erst noch bestimmt Dinge machen müsste (was ansich auch kein Problem ist), aber du würdest dich damit auf bestimmte CPUs festlegen (auch erstmal kein Problem), könntest dann eventuelle neue Opodes auf neueren CPUs nicht mehr nutzen und müsstest, zumindest unter 32bit 2 Varianten, einmal für Intel und einmal für AMD zur Verfügung stellen und wozu den Aufwand, wenn man auch ne mini-Funktion vom OS nutzen kann?
Blödsinn. Erstens ist es sowieso immer Aufgabe des Compilers, die passenden Opcodes rauszusuchen. Wenn du die benutzen willst, brauchst du halt einen aktuellen Compiler. Wo ist das Problem?

Und du brauchst auf x86 auch im PM keine zwei Varianten.
« Letzte Änderung: 12. October 2011, 10:29 von taljeth »
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #25 am: 12. October 2011, 12:18 »
Hallo,


Als was würdest du denn den YIELD-Befehl bezeichnen, wenn nicht als eine Art Sonder-Syscall? Für mich macht das die Sache nur uneinheitlicher, weil du nur noch fast alle Syscalls über dieselbe Instruktion abwickelst.
Meiner persönlichen Meinung nach ist die Funktionalität von Yield etwas anderes als ein typischer Syscall, es wird ja kein Service o.ä. angeboten, außerdem wird Yield üblicherweise von einer Hardware-Komponente angetriggert und hat daher eher den Charakter eines IRQs. Für mich ist der YIELD-Befehl eher sowas wie UD2 bei x86, eine Art Sonder-Weg für eine normale Exception. Bei mir haben die verschiedenen Eintrittsmöglichkeiten in den Kernel jeweils individuelle (konfigurierbare) Einsprungspunkte (ein paar für die Exceptions, einen für Yield, einen (eigentlich zwei aber das ist hier jetzt mal uninteressant) für den Syscall und dann kann der IRQ-Controller noch den Einsprungspunkt für den aktuell gelieferten IRQ vorgeben (was üblicherweise immer der selbe ist)), bei dem Einsprungspunkt für Yield gibt es zwei Möglichkeiten wie der angetriggert werden kann, einmal per Hardware wenn der Zeitscheiben-Counter bei 0 angekommen ist und zum zweiten mit dem YIELD-Befehl. Mir ist klar das der YIELD-Befehl eine Art Außname darstellt weil er so einen zusätzlichen Sonderweg in den Kernel bietet aber für diesen speziellen Zweck ist das IMHO gerechtfertigt, mit dem YIELD-Befehl kommt die CPU direkt im Scheduler-Code an und spart sich so unnötige Befehle. Darüber hinaus ist der Code am Einsprungspunkt für Yield ein anderer als für den Syscall, bei ersterem geht es darum möglichst schnell den aktuellen Thread-Zustand von der CPU runter zu holen und im Thread-Descriptor zu sichern wogegen es bei letzterem darum geht nur ein paar Register auf dem Kernel-Stack zu sichern damit die Syscall-Services ein paar freie Register zum arbeiten haben. Die zusätzliche Komplexität (in der Hardware) für diesen Schnell-Weg ist IMHO minimal da ich den Yield-Mechanismus für den Zeitscheiben-Counter ja eh benötige, wenn ich das über den Syscall machen würde würde das in Software wohl mehr Aufwand bedeuten als so.

Falls dein OS den Timer benutzt, um seine Uhr zu aktualisieren, wäre ein manueller Aufruf des Timerinterrupts sowieso nicht so geschickt... (Auf Eriks Architektur geht das dann grundsätzlich nicht)
Ich hatte FlashBurn so verstanden das er diesen Timer exklusiv für die Zeitscheibe benutzt, wenn er den selben Timer auch für andere Dinge nutzt kann er sowieso nicht einfach blind bei jedem IRQ den Thread wechseln. Obwohl ich da auch bei SMP eindeutig die Notwendigkeit sehe dafür den Timer im Local-APIC zu nutzen und der hätte dann sowieso einen eigenen INT-Vector (unabhängig von allen anderen IRQs). Das man auf meiner Architektur, so wie auf den meisten anderen auch, nicht per Software einfach einen IRQ-Vector aufrufen kann ist natürlich richtig und auch gewollt (wegen der Sicherheit usw.), deswegen benötige ich ja auch extra den YIELD-Befehl um da gezielt eine klar definierte Ausnahme machen zu können.


Grüße
Erik
Reality is that which, when you stop believing in it, doesn't go away.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #26 am: 12. October 2011, 12:36 »
Meiner persönlichen Meinung nach ist die Funktionalität von Yield etwas anderes als ein typischer Syscall, es wird ja kein Service o.ä. angeboten
Es ist eine Funktion aus der API des Schedulers. Also ist es ein Syscall.

Zitat
außerdem wird Yield üblicherweise von einer Hardware-Komponente angetriggert und hat daher eher den Charakter eines IRQs. Für mich ist der YIELD-Befehl eher sowas wie UD2 bei x86, eine Art Sonder-Weg für eine normale Exception.
Nur dass ud2 nicht in normalen Codepfaden vorkommt (sondern eben nur, wo man sicherstellen will, dass eine (Nicht-)Instruktion nicht ausgeführt wird) und dass ein per Software getriggerter IRQ wesentlich krimineller als eine per Software getriggerte Exception ist.

Zitat
Bei mir haben die verschiedenen Eintrittsmöglichkeiten in den Kernel jeweils individuelle (konfigurierbare) Einsprungspunkte (ein paar für die Exceptions, einen für Yield, einen (eigentlich zwei aber das ist hier jetzt mal uninteressant) für den Syscall und dann kann der IRQ-Controller noch den Einsprungspunkt für den aktuell gelieferten IRQ vorgeben (was üblicherweise immer der selbe ist))
Es tut mir ja wirklich leid, aber an dieser Stelle muss ich dann auch dein Design mal kritisieren. ;)

Drei grundsätzlich verschiedene Möglichkeiten, einen Syscall zu machen, spricht dafür, dass dein Design nicht durchdacht genug ist, dass es eine einheitliche Lösung bieten kann. Wenn du mit Ausnahmen anfangen musst, ist die Basis nicht generisch genug. Wer sagt dir, dass Yield der einzige Syscall ist, der ein bisschen anders ist? Solltest du dann nicht Möglichkeiten bieten, ein paar verschiedene, frei definierbare Gruppen von Syscalls anzubieten? Ich weiß, dann landest du bald wieder bei der x86-IDT, aber vielleicht ist das ja doch alles nicht ganz so blöd (und Exceptions und IRQs kannst du ja nach wie vor zwingend separat halten).
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #27 am: 12. October 2011, 13:06 »
Ah, und noch eine Anmerkung, die ich machen wollte, dann aber beim Schreiben vergessen habe: Dass der Interrupt-Controller den Einsprungspunkt vorgibt, fühlt sich irgendwie komisch an und ich bin mir nicht sicher, ob das so eine tolle Idee ist. Aber was es auf jeden Fall ist, ist ein weiterer Fall, wo du nicht einheitlich arbeitest. Der Einsprungspunkt kommt einmal vom Interrupt-Controller, das nächste Mal von jeweils (im Speicher oder Registern konfigurierten?) unterschiedlichen Einsprungpunkten für die Exceptions, und genau drei Einsprungspunkte für n Syscalls (Wo sind die konfiguriert? Ist wenigstens das gleiche wie die Exceptions?), die dann im Kernel gemultiplext werden.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #28 am: 12. October 2011, 14:04 »
Hallo,


Es ist eine Funktion aus der API des Schedulers. Also ist es ein Syscall.
Hm, Ansichtssache. Der Punkt ist das ich für Yield trotzdem einen eigenen Einsprungspunkt in den Kernel benötige da der Zeitscheiben-Counter mit Sicherheit keinen Syscall initiieren wird. Wenn dieser dedizierte Einsprungspunkt dann eh vorhanden ist ist eine Zweitnutzung zur Steigerung der Effizienz zwar immer noch ein (kleiner) Konzept-Bruch aber in diesem konkreten Fall meiner Meinung nach absolut okay. Ich bleibe auch der Meinung das Yield, im Gegensatz zu allen anderen Syscalls, keinen Service anbietet.

dass ein per Software getriggerter IRQ wesentlich krimineller als eine per Software getriggerte Exception ist.
Dem kann und werde ich nicht widersprechen, das wäre ein billiger Trick für ein klein wenig mehr Effizienz (und im Fall das Syscalls über spezielle Befehle gehen auch etwas Code-Ersparnis für eine zusätzliche Return-Methode). Auf x86 gibt es noch genug andere Dinge die man durchaus als kriminell betrachten kann, da wäre dieser Trick zumindest in guter Gesellschaft.

Es tut mir ja wirklich leid, aber an dieser Stelle muss ich dann auch dein Design mal kritisieren. ;)
Nur zu.

Drei grundsätzlich verschiedene Möglichkeiten, einen Syscall zu machen, spricht dafür, dass dein Design nicht durchdacht genug ist, dass es eine einheitliche Lösung bieten kann.
Der Weg wie meine CPU in den Kernel-Modus wechselt ist immer der selbe (da hat x86 mit mit und ohne Error-Code schon mehr Vielfalt zu bieten), nur der Vector ist jedes mal ein anderer. Auch der Code der am jeweiligen Vector steht ist je nach Aufgabenstellung ein anderer, hier ist mir Effizienz eindeutig wichtiger als Einheitlichkeit (vor allem weil Einheitlichkeit ja nicht zwangsläufig Simplizität ergibt). Nebst dessen das ich immer noch bestreite das Yield ein echter Syscall ist (eine Hardware würde schließlich nie einen Syscall aufrufen). Yield ist IMHO ein Zwischending aus Exception und IRQ, stellt also gegenüber diesen 2 Basis-Konzepten eh schon eine Ausnahme dar.

Wer sagt dir, dass Yield der einzige Syscall ist, der ein bisschen anders ist?
Also mir fällt da nichts weiter ein. Wenn Du da eine Idee haben solltest dann ruhig raus damit. Eine einzige Ausnahme rechtfertigt auf jeden Fall noch nicht ein (deutlich) komplexeres Basis-System.

Solltest du dann nicht Möglichkeiten bieten, ein paar verschiedene, frei definierbare Gruppen von Syscalls anzubieten?
Da hätte ich dann aber immer noch das Problem das ich damit ja nicht den Yield-Exception-Vector erreiche aber das ist ja genau der Grund warum ich einen extra YIELD-Befehl haben will damit der in der CPU genau das selbe auslöst wie eine bestimmte HW-Komponente aber ohne eine HW-Komponente sein zu müssen. Ich könnte auch eine bestimmte Port-Adresse freigeben wo dann bei einem Schreibzugriff der Zeitscheiben-Counter auf 0 gesetzt wird und damit eine Yield-Exception auslöst aber auch das ist ein Sonderweg nur das der nicht primär das CPU-Design betrifft.

Ich weiß, dann landest du bald wieder bei der x86-IDT, aber vielleicht ist das ja doch alles nicht ganz so blöd
Mein Syscall-Befehl ist recht flexibel und es ist auch sehr Effizient möglich im Kernel direkt die richtige Funktion anzuspringen (dazu benötige ich nur 2 Assemblerbefehle). Ich hab sogar vorgesehen das die Syscall-Nummer nicht nur als Immed angegeben werden kann sondern auch aus einem Register kommen darf (quasi eine Art "INT AL").

und Exceptions und IRQs kannst du ja nach wie vor zwingend separat halten
Das sowieso, alles andere wäre ein pures Sicherheitsrisiko.

Dass der Interrupt-Controller den Einsprungspunkt vorgibt, fühlt sich irgendwie komisch an und ich bin mir nicht sicher, ob das so eine tolle Idee ist.
Dann schau Dich mal auf anderen Plattformen um, z.B. bei ARM gibt es auch einen Vectored-IRQ-Controller (VIC) der für jeden seiner IRQs einen individuellen Vector direkt an den CPU-Kern liefern kann, damit werden (gegenüber älteren ARM-CPUs ohne VIC) bei jedem IRQ gleich mal ein paar CPU-Takte eingespart weil die CPU nicht erst den IRQ-Controller befragen muss um welchen IRQ es sich handelt und dann aus einer Tabelle den Funktions-Vector holen muss (man spart also einen Peripherie-Zugriff und einen Speicherzugriff ein). Diese Idee ist nicht nur toll sondern auch flexibel, weil ich als IRQ-Controller-Designer dann immer noch entscheiden kann ob ich so viel Speicherkapazität vorsehe das jeder IRQ einen eigenen Vector bekommen kann (was für einen Monolithen ein echter Vorteil wäre weil man sich dort dann jegliche Form von Dispatcher-Code sparen kann) oder ob der immer den selben Vector liefern soll (was für einen Micro-Kernel keine Einschränkung darstellt weil dieser ja eh IPC-Messages verschickt und damit auch nur einen einzigen generischen IRQ-Handler hat). Das tollste ist aber das diese Flexibilität keine Änderung in der CPU erfordert, man kann also immer die selbe CPU mit verschiedenen IRQ-Controllern kombinieren um je nach Anwendung das Optimum aus Hardware-Kosten und Performance zu gewinnen.

Aber was es auf jeden Fall ist, ist ein weiterer Fall, wo du nicht einheitlich arbeitest.
Ja, das stimmt, zumindest etwas. Meine CPU hat grundsätzlich zwei Möglichkeiten den Einsprungspunkt in den Kernel zu bekommen, einmal aus globalen Controll-Registern (das wird für alle Exceptions und Syscall und Yield so gemacht, sind genau 11 Stück) und dann von Außen als Teil der Antwort des IRQ-Controllers (zusammen mit der IRQ-Nummer und der Anzahl der angelaufenen IRQs) wenn die CPU den IRQ vom IRQ-Controller abholt. Das hat aber nur Auswirkungen auf den Wert in R63 (meinem IP) wenn die CPU vom User-Mode in den Kernel-Mode wechselt, der restliche Zustand (wie z.B. der frische Kernel-Mode-Stack) ist immer identisch.

und genau drei Einsprungspunkte für n Syscalls
Wie kommst du auf 3? Für meinen einen Syscall-Mechanismus hab ich 2 Einsprungspunkte vorgesehen, eigentlich würde das auch mit einem gehen aber bei den zwein macht einer von beiden bestimmte Zusicherungen so das der Code da nichts prüfen muss und schneller zu den eigentlichen Service-Funktionen springen kann (mit nur 2 Assemblerbefehlen, wie oben schon erwähnt). Dieser Zusatz ist natürlich genau auf mein OS abgestimmt und ist im wesentlichen nur eine Hardwarebeschleunigung für etwas das man auch genauso (nur nicht so schnell) in Software machen kann.

die dann im Kernel gemultiplext werden.
Gemultiplext wird bei mir gar nichts im Kernel. Die verschiedenen Einsprungspunkte haben eigenständige Code-Pfade. Die CPU landet bei mir z.B. beim Yield direkt im Code des Schedulers der dann auch sofort seine Arbeit erledigt, es gibt da keine gemeinsame Basis wo alle Mode-Wechsel durch müssen.
Ich habe den subjektiven Eindruck das Du zu x86-lastig denkst. ;)


Grüße
Erik
« Letzte Änderung: 12. October 2011, 14:10 von erik.vikinger »
Reality is that which, when you stop believing in it, doesn't go away.

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #29 am: 12. October 2011, 14:18 »
Zitat von: erik
Du scheinst Simplizität immer als absolute Simplizität anzunehmen und nie in Relation zur Problemstellung zu setzen.
Ah, also subjektiv. Denn wer legt fest was relativ ist?

Dann zur Problemstellung, in meinem Fall heißt das, der Kernel soll MAP_NOW anbieten (es soll nicht irgendwie über den UserSpace gelöst werden) und der Kernel soll eine gewisse maximale Zeitspanne nicht mit Ints aus laufen.

Also entweder man nimmt KISS wörtlich und dann braucht man mMn auch nix besseres als ne Liste (lasse mich gerne eines besseren belehren) oder es ist abhängig von den Anforderungen.

Um mal wieder nen Autovergleich zu bringen. Willst du nen Auto das fährt brauchst du keine hoch-komplexen Motoren, wie wir sie heute haben. Willst du aber nen Auto das auch noch wenig Verbraucht, also effizient ist, brauchst du nen komplexen modernen Motor.
Selbst wenn es vllt einfache Grundprinzipien gibt, ist die Umsetzung dann meistens komplex.

Zitat von: erik
Ich verstehe z.B. nicht wozu Du verschiedene Arten von Threads mit unterschiedlichen Speicheranforderungen haben möchtest.
Anforderung -> max. Zeitspanne mit Int aus => der Code muss im Kernel unterbrechbar gemacht werden, wenn er Gefahr läuft zu lange zu brauchen.

Ich habe in dem Sinne auch nicht verschiedene Arten von Threads. Ich setze da nirgends ein Flag was sagt, du bist jetzt ein Kernel-Thread und du ein User-Thread (gut man könnte argumentieren, dass ich das indirekt mache).

Zitat von: erik
Bei mir werden Threads nur Attribute haben, z.B. Dämon-Thread (die den Prozess-Tod nicht blockieren) oder PopUp-Thread (vom IPC-System), aber diese Attribute spielen nur in einer eng begrenzten Anzahl an Situationen eine Rolle (z.B. ein PopUp-Thread darf sich nicht einfach selbst killen, was sollte in so einer Situation das IPC-System dem Caller als Antwort geben?) und werden ansonsten ignoriert (weder der Scheduler noch die Exceptionhander oder der generische IRQ-Handler interessieren sich für die Thread-Attribute wenn sie einen Thread von der CPU schmeißen u.ä.).
Das finde ich komplex. Wieso kannst du nicht nur eine Art von Thread haben :P

Zitat von: erik
Hä? Du meinst ne Minifunktion aus der libOS? Also die die das kleine Stück Inline-Assembler enthält.
Jap. Mir fällt auf, das immer nur von Open-Source ausgegangen wird. Wenn das Programm aber nur in binärer Form vorliegt (und man nicht den DAU entscheiden lassen möchte welche Version er braucht, ob Intel oder AMD), dann macht genau solch eine Funktion (wie es in Windows und ich möchte meinen auch in Linux verwendet wird) Sinn.

Auch möchte ich nicht mehrere Einsprungspunkte haben (einmal für Int, Syscall und Sysenter).

Zitat von: taljeth
Blödsinn. Erstens ist es sowieso immer Aufgabe des Compilers, die passenden Opcodes rauszusuchen. Wenn du die benutzen willst, brauchst du halt einen aktuellen Compiler. Wo ist das Problem?
Wie oben schon beschrieben, die Situation Programm liegt nur in binärer Form vor.

Zitat von: taljeht
Und du brauchst auf x86 auch im PM keine zwei Varianten.
Einmal Int, einmal Sysenter und einmal Syscall, macht schon 3 Varianten und alle im PM!

Zitat von: erik
Ich hatte FlashBurn so verstanden das er diesen Timer exklusiv für die Zeitscheibe benutzt, wenn er den selben Timer auch für andere Dinge nutzt kann er sowieso nicht einfach blind bei jedem IRQ den Thread wechseln.
Richtig, ich benutze den IRQ nur für die Zeitscheiben. Zumal ich ja nen One-Shot-Timer nutze und keinen monotonen.

Edit::

Ich habe ganz vergessen, es gibt sogar noch eine 4. Methode nen Syscall zu machen, call-gates. Die sollen wohl auch schneller sein als Ints, nur halt mehr Speicher als Opcode verbrauchen.
« Letzte Änderung: 12. October 2011, 14:27 von FlashBurn »

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #30 am: 12. October 2011, 16:27 »
FlashBurn ist ein typischer Vertreter des deutschen Over-Engineerings. :roll: Muss man mit leben.

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #31 am: 12. October 2011, 16:39 »
Zitat von: svenska
FlashBurn ist ein typischer Vertreter des deutschen Over-Engineerings.
Also erstmal danke für das Kompliment :P

OT:
Sind wir deutschen wirklich dafür bekannt?

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #32 am: 12. October 2011, 17:27 »
Ja.
PS: Für solche Dinge solltest du ins IRC kommen, dafür muss man das Forum nicht zuspammen. :-)

Sannaj

  • Beiträge: 103
    • Profil anzeigen
Gespeichert
« Antwort #33 am: 09. December 2011, 20:06 »
Also es gibt unterbrechbare Kernel, Linux kann das zum Beispiel. Allerdings macht so etwas nur bei Monolithischen Kernels Sinn. Hierbei werden die ehr unwichtigen Kernelmoduel (sprich Hardwaretreiber), als Task mit Ring 0 Rechten behandelt. Die Idee, das du ein Kernel internes cooperatives MT, über ein externes präemeratives Multitasking legen willst, macht die Sache natürlich komplizierter. Eine Interessante Idee ist es aber trozdem. Du musst dir auch im klaren sein, das Funktionen wie vmm_alloc immer atomar ausgeführt werden sollten, weil es sonst zu bösen Überraschungen kommst. Wenn du meinst, das es sich lohnt den Aufwand trotzdem zu betreiben würde ich eine Funktion einbauen, die dem Schedule sagt, das er eine bestimmte Aktion atomar ausführen werden muss. Der Schedule sollte in diesem Fall nur eine Markierung setzten, die Uhr aktualisieren und dann weitermachen. In die entsprechenden Kernelfunktionen müsste dann so etwas wie eine "atomar Anfang"/"atomar Ende" Algorithmus eingebaut werden. Die "atomar Anfang"-Funktion setzt eine dafür markierte Flag auf den "no shedule interrupts - time out not reached mode". Wird nun der Shedule aufgerufen setzt er " den "no shedule interrupts - time out reached mode". Die "atomar Ende" - Funktion setzt den Wert auf den Standart zurück und führt den Rest des Shedules aus, wenn "time out reached mode" da war. (Aufpassen, das nicht zusätzlich auf noch der PIT gleichzeitig den Shedule starten kann.)

Das ein Programm, das auf einen Schlag einen ganzen Gigabyte Speicher haben will, halte ich für relativ unwahrscheinlich. Ausführbare Dateien und dylib's selbst sind in der Regel wesentlich kleiner und auf solch große Dateien sollte man nur noch partiell zugreifen.

 

Einloggen