Hallo,
sync/async/detached?
Okay, gekauft, Zahlung erfolgt später.
Ich nutze diese Terminologie dann gleich mal.
Umgekehrt wird ein Schuh draus: Wenn das IPC-Design es unmöglich macht, dass ein Prozess Speicher weiterbenutzen kann nachdem er die Antwort geschickt hat, dann muss man sich überlegen, ob Memory Sharing fest daran zu koppeln wirklich eine gute Idee ist.
Also da alle wichtigen Dinge (also read()/write(), bis einschließlich dem asynchronen File-I/O) den User-Buffer nur so lange ausleihen bis die Aktion abgeschlossen ist sehe ich darin erst einmal keine Beschränkung, solltest Du oder jemand anders ein
praxisrelevantes Szenario kennen in dem das anders ist dann würde ich das sehr gerne lesen. Ansonsten steht auf meinem System ja nichts im Wege auch dediziertes Memory-Sharing mit extra erstellten Segmenten zu machen so das dann per IPC nur noch die Kommandos ausgetauscht werden müssen, es ist bei meinem IPC-Konzept nicht Pflicht das Memory-Sharing immer in vollem Umfang zu nutzen. Da mein IPC-Konzept aber eben komplett durchgängiges Zero-Copy (und zwar wirklich vom Hardware-Gerät bis zur eigentlichen Applikation) ermöglicht, und Du hast ja selber geschrieben dass das wichtig ist, kann ich durchaus damit leben das mein IPC-Konzept nur die normalen Dinge ohne Verrenkungen ermöglich und für die exotischen Dinge eben das Shared-Memory extra gemanaged werden muss (so wie bei Euch immer). Das heißt für mich das ich in über 99% aller Fälle mit maximaler Performance arbeiten kann und beim Rest eben auf das (niedrige) Niveau der Konkurrenz zurückfalle. Das gezielte abkoppeln des geteilten Speichers durch den Callee habe ich nur für detached IPC vorgesehen, wobei auch gerade da es sich lohnt wenn der Caller angibt das der Kernel in jedem Fall kopieren soll (egal wie viele Daten es sind) damit der Caller eben wirklich unabhängig bleibt.
Der Workaround, den du beschreibst, hinterlässt bei mir den Eindruck, dass das nicht wirklich mit deinem Design zusammenpasst, ...
Ja, da hast Du recht. Deine beiden Szenarien, mit dem allein Weiterarbeiten und dem Nacharbeiten, sind so ohne weiteres in meinem IPC-Konzept nicht vorgesehen, da beides nicht der Regelfall ist (oder siehst Du das anders?) habe ich damit auch absolut kein Problem. Wenn man das normale IPC trotzdem dafür nutzen möchte muss man eben einen Workaround nutzen oder man entscheidet sich besser dafür das Memory-Sharing und das Übermitteln der Kommandos/Antworten zu trennen (ersteres über dedizierte Memory-Sharing-Funktionen des OS-Kernels und zweites z.B. per detached IPC).
Interessant könnte der Fall werden, wenn der Empfänger das alleinige Schreibrecht auf den erhaltenen Puffer haben will (und das will er in aller Regel nachdem er den Puffer geprüft hat, sonst kriegst du oft genug ein sicherheitskritisches Race). Dazu müsste er in deinem Konzept wahrscheinlich kopieren.
Ich verstehe nicht ganz was Du meinst. In meinem Konzept bleibt der geteilte Speicher beim IPC-Caller immer so erhalten wie er ist und der IPC-Callee bekommt entweder Leserechte oder Schreibrechte (aber nie beides gleichzeitig) auf die bis zu 4 übergebenen Speicherbereiche (davon maximal 2 Lesen für Kommando und write-Nutzdaten und maximal 2 Schreiben für Antwort und read-Nutzdaten). Klar kann es damit passieren das der Caller z.B. im Kommando rumfuscht obwohl der IPC-Call noch nicht beendet ist (bei Multithreading im Caller ja durchaus möglich) aber wenn der Callee dann das Kommando nicht korrekt verarbeitet und Blödsinn zurück schickt ist das ein Problem des Callers. Das einzigste was natürlich nicht passieren darf ist das damit z.B. ein Service gestört wird oder gar abstürzt, da die kleinen Kommandos eh meistens vom Kernel kopiert werden (bei Speicherbereichen unterhalb einer gewissen Größe soll der Kernel grundsätzlich kopieren und nicht Sharen, das wird für jeden der bis zu 4 Speicherbereiche individuell entschieden) und der Callee auch prüfen kann ob wirklich kopiert wurde und falls nicht das notfalls selber nachholen kann sehe ich da keine große Gefahr. Auch wenn das bei Eurem Shared-Memory wohl eher nur die Nutzdaten betrifft so ist diese Gefahr ja grundsätzlich ebenfalls vorhanden.
Naja, damit kommen wir direkt wieder zur Diskussion von Popup-Threads. Ich halte es nach wie vor übertrieben, von allen Programmen zu verlangen, dass sie threadsafe sind.
Da hast Du grundsätzlich recht, deswegen kommt bei mir ein reiner IPC-Caller der nur synchrounus und detached IPC nutzt auch mit einem einzelnen Thread aus, das dürfte die meisten einfachen Programme (die kein asynchrones File-I/O u.ä. nutzen) betreffen, ich würde sogar soweit gehen zu behaupten das die meisten Programme die auf tyndur laufen auch auf meinem System als simple singlethreaded Applikationen laufen müssten. Erst komplexere Programme, die z.B. für asynchrones File-I/O eben auch asynchrones IPC nutzen, oder richtige Services müssen bei mir zwangsläufig multithreadingtauglich sein. Meine libc möchte ich grundsätzlich nur multithreadingtauglich anbieten.
Naja, ein IPC-Mega-Syscall ist ja genau das was du machst. Der ist wohl unabhängig davon, ob am Ende Pipes oder Popup-Threads stehen.
Hä, nein, einen Mega-IPC-Sycall hab ich nicht, ich habe in meinem aktuellen Konzept 19 Syscalls für IPC vorgesehen. Es gibt auch für sync/async/detached jeweils einen eigenen Call-Syscall. Natürlich werden die intern für viele Dinge die selben Unterfunktionen nutzen (z.B. für das Vererben/Kopieren des Speichers oder für das Erstellen des PopUp-Threads), weswegen ich auch nicht davon ausgehe das diese doch recht große Anzahl an Syscalls nur fürs IPC meinen Kernel unangemessen komplex werden lässt, aber nach außen sind das unabhängige Syscalls.
Was die Puffer angeht, führt bei einem x86-OS mit flachem Speichermodell nichts dran vorbei, das ist keine IPC-Designentscheidung.
Ist mir bekannt.
.... Wenn irgendwo zwischen Anwendungscode und Platte eine Schicht nicht ordentlich mitspielt, wird es schwierig.
Natürlich, mit all dem hast Du uneingeschränkt recht. Es ging mir doch erst mal nur um die Kohärenz die die Anwendungen auf jeden Fall sehen müssen, das es da noch mehr gibt ist mir auch klar.
Es ist also schon die Frage, welches Interface das VFS dafür zur Verfügung stellen sollte. Nur einen Holzhammer fsync(fd); oder irgendwelche feineren Operationen?
Wenn ich Dich vorhin richtig verstanden hab dann bietet doch eine konforme POSIX-Implementierung schon so einige Mitelchen an, ich denke das ist zumindest eine gute Orientierung was sinnvoll ist und was auch von existierenden Programmen so alles benutzt wird.
Hm, ich würde sagen, dass dazu das Dateisystem mitspielen sollte. Ansonsten musst du ja alles im Speicher machen.
Ja, ein berechtigter Einwand. Ich denke mal das btrfs und ZFS sowas von Hause aus bieten, NTFS wimre auch (zumindest sein kurzer Zeit) und ob da auch die ext?-Familie was zu bieten hat weiß ich gar nicht.
Der Fall mit zwei VMs und einem Clusterdateisystem gefällt dir nicht, wenn du noch was anderes als Snapshots willst?
Ah
zwei VMs (das hatte ich heute Mittag offensichtlich überlesen), das macht die Sache schon wesentlich interessanter. Ja da müsste man wirklich überlegen welche Konsistenzen das VFS zusichern muss und welche Mechanismen die VMs nutzen wollen um das zu gewährleisten. Ich schätze mal da hat POSIX auch was hübsches anzubieten.
Trotzdem muss ich ganz ehrlich sagen das ich noch gerne ein etwas alltäglicheres Beispiel lesen würde. Clusterdateisysteme und mehrere VMs sind IMHO nicht so das typische Anwendungsszenario für ein Hobby-OS.
Ich möchte den Syscall sogar so allgemein machen, dass du nur durch ein Flag auch den Speicher versenden (Speicher wird auf Senderseite ungemappt) kannst.
Da ich eher versuchen möchte möglichst immer direkt den eh vorhandenen User-Buffer für das IPC zu nutzen (wegen dem lieben Zero-Copy) ist das für mich sowieso kein interessantes Ziel, nebst dessen das ich aus meinen Segmenten nicht einfach Speicher mitten raus klauen kann.
Denn wie bekommt man die SHM-ID in einen anderen Prozess, wenn nicht über IPC, sprich der Port muss eh vorhanden sein.
Also da kann ich mir so einiges vorstellen: z.B. ein Programm könnte den SHM erstellen und dann weitere Kind-Prozesse starten und diesen die nötigen Zugriffsinformationen gleich als Command-Line-Parameter o.ä. mitgeben.
aber da ja niemand hier mit solch "alter" Hardware wie ich plant, sollte das auch kein Problem darstellen.
Der Nutzwert von Zero-Copy ist IMHO unabhängig vom Alter des Systems, Kopieren kostet
immer unnütz CPU-Zeit.
Grüße
Erik