Hm, das klingt umständlich, davon würde ich persönlich eher abraten.
Naja, Problem ist halt, es geht nicht ohne
Ich brauche die für die Idle-Threads, für das Killen von Threads/Tasks und für das Erstellen von Tasks.
Naja, was heißt umständlich. Ich stelle mir das dann so vor, dass ich alle Infos in Variablen sammle. Dann die Ints ausmache, den Speicher freigebe und was sonst noch gemacht werden muss.
Neben dem VMM fällt mir da auch das Erstellen neuer (oder das Killen alter) Prozesse ein.
Interessant, dass immer diese beiden (erstellen und killen) Sachen genannt werden. Dabei bin ich mir sicher, dass das bei mir schneller ist als viele VMM aufrufe (wenn man nur eine Page mappen will, geht das klar schneller).
Ich habe das Erstellen und Killen halt in Threads ausgelagert (Kernelthreads) und weil die unterbrechbar sind (bzw. sein müssen) ist die Länge erstmal kein Problem, nur halt die Zugriffe auf den VMM und das ganz kurze Eintragen in Datenstrukturen.
Was ich vllt noch hätte zu den ticket locks schreiben sollen, sie schonen den Speicherbus (im Vergleich zur klassischen Spinlock). Aber auch sie sind nicht frei von Nachteilen und hier ist es das Cachesystem.
Der Vorteil ist ja, das pro Zugriff (also Lock bekommen und wieder freigeben), nur ein einziger lock Befehl ausgeführt werden muss. Das Spinnen findet dann im Cache statt.
Das ganze kann man auch noch entschärfen, aber mit mMn viel zu viel Speicheraufwand (Array von ticket locks und ein Element ist immer so groß wie eine Cacheline).
Ich habe heute auch alle meine Spinlocks durch diese ticket locks ersetzt und dadurch das ich mich auch nicht mehr um die Ints kümmern muss, ist der Code deutlich geschrumpft.
Ein Problem bleibt, aber trotzdem noch mit einem nicht unterbrechbaren Kernel. Die Locks werden dort nämlich noch teurer als bei einem Unterbrechbaren Kernel. Denn es kann passieren das alle CPUs gleichzeitig auf einen Lock zugreifen wollen und die letzte CPU muss dann sehr lange warten (abhängig von der Anzahl der CPUs und der Länge des kritischen Bereichs).
Entschärft wird das dadurch, dass die ersten CPUs ja theoretisch genügend Zeit haben einen IRQ entgegen zu nehmen, aber da kommt dann auch schon wieder ein anderes Problem. Soweit mir bekannt, kann man den IO-APIC ja so programmieren, dass immer die CPU den IRQ bekommt, die die niedrigste Priorität hat, aber wenn diese gerade die Ints aus hat, wird der IRQ auch nicht an eine andere CPU weitergegeben. Sprich wenn nun dummerweise die letzte CPU (aus obigem Beispiel) den IRQ bekommt, kann es auf Systemen mit vielen Cores doch wieder zu unschönen Latenzen kommen (von SingelCore gar nicht zu sprechen).