Wie kann ich meinen Tasks im OS am besten,elgantesten,sichersten und codeschlankesten einen Timer anbieten?
Wie so oft: Das hängt davon ab, in welcher Auflösung und Reaktionszeit du sein möchtest.
(1)Ist es möglich einen Timer-Dienst zu implementieren und als Taks laufen zu lassen oder ist es notwendig das im Kernel zu haben.
Es ist notwendig, wenn du kurze Timerlaufzeiten haben möchtest. Da der Timer über Interrupts arbeitet, müsstest du für jeden Timerinterrupt eh in den Kernel schalten und wenn du sowieso schon dort bist, kannst du auch die Schedule-Anweisungen und Tabellen mitverarbeiten.
(2)Welchen Timer(-Chip) nehm ich? (Wenn ich den vom Multitasking nehm, dann können die Tasks die den Timer-Dienst benutzen wollen nur solche Werte nehmen, die teilbar durch die Einstellung des IRQ 0 sind)
Du hast mehrere zur Auswahl; Minix benutzt einen der drei Timer und lässt diesen in einer Auflösung von 60 Hz arbeiten (d.h. alle 16,8 ms ein Interrupt). Diese Frequenz kannst du auch anpassen, wenn dein Rechner schneller als 12 MHz ist *g*. Allerdings sollte das für das meiste reichen. Besser ist allerdings, zwei Timer zur Verfügung zu stellen.
(3)Gibt es Anwendungen wo das nicht verschmerzbar ist? (TCP/IP, bst. Treiber, Audio + Video)
Hängt wieder von den Treibern und deren Implementation ab. Besonders für Multimedia musst du u.U. auch einen Hochgeschwindigkeitstimer anbieten, mit einer bedeutend höheren Frequenz. Unter Linux hast du die Funktionen sleep (in ms) und usleep (in µs) - daran kannst du dich auch orientieren.
(4)Muss ich solche getimeten Prozesse den anderen im Multitasking vorziehen, was wenn zwei Prozesse vorgezogen werden wollen?
Das hängt davon ab, ob du Echtzeitfähigkeit haben möchtest oder die relativ unwichtig ist. Sicher ist, dass du möglichst schnell auf einen Timer reagieren musst, um Pufferunterläufe o.ä. zu vermeiden.
Was ist, wenn ein Prozess die ganze Zeit einen Timer on hat, nur um länger ausgeführt zu werden?
Um mich nochmal auf Minix zu beziehen: Dort gibt es für Timer prinzipiell zwei Möglichkeiten - jeder Prozess darf genau EINEN Alarm setzen. Zu diesem Zeitpunkt wird dem Prozess ein Signal (SIGALARM) gesendet, dass er verarbeiten (oder ignorieren) muss. Die zweite Variante ist, dass das Programm ein sleep() oder [Linux] usleep() aufruft, und so lange geblockt (d.h. im Scheduler ausgetragen) wird, bis die Zeit abgelaufen ist.
So umgeht man das Problem, dass ein Prozess den Timer "ausnutzt", um sich Zeit zu geben. Zudem sollten kritische Services (Kernel, Treiber) grundsätzlich auf "ewig" laufen gelassen werden, d.h. bis sie fertig sind und blocken.
Ich hoffe, es hilft dir.
edit: Mir fällt gerade ein: Ich glaube, usleep wird mit Busy-Waiting (also ne sehr enge Schleife) implementiert, weil kein hardwareseitig schneller Interrupt verfügbar ist. sleep wartet auf den Int vom Timer.
Gruß,
Svenska