Warum? Es gibt doch bestimmt auch viele Syscalls wo gar nicht alle Register gesichert werden müssen.
Es werden auch nur die wichtigsten Register gesichert (die, die die ABI vorschreibt), was auf alle Syscalls zutrifft.
Warum wird das nicht auch im Thread-Descriptor gesichert? Das ist doch schon wieder eine unnötige Fallunterscheidung.
Weil wir dann ja wieder unnötiges Kopieren hätten. Denn die Daten liegen ja schon auf dem Stack, von dort würde man sie dann in den Thread-Discriptor kopieren um sie dann später wieder aus dem Thread-Discriptor zurück auf den Stack kopieren würde (und somit effektiv die gleichen Daten mit den gleichen Daten überschreibt).
Zumal ich die Fallunterscheidung trotzdem bräuchte, weil die Position wo auf den CPU-lokalen-Stack kopiert wird ist immer die gleiche, bei dem KernelThread nicht. Bzw. muss ich mir bei UserThreads immmer den CPU-lokalen-Stack holen und bei KernelThreads steht der Stack-Pointer ja im Thread-Discriptor.
das wäre für mich ein wichtiger Grund auf Kernel-Threads gleich ganz zu verzichten
Geht halt nicht, bei mir läuft z.B. immer ein Thread-Killer-Thread im Hintergrund mit, der Threads (und wenn nötig ganze Tasks) komplett aus dem Speicher entfernt, was halt am einfachsten in einem extra Thread ist. Wie willst du das eigentlich lösen?
Sorry, wenn ich das wieder so deutlich raus hängen lass aber KISS ist Dir wirklich nicht sonderlich vertraut oder?
Ich kenne es, aber ob ich immer auf KISS komme, steht auf nem ganz anderem Blatt. Zumal diese Lösung noch von meinem "alten" Kernel stammt.
Das heißt das Du aus 2 Funktionsaufrufen 3 gemacht hast ohne dadurch an Funktionalität zu gewinnen?
Wieso habe ich nicht an Funktionalität gewonnen? Es ist dann so, dass der eigentliche Thread nicht mehr läuft, sondern seinen neuen Status (in dem Fall blockiert) hat und auch auf einer anderen CPU wieder laufen kann.
Genau dagegen würde meine Idee mit den Events nachhaltig helfen.
Ich sehe immer noch nicht, was deine Events von ganz normalen Semaphoren unterscheidet? Ich will diese auch genau dafür benutzen.
Entweder darfst Du aus wait() nicht zwei mal raus kommen (so will ich das in meinem Kernel machen) oder Du machst das mit einem Rückgabewert wie bei fork().
Spontan habe ich keine Idee, wie ich das mit den Rückgabewerten machen sollte. Wie willst du es denn verhindern nicht zwei mal aus wait() zurück zukommen? Ich werde das halt über die Rücksprungadresse lösen. Im Falle der KernelThreads würde die Rücksprungadresse die von Sem::acquire() sein und im Falle von UserThreads würde er sogar gleich wieder zurück in den UserMode springen (da kann ich mir ja das ganze zurück gespringe, aus dem Syscall wieder raus, sparen).
Ich bin gerade dabei, meinen kompletten Ansatz wie ich mit Threads im Scheduler umgehe, umzuschreiben. Mein neuer Scheduler (es geht da nur um den eigentlichen IRQ Handler) holt nur noch einen neuen Thread und packt einen Thread nur zurück in eine Queue, wenn der Status des Threads Running ist. Bei allen anderen Threads wird davon ausgegangen das sie schon an der richtigen Stelle sind, das wiederum wird schon im Kernel vor dem Scheduler gemacht, so dass der Scheduler wieder ein Stückchen kürzer und einfacher ist.
Dein Hinweis mit, dass ich ja schon nen CPU-lokalen-Stack habe und nicht extra nen Scheduler-lokalen-Stack brauche, werde ich nochmal überdenken. Ich brauche auf jeden Fall die Fallunterscheidung zw Kernel- und UserThreads. Problem ist einfach, das der IRQ-Handler (vom Timer) die Register ja auf dem gerade aktuellen Stack sichert und das kann einmal ein CPU-lokaler-Stack oder ein KernelThread-Stack sein. Um dann nicht noch nachgucken zu müssen (im IRQ-Stub-Code, bevor der eigentliche Scheduler aufgerufen wird) um was es sich handelt, ist es halt einfacher nen "anderen" Stack zu nehmen. Ich sollte vllt dazu sagen, dass ich dafür nicht extra nen Stack bzw. Speicher allozieren. Ich habe ja meine Idle-Threads und die brauchen nicht mal annähernd die 4kb Stack, also nutze ich die eine Hälfte für den KernelThread-Stack und die andere Hälfte ist der Scheduler-Stack (geht da ich ja für jede CPU nen Idle-Thread habe).
Wenn du dann wieder sagst, dazu habe ich ja den CPU-lokalen-Stack, dann müsste ich ja wieder ne Unterscheidung machen oder der Thread müsste seinen State selbst sichern (was auch einer Unterscheidung gleich kommt). So ist das nen ganz normaler KernelThread wo ich auf nix achten muss.