longjmp um i/o-operation abzubrechen?

13/06/2009 - 12:44 von xou | Report spam
Hi,

ich schreibe derzeit im Rahmen eines Uni-Projektes (u.a.) an einem
Simulator fuer eine CPU. Dort gibt es eine art "step"-Modus, die
Iteration um die befehlsausfuehrung wartet mittels getchar() auf ein
"enter", bis der naechste befehl ausgefuehrt wird.
Der Simulator soll bei Beendigung den simulierten CPU-Speicher in eine
Datei schreiben, daher handle ich SIGINT, setze ein flag und bei der
naechsten Iteration wird dann die Schleife abgebrochen.
Bloederweise kehrt der Signalhandler (logischerweise) in die getchar()-
Funktion zurueck, weswegen man zuerst noch mal "enter" druecken muss,
bevor der Simulator sich wirklich beendet.
Meine Frage ist nun, waere es "legal" im signalhandler ein longjmp()
auf eine andere Stelle zu machen? Ich weiss eben nicht was passieren
wuerde, wenn dann waehrend der Beendigung des Simulators doch noch
Daten ankommen und getchar() versucht zurueckzukommen.

Oder gibt es eine elegantere Moeglichkeit fuer das Problem?

MfG,
Niko Weh
 

Lesen sie die antworten

#1 Marcel Müller
13/06/2009 - 16:52 | Warnen spam
Hallo,

xou wrote:
ich schreibe derzeit im Rahmen eines Uni-Projektes (u.a.) an einem
Simulator fuer eine CPU. Dort gibt es eine art "step"-Modus, die
Iteration um die befehlsausfuehrung wartet mittels getchar() auf ein
"enter", bis der naechste befehl ausgefuehrt wird.
Der Simulator soll bei Beendigung den simulierten CPU-Speicher in eine
Datei schreiben, daher handle ich SIGINT, setze ein flag und bei der
naechsten Iteration wird dann die Schleife abgebrochen.
Bloederweise kehrt der Signalhandler (logischerweise) in die getchar()-
Funktion zurueck, weswegen man zuerst noch mal "enter" druecken muss,
bevor der Simulator sich wirklich beendet.



Da Du nicht ernsthaft vor hast, nach dem Signalhandler noch etwas
sinnvolles zu tun, würde ich einfach das Programm hart beenden. Man muss
etwas aufpassen, welche C-runtime Methoden man im Signalhandler aufrufen
darf.

Plan B: Eingaberoutine in eigenen Thread packen, also einer für das UI
und einer für die Arbeit (Simulation, Status-Sichern etc.). Das macht
auf den ersten Blick Arbeit, aber auf den zweiten Blick vieles
einfacher. Darunter auch das, denn es müsste nunmehr im Signal-Handler
nur ein Flag gesetzt werden, dass ein Shut-Down gewünscht ist. Daraufhin
würde der Simulator beim nàchsten Befehl stoppen, den Status sichern und
Harakiri machen. Den Eingabe-Thread kann er dabei gleich mit ins Grab
nehmen. Damit das sicher geht, muss beim Signal natürlich der
Worker-Thread angestoßen werden, falls er gerade blockiert, weil es
nichts zu tun gibt. Sinnvollerweise verpasst man dem Worker gleich eine
Kommando-Queue. SIGINT wàre dann ein priorisiertes Kommando, was immer
als erstes in die Queue gestellt wird. Kommados in der Queue hàtten
stest Prioritàt vor simulierten CPU-Instruktionen.

Meine Frage ist nun, waere es "legal" im signalhandler ein longjmp()
auf eine andere Stelle zu machen?



Ich würde es nicht machen, selbst wenn es im Einzelfall funktionieren
mag. Es gibt irgendwo eine Liste, welche Runtime-Methoden im
Signal-Kontext benutzt werden dürfen. Üblicherweise steht es bei der
Runtime-Doku dabei. Da steht allerdings meist nicht, ob es sich im
Einzelfall um laut Standard garantiertes Verhalten oder um eine
Eigenschaft der jeweiligen Implementation handelt. Also aufpassen, wenn
es portierbar sein soll.

Oder gibt es eine elegantere Moeglichkeit fuer das Problem?



Denke schon, s.o.


Marcel

Ähnliche fragen