Inter-Process-Communication (IPC)



  • Problem:
    Ein Betriebssystem hält Unmengen an Informationen vor. Viele davon müssen auch für User abfragbar sein. Beispielsweise möchte ein Nutzer wissen, ist Laufwerk 1: ein Floppy-Laufwerk und wenn ja, liegt was drin. Er könnte Informationen zur eingebauten Grafikkarte verlangen. Er braucht Infos zu Plattenbelegung. Er möchte wissen, wie spät es ist. Er braucht die Mausposition oder will wissen, welche Taste gedrückt ist.
    Würde man für all diese Anfragen Syscalls anlegen, würden wir schnell 1000 Syscalls haben. Das sprengt definitiv den Rahmen des Vernünftigen.
    Desweiteren enthält der Kernel zahlreiche Funktionen, die Informationen auf den Bildschirm drucken. Ich finde, das sollte man auslagern. Wenn die Shell entscheiden könnte, wie das gedruckte aussehen soll, würde das die Möglichkeiten steigern, PrettyOS zu inidividualisieren.

    Lösung:
    PrettyIPC
    PrettyOS legt eine Baumstruktur an, in der es Daten wie die o.g. speichert. Das Prinzip ist dabei etwas (aber auch nur etwas) mit der Windows Registry zu vergleichen. Ein wesentlicher Unterschied ist, das sich dort nur nicht-permanente Daten befinden; die IPC wird also auch nicht auf der Platte gespeichert und beim Boot davon geladen, sondern bei jedem Boot-Vorgang neu angelegt.
    Der Kernel, bzw. Treiber legen Informationen im Kernelbereich ("/PrettyOS") ab, die sie den Nutzern preisgeben möchten. Sortiert werden diese Daten dabei, wie oben erwähnt, in einer Baumstruktur um eine ordentliche Kategorisierung zu ermöglichen.
    Jeder Task hat außerdem einen Task-Bereich der als Namen die PID des tasks hat (letztlich ist der Kernelbereich der Bereich des Tasks mit der PID 0, hat allerdings nicht den Namen "0"). In diesem kann jeder Task Daten ablegen und beispielsweise auch Dateien anlegen (-> Ramdisk).
    Jeder Schlüssel hat einen Namen und kann Datenmember oder Unterschlüssel (-> Ordner) haben.

    Zusätzlich sollte man noch ein Besitzrechte-System einbauen, das dafür sorgt, das nur der Besitzertask diese Schlüssel lesen, löschen und ändern kann. Diesem Task könnte man dann auch erlauben, anderen tasks Lese- und Schreibrechte zu geben.

    Diese Lösung hat durchaus etwas gemeinsam mit der Lösung, einfach einen rohen Speicherbereich zu definieren, in dem Kommunikation zwischen Tasks stattfindet. Dann hätte der Kernel aber keine Kontrolle, um Fehlern in der Handhabung vorzubeugen. Auf diese Weise kontrolliert der Kernel die Kommunikation, indem er die Struktur vorgibt und beugt so Fehlern vor und erleichtert gleichzeitig den Programmierern von Userprogrammen die Arbeit, weil sie sich nicht mehr um das Format dieser Daten kümmern müssen, sondern diese automatisch strukturiert gespeichert werden können.

    Die Kommunikation zwischen Tasks könnte zudem erleichtert werden, indem Events für die IPC geschaffen werden. So könnte ein Tasks ein IPC_PING_EVENT an alle Tasks senden, die auf einen Schlüssel Zugriff haben, um zu signalisieren, dass dieser geupdatet wurde.

    Beispiel:

    - PrettyOS
        - Time = 14231095
        - VGA
            - Type = "VBE"
            - Manufacturer = "ATI"
            - Driver Version = 12345
            - Videomodes
                - ...
        - Ports
            - A
                - Type = "FDD"
        - Disks 
            - 1
                - Port = "A"
                - Type = "Floppy"
                - Size = 1440000
    - 1
        - Name = "Shell"
        - IPC-Datei ...
    

    In diesen Datenspeicher können aber auch Programme Daten ablegen, die der Kommunikation mit anderen Programmen dienen.

    Es müsste also nur wenige Syscalls geben, die so aussähen (Also pro Datentyp je einen zum setzen und einen zum auslesen):

    FILE* ipc_fopen(const char* path, const char* mode); // Öffnet IPC-Datei. Weiterer Zugriff über Standard-Dateifunktionen
    IPC_ERROR ipc_getFolder(const char* path, char*       destination, size_t length); // Schreibt Namen aller Unterknoten in destination.
    IPC_ERROR ipc_getString(const char* path, char*       destination, size_t length);
    IPC_ERROR ipc_setString(const char* path, const char* val);
    IPC_ERROR ipc_getInt   (const char* path, int64_t*    destination);
    IPC_ERROR ipc_setInt   (const char* path, int64_t     val);
    IPC_ERROR ipc_getDouble(const char* path, double*     destination);
    IPC_ERROR ipc_setDouble(const char* path, double      val);
    IPC_ERROR ipc_deleteKey(const char* path);
    IPC_ERROR ipc_setAccess(const char* path, IPC_RIGHTS permissions, uint32_t task); // Task: Angabe als PID. PID 0: Für alle tasks, da Kerneltask immer Vollzugriff hat.
    

    Der zurückgegebene IPC_ERROR beim Aufruf der IPC-Funktionen dient zum Abfangen von Fehlern beim Zugriff. Im Falle eines IPC_NOTENOUGHMEMORY-Errors wird ins Destination-Feld die nötige Größe geschrieben, sofern der Speicher zumindest dazu ausreicht. Die ipc_set-Funktionen legen den Schlüssel an, sofern er noch nicht existiert. Die ipc_get-Funktionen speichern die Daten im übergebenen destination-Feld. Der Aufrufer hat sicherzustellen, dass der Speicherbereich ausreichend groß ist.

    Vorteile:

    • Die Shell kann zahlreiche Aufgaben übernehmen, die derzeit beim Kernel sind. Z.B. das Auflisten der Disks und Ports, fdir, ... -> Individuellere Anpassungsmöglichkeiten
    • Der Kernel wird entschlackt - Nur noch wenig Kernel-Output
    • Wenige Syscalls - Viele Infos verfügbar
    • Erleichterung der Interaktion zwischen verschiedenen Tasks

    Nachteile:

    • Nicht ganz trivial zu implementieren (Verglichen mit 1000 einzelsyscalls, die nur Schreibarbeit wären)
    • Frisst ein paar RAM-Ressourcen

    mfg
    Mr X

    EDIT: Ich habe das Konzept mal etwas weitergedacht und aktualisiert.


  • Mod

    Begriffsklärung:
    Ports: usb-slot, FDD, RAM
    Disks: usb-MSD, Floppydisk, RAMdisk



  • Hm.. verdammt, wie bei dem Device-Manager.. klingt für micht nicht optimal, habe aber auch keine bessere Lösung..-.-

    Naja, wenn dein "Video" einen "Manufactorer" hat..^^

    Cuervo



  • War ja alles nur Beispielhaft, kann man auch VGA nennen (sollte man sogar, wo Du es sagst)


  • Mod

    Manufacturer

    Video ist der allgemeine Begriff, ist schon ok.


  • Mod

    MrX: wie ist hier der aktuelle Stand?



  • Ich habe bei mir ein wenig unvollständigen Code liegen, der unter Windows läuft (Ich hab mir da eine Testumgebung gebastelt, die sozusagen dem Compiler PrettyOS emuliert (unvollständig, aber für meine Zwecke ausreichend)). Diese Implementation ist aber, s.o., unvollständig.


  • Mod

    MrX hat den obigen Entwurf heute aktualisiert: http://www.c-plusplus.net/forum/269501


Log in to reply