Auch in Systemen, die zum größten Teil periodische Ereignisse bearbeiten,
kommt es vor, dass auf nicht-periodisch Ereignisse reagiert werden muss. Im
Bereich von Echtzeitsystemen spricht man dabei von aperiodischen und
sporadischen Ereignissen. Diese beiden Typen unterscheiden sich darin,
dass an die Behandlung sporadischer Ereignisse Zeitbedingungen gestellt werden,
während dies bei aperiodischen Ereignisse nicht der Fall ist. Im folgenden
wollen wir uns aber nur mit der Behandlung aperiodischer Ereignisse
befassen.
Ein Problem bei der Behandlung solcher nicht-periodischer Ereignisse
innerhalb eines zeitgesteuerten Systems, ist die Integration der Behandlung
solcher nicht-periodischen Ereignisse in einen periodischen Ablaufplan. Eine
Möglichkeit ist, die nicht-periodische Ereignisbehandlung auf eine periodische
Ereignisbehandlung abzubilden, die prüft, ob das Ereignis aufgetreten ist oder
nicht, und es gegebenenfalls auch bearbeitet (engl. Polling). Dies hat
jedoch zur Folge, dass die Antwortzeit für die Behandlung solcher aperiodischer
Ereignisse unter Umständen sehr groß wird: Angenommen ein aperiodisches Ereignis
tritt unmittelbar nach der periodischen überprüfung ein, dann wird dieses
aperiodische Ereignis erst beim nächsten Durchlauf der ScheduleTable
behandelt. Dieses Verhalten wird durch das folgende, kleine Beispiel
veranschaulicht:
Thread
Startzeitpunkt
Bemerkung
T1
1000 µs
periodisches Ereignis
T2
2000 µs
aperiodisches Ereignis (Polling von AT2)
T3
3000 µs
periodisches Ereignis
T4
4000 µs
periodisches Ereignis
T1
6000 µs
periodisches Ereignis
Ein aperiodisches Ereignis AT2 wird auf die Behandlung eines
periodischen Ereignisses T2 abgebildet. Dieser Thread wird 2000
µs nach dem Start der ScheduleTable eingeplant und hat 1000 µs
Rechenzeit zur Verfügung. Kurz nachdem im ersten Durchlauf der ScheduleTable das
Eintreten des aperiodischen Ereignisses überprüft wurde, tritt dieses Ereignis
tatsächlich ein, behandelt werden kann dieses Ereignis aber erst im nächsten
Durchlauf. Insgesamt ergibt sich so eine Antwortzeit von 8333 µs.
Eine andere Möglichkeit ist, die aperiodischen Ereignisse zu behandeln, wenn
gerade kein periodisches Ereignis bearbeitet wird:
Thread
Startzeitpunkt
Bemerkung
T1
1000 µs
periodisches Ereignis
T3
3000 µs
periodisches Ereignis
T4
4000 µs
periodisches Ereignis
T1
6000 µs
periodisches Ereignis
Die Behandlung des aperiodische Ereignisses AT2 beginnt sofort
nach dem Eintreten des Ereignisses (sofern nicht gerade ein periodisches
Ereignis behandelt wird) und ist bereits nach 5000 µs komplett behandelt,
die Antwortzeit konnte also auf 2333 µs reduziert werden. Zwar müssen bei
der Behandlung aperiodischer Ereignisse keine Fristen eingehalten werden, kurze
Antwortzeiten erhöhen aber die Reaktivität des Gesamtsystems und sind deshalb
wünschenswert. Ein ähnliches Verfahren beschränkt sich nicht darauf,
aperiodische Ereignisse zwischen der Behandlung periodischer Ereignisse zu
bearbeiten: solange der Scheduler garantieren kann, dass die Frist für die
Behandlung des periodischen Ereignisses nicht verletzt wird, wird sie nach
hinten verschoben und stattdessen, falls notwendig, ein aperiodisches
Ereignis behandelt (Slack Stealing). Auf diese Weise lassen sich die
Antwortzeiten für die Abarbeitung aperiodischer Ereignisse noch weiter
verringern.
In dieser Aufgabe soll der ScheduleTable-Scheduler aus Aufgabe 1 um die Fähigkeit erweitert werden, auch
Behandlungen für aperiodische Ereignisse einzuplanen. Als Verfahren soll das
vereinfachte Slack Stealing Verfahren verwendet werden, das in der
übung besprochen wird und oben skizziert ist. Der Einfachheit halber sollen
aperiodische Ereignisse nach dem FCFS-Prinzip bearbeitet werden. Für die
Bearbeitung der Aufgabe sind die rot markierten Klassen zu implementieren
bzw. anzupassen:
Thread_Aperiodic
Die Klasse Thread_Aperiodic ist die Basisklasse für
Aktivitätsträger, die aperiodische Ereignisse behandeln. Im Gegensatz zur Klasse
Thread wird diese Klasse von der Klasse Coroutine
abgeleitet, weil die Behandlung eines aperiodischen Ereignisses von anderen
Ereignisbehandlungen unterbrochen werden kann und später wieder fortgesetzt
wird. Dieses Eigenschaft wird von der Klasse Coroutine zur
Verfügung gestellt.
Abstract_Schedule_Table_Coroutine
Die Klasse Abstract_Schedule_Table_Coroutine wird wie die Klasse
Thread_Aperiodic von der Klasse Coroutine abgeleitet,
um einfach einen Wechsel von einer aperiodischen zu einer periodischen
Ereignisbehandlung ausführen zu können.
Schedule_Table_Scheduler_Aperiodic und Guarded_Schedule_Table_Scheduler_Aperiodic
Neben der Abarbeitung der ScheduleTable übernimmt die Klasse
Schedule_Table_Scheduler_Aperiodic auch den Wechsel zwischen
periodischen und aperiodischen Ereignisbehandlungen und verwaltet aktive
Behandlungen aperiodischer Ereignisse in einer Warteschlange. Immer wenn in der
ScheduleTable eine Lücke vorhanden ist (z.B. bei Beginn der
ScheduleTable oder wenn eine periodische Ereignisbehandlung endet), wird
geprüft, ob aperiodische Ereignisse eingetreten sind und die entsprechenden
Ereignisbehandlungen abgearbeitet. Tritt während der Behandlung eines
aperiodischen Ereignisses ein periodisches Ereignis ein, wird die Behandlung des
aperiodischen Ereignisses unterbrochen und nach der Behandlung des periodischen
Ereignisses fortgesetzt. Die Klasse
Guarded_Schedule_Table_Scheduler_Aperiodic stellt ein gegen
Unterbrechungen gesicherte Schnittstelle der Klasse
Schedule_Table_Scheduler_Aperiodic zur Verfügung.
Eine genauere Beschreibung der jeweiligen Klassen und der zu implementierenden Schnittstellen, findet man in der Doxygen-Dokumentation von EZ-Stubs.