Hä? Was willst Du da genau machen? Also ich würde nicht bestimme OS-Kernel-Aufgaben auf bestimmte CPUs festpinnen. Das würde ich auch nicht mit IRQs machen, ein IRQ wird am besten auf der CPU verarbeitet auf welcher gerade der User-Mode-Code mit der niedrigsten Priorität läuft.
Also bei meinem System wird der IRQ Handler immer auf der CPU mit der niedrigsten Prio ausgeführt (Ausnahme sind CPUs im Idle-Zustand).
Ich hab mir das so vorgestellt. Du hast halt den PIT im periodischen Modus mit den magischen 18,2Hz = 55,4ms.
Ein Thread läuft auf CPU0 und möchte für 200ms schlafen, dann ruft er halt sleep(200000000) auf (die Zahl ist so groß, weil ich ns als Basis nehme, da rechnet sich einiges leichter ohne die FPU verwenden zu müssen) und die holt sich den aktuellen Wert des internen PIT Counters (weil ich den vorher von der zu wartenden Zeit abziehen muss) und packe den Thread in die Delta-Queue des PIT-Handlers.
Jedes Mal wenn der PIT den IRQ-Handler aufruft, zieht er 55,4ms von dem 1. Thread in der Delta-Queue ab und wenn die Zeit die da rauskommt kleiner als 55,4ms ist, wird der (und alle Threads für die dies auch noch gilt) in die Sleep Queue der CPU gepackt auf welcher der IRQ-Handler gerade ausgeführt wird.
Ich hätte dann also eine "globale" Sleep-Queue die nur vom PIT bearbeitet wird und auf jeder CPU noch mal eine Sleep-Queue die von der jeweiligen CPU bearbeitet wird.
In der PIT Queue sind alle Threads welche länger als 55,4ms warten wollen und in den CPU Queues sind alle Threads welche weniger als 55,4ms warten wollen.
Damit sollte ich den Jitter klein halten bzw. (mal vom worst-case abgesehen) sollte der sich zumindestens nicht aufaddieren.
Als Alternative würde ich den PIT nicht betrachten, aller höchstens, und nur mit viel Bauchweh, als Notlösung.
Genau das ist er auch (aber war er das nicht von Anfang an
).
Du musst immer mit absoluten Zeiten rechnen. Wenn Dein Programm zum Zeitpunkt 510638ms den ersten Event bekommen hat und der nächste Event 60ms später kommen soll dann muss das eben zum Zeitpunkt 510698ms passieren und darf nicht von der verbrauchten Zeit o.ä. abhängen. Den HPET kann man auch nicht einfach so mal auf einen neuen Zählerwert setzen sondern man kann nur einen neuen absoluten Vergleichswert hinein laden an dem der nächste IRQ generiert wird, genau das habe ich in meinem Ursprungspost beim PIT in Software nach gebaut.
Wenn ich dich richtig verstanden habe, dann meinst du das ich Probleme mit periodischen Events bekommen würde.
Das Problem was ich im Moment mit Events habe ist, ich habe noch gar keine Events auf meinem System
Ich rede die ganze Zeit nur von Threads die schlafen gelegt werden. Das andere was ich noch meine ist ne Performance Counter um sagen zu können wieviel Zeit vergangen ist.
Aber, deine Idee mit den Events (um z.B. ein Spiel auf 60FPS zu "eichen") find ich gut, ich weiß halt nur nicht wie ich die umsetzen würde/sollte.
Jetzt so spontan würd ich einfach ne Message an einen vorgegebenen Port senden und der Inhalt wäre halt ne Art ID die sagt, Event ausgelöst.
So dass ich einfach Events in anstatt Threads in eine Queue packe (anstatt der Sleep-Queue im PIT und auf den CPUs) und dann so alles löse.
Die periodischen Events würde ich dann so lösen, das du ne Startzeit (die Zeit bei der der Event eingetragen wurde) nimmst und die Eventzeit draufrechnest und den Event wieder in die PIT-Queue packst und nen "neuen" Event erzeugst mit der Restzeit (kleiner als 55,4ms) und diesen in die CPU Queue packst.
Ich hoffe ich war einigermaßen verständlich, klingt alles ein wenig wirr ich weiß.
Ich würde spontan sagen, das ich ne Semaphore für die Events nutzen könnte (zumindest für das Sleep-Event). Es wird halt ein neues Event erstellt, das einmal feuern soll und in 200ms soll das ganze passieren, der Thread versucht darauf hin die Semaphore zu bekommen (was ja nicht klappt und der wird auf blockierend/wartend gesetzt). Wenn das Event dann feuert, gibt es die Semaphore frei (was den Thread praktisch aufweckt) und "zerstört" sich selbst. Dann hätte ich die Sleep-Funktion über Events gelöst und müsste mir nur noch nen Kopf machen, wie ich das mit anderen Events mache.
Obwohl es gar nicht schlecht wäre das immer über Semaphoren zu machen. Um nochmal das Bsp mit dem Game zu bringen, wenn das Event alle 16ms die Semaphore freigibt und der Thread mal länger brauchen sollte, dann bekommt er die Semaphore ja sofort und kann gleich den nächsten Frame berechnen.
Wenn ich dann noch die Linux Idee von den Futexen nutze, dann kann ich das ganze noch halbwegs effizient im User-Space machen.
Was haltet ihr von der Idee (meine Event Idee und die Sache mit dem PIT)?
Also wenn Dual-Core (nicht Dual-Sockel) vorhanden ist dann sollte auch ein HPET anwesend sein. Auf älteren PCs kannst Du ja den PIT im Periodic-Modus nutzen, dort dürften die CPUs auch nicht so interessante Tiefschlaf-Modi kennen so das dort kein so großes Problem entsteht.
Ich habe hier einige Motherboards mit mehreren CPUs (Slot1, Sockel370, Sockel5/7, SockelA) die keinen HPET haben und die möchte ich ja auch unterstützen!
Du weißt nicht zufällig ab wann ungefähr der HPET auf neuen Boards vertreten war?
Ich hab von dem Ding das erste Mal zu Core2 Zeiten gehört.