Ich weiß ja nicht, wo du deine x86-Fälschung erworben hast, die das so macht, aber mein x86 sichert von sich aus bei einem Interrupt oder Trap Gate nur ss, esp, eflags, cs und eip auf den Stack. Der Rest landet nur dann auf dem Stack, wenn du das so programmierst. Bei einem Task Gate geht sogar alles direkt in eine andere Struktur (nämlich das TSS).
Naja, ich bin halt einfach davon ausgegangen das man alles auf dem Stack speichert, weil es das schnelleste und einfachste ist. Es dann nochmal umzukopieren wäre ja quatsch.
Das bedeutet das wenn Du asynchrones I/O implementieren möchtest soll das über noch mehr Ports (und damit Threads) im Service gehen? Ich gebe zu das ich über asynchrones I/O auch noch nicht so viel nachgedacht habe aber diese Idee erscheint mir nicht sonderlich geschickt.
Ich wollte damit nur sagen, dass mein Konzept bei A-I/O nicht mehr funktioniert, aber diese Baustelle werde ich frühestens bearbeiten wenn alles andere läuft und bis dahin vergeht noch ne ganze Weile.
Doch, sehr lange und intensiv sogar, aber ich hatte kurz vergessen das die x86-CPU die Register ja zwangsweise in den Speicher schreibt aber auch so bin ich davon ausgegangen das man das gesicherte Register-Set vom Stack in die Thread-Descriptor-Struktur kopiert und wenn man einen anderen Thread weiterlaufen lassen will dann wird sein Register-Set eben in den CPU-Lokalen-Kernel-Stack kopiert und ein IRET gemacht.
Naja, du vergisst, dass auf dem Stack aber nicht nur die Register liegen, da liegen auch noch Funktionsargumente, lokale Variablen usw., das müsstest du dann alles mit in den Thread-Descriptor speichern und das artet dann mal schnell darin aus, das du den gesamten Stack woanders hinkopierst, nur um zu erreichen das du nur einen Stack im Kernel verwendest. Das einzigste was du dadurch erreichen würdest wäre, dass du pro CPU einen Stack mehr hast als normalerweise nötig.
Ich bin jetzt mal ganz einfach davon ausgegangen, dass jeder Thread auch mal den Syscall macht und das der Kernel unterbrechbar ist.
Übrigens wiedersprichst du da deiner eigenen Philosophie des zero-copy (ich betrachte das Speichern auf dem Stack nicht als kopieren in dem Sinne, weil mind. 1 Register sowieso erstmal irgendwo zwischen gespeichert werden muss um den Rest dann irgendwo zu speichern).
Selbst bei x86-64 ist ein Register-Set nur 128 Bytes groß und dafür einen kompletten Stack zu reservieren finde ich eher ungeschickt, bei den paar Bytes fällt das kopieren nun wahrlich nicht ins Gewicht (das passt ja bequem in den L1-Cache so das der von Dir erhoffte Performance-Vorteil vermutlich weniger als 10 Takte pro Context-Switch beträgt). Im Tutorial wird doch wimre auch nur ein TSS pro CPU empfohlen, wo mir dann auffällt das Du dann dort immer einen anderen Kernel-Stack eintragen musst (also Speicherzugriffe) oder Du hast so viele TSS wie es Threads gibt und da dürften Dir dann doch ziemlich schnell die GDT-Einträge ausgehen (vor allem weil Du ja mit Threads seeeehr großzügig bist).
Du hast, wie gesagt, das Szenario Syscall vergessen und das die Kernel-Funktionen ja auch den Stack verwenden. Wie kommst du auf 10 Takte bei 128byte? Zumal es mehr als nur die 16 Register sind, da wäre noch das RIP und das RFlags Register.
Und ja ich verwende nur ein TSS pro CPU, weil es halt nötig ist. Denn keiner von uns wird wohl Hardware-Taskswitching auf der x86-Architektur nutzen (wenn doch komm ich dem gleich mit der Portabilität
)!?
Ich möchte das ein Service bei der Erstellung seines Message-Targets bestimmen kann wie viele Threads maximal für dieses Message-Target erstellt werden dürfen, das bedeutet dann das wenn mehr Anfragen gleichzeitig kommen das dann gequeued werden muss. Dieses Maximum darf auch 1 betragen. Aber das ein bereits vorhandener Thread in dem Prozess benutzt werden soll ist definitiv nicht vorgesehen. Es wird weder aktives abholen von Messages geben (eben wegen den Problemen mit der unbekannten Message-Größe) und auch keine Unterbrechung eines Threads (in der Art der Unix-Signale, das hat mir zu viele Nachteile für die Signal-Handler bei der Benutzung von Ressourcen wie malloc usw.).
Ok, wenn du das so machen willst, darfst du mir nie mehr damit kommen, das man nicht alzu sehr von gewohnten Weg abweichen sollte
Ich sag mal ne normal GUI-App zu schreiben/portieren dürfte noch gehen, aber wenn es dann zu sachen kommen die normaler Weise nicht blockieren wenn keine Nachricht da ist, sondern weiter arbeiten, da stelle ich es mir dann schon schwierig vor (Bsp. Spiele, die warten ja auch nicht bis die Taste gedrückt wurde, sondern es wird geguckt, wurde eine gedrückt und dann wird der nächste Frame berechnet).
Aber ansich ist die Idee von daher gut, weil man damit zum Multithreading gezwungen wird, macht die Sache nicht einfacher, aber dann gibt es vielleicht irgendwann mal mehr Programme mit denen man Vorteile aus mehreren Kernen holen kann.
Klar kann es sein das der Pool mal ziemlich voll wird aber dann muss der eben etwas geleert werden. Es kommt letztendlich auf eine gute Pool-Verwaltungsstrategie an aber wenn ich die finden sollte werde ich wohl weniger Speicher verbrauchen als Dein Konzept.
Das klingt für mich wie nach dem Kontept eines Garbage-Collectors. Wird von allen als das Allheilmittel angepriesen (weil sich der dumme Programmierer nicht mehr um die Speicherverwaltung kümmern muss). Jedes Mal wenn ich das Wort Garbage-Collector höre, dreht sich bei mir im Magen alles um.
Meine Erfahrung von Programmen die in Java oder python oder anderen Sprachen mit einem Garbage-Collector geschrieben sind, der wird immer in einem bestimmten Zeit-Interall aufgerufen, wo er halt aufräumt und in der Zeit geht die Performance meistens in den Keller.
Sowas hört sich in der Theorie immer toll an, aber in der Praxis hapert es fast immer
Bitte nicht übel nehmen aber das ist völliger Quatsch! Eine TCP-Verbindung wird über die 2 IP-Addressen und die 2 Port-Nummern (jeweils vom Client und vom Server) unterschieden und selbst wenn davon immer eine IP-Adresse und ein Port gleich sind (also die vom Server) so sind doch trotzdem mit IPv4 theoretisch bis zu 2^48 Verbindungen zu einem einzelnen Web-Server möglich (mit IPv6 entsprechend mehr).
Das klingt doch schon ganz anders und ist auch viel logischer!