Interrupts
-
Hallo,
eine Frage: ein Periphäriegerät sendet ein Interrupt Signal an das Betriebssystem. Das Betriebssystem sichert den aktuellen Prozess um den Interrupt zu behandeln und springt in deren Interrupt Routine. Bevor dieses Interrupt jedoch beendet werden kann, folgt das gleiche Interrupt mit der selben Priorität. Was passiert dann?gruß seux
-
Ich würde sagen, es kommt in eine Warteschlange.
Tatsächlich ist das doch immer implementierungsabhängig...
-
ich würde mal behaupten, bis zum iret sind die abgeschaltet
-
naja, ganz kann das nicht stimmen http://en.wikipedia.org/wiki/Triple_fault
-
warteschlange...
-
Warteschlange ist zumindest schon die richtige Richtung. Meistens handhabt man es so, dass man nicht alle Interrupts in der Interruptsbehandlung deaktiviert, sondern nur denjenigen den man gerade behandelt. Wenn man mit Prioritäten arbeiten will, kann man auch alle mit kleinerer Priorität deaktivieren. So haben Interrupts mit höherer oder gleicher Priorität weiterhin die Möglichkeit schneller abgearbeitet zu werden.
Ein weiteres Problem besteht aber noch darin das man nur mitbekommt, dass ein Interrupt ausgelöst wurde, nicht wie oft. Das kann bei der Verwendung von Timern für die Zeitmessung kritisch sein. Dafür muss man die Interruptbehandlung möglichst kurz halten. Man tut dafür nur das nötigste in der Interruptbehandlung und reiht dann die längeren Aufgaben in eine Warteschlange für später. Damit sind die Interrupts wieder möglichst schnell auslösbar.
oO schrieb:
naja, ganz kann das nicht stimmen http://en.wikipedia.org/wiki/Triple_fault
Double und Triple Fault ist noch nen bisschen was anderes. Ein Double Fault tritt auf wenn eine Interruptbehandlungsroutine nicht ausgeführt werden kann, weil sie z.B. nicht in einem erreichbaren Speicherbereich liegt etc. Das was der TE meint sind verschachtelte (nested) Interrupts.
-
vllt. sollte man dann wiki überarbeiten?
3. Die CPU akzeptiert die Unterbrechungsanforderung und führt den Interruptzyklus durch, in dessen Verlauf (je nach CPU) der Interruptvektor vom Datenbus gelesen wird. Danach wird der Interrupteingang automatisch maskiert und somit gesperrt, damit nicht beliebig geschachtelte Interruptsequenzen auftreten können und dadurch einen Stackoverflow ermöglicht.
8. Die ISR beendet sich durch einen Rücksprung (RTI), der das Rückspeichern des alten Befehlszählers und ggf. des alten Statusregisters vom Stack bewirkt und der dadurch wieder seinen Stand wie vor der Unterbrechung hat (so als wäre nichts gewesen). Durch die Rückspeicherung des Statusregisters (das auch das Interrupt-Mask-Bit enthält) ist die Interruptlogik unmittelbar bereit, weitere IRQs zu akzeptieren.
-
Nur so am Rande...
Es gibt level-triggered, edge-triggered und event-basierte Interrupts.
Bei PCI war soweit ich weiss level-triggered Standard, PCI-Express Interrupts sind event-basiert.Bei level-triggered Interrupts kann der selbe Interrupt sowieso nicht ausgelöst werden während der Interrupt-Handler dafür gerade läuft -- das Signal für die Interrupt-Anforderung ist dabei ja schon logisch 1, und daher ist keine Zustandsänderung erkennbar wenn noch ein 2. Gerät dazukommt das diese Leitung auch auf 1 zieht.
Bei edge-triggered bzw. event-basierten Interrupts wäre es möglich, wird aber soweit ich weiss normalerweise vom OS unterdrückt.
Üblich ist dabei dass ein Interrupt nur von einem mit höherer Priorität unterbrochen werden kann, alles was niedrigere oder gleiche Priorität hat muss warten.Wie das dann genau implementiert ist, ist dann je nach OS bzw. je nach Hardware unterschiedliche (soweit ich weiss machen das auch verschiedene HALs von Windows unterschiedlich). Eine Möglichkeit ist dass Interrupts mit niedrigerer Priorität hardwaremässig sofort maskiert werden.
Eine andere Variante ist dass das OS erstmal optimistischerweise davon ausgeht dass eh kein anderer Interrupt dazwischenfunkt. Kommt doch einer dann wird ein Interrupt-Handler des OS aufgerufen, der erstmal die Priorität checkt. Ist sie höher dann wird gleich der Interrupt-Handler des Treibers aufgerufen. Ist sie gleich oder niedriger, dann wird nur vermerkt dass es noch was zu tun gibt, und sofort an den alten Interrupt-Handler zurückgegeben. In so einem System ist im Callstack also immer noch eine Wrapper-Funktion des OS, die einerseits den Prioritäts-Check macht, und andrerseits beim zurückkehren guckt ob ein anderer Interrupt zur Abarbeitung vorgemerkt wurde.
Der Vorteil davon ist dass man sich dadurch das (oft recht langsame) Umprogrammieren des Interrupt-Controllers in dem meisten Fällen spart - weil die meisten Interrupts eh nicht unterbrochen werden.
-
Die Frage erinnert mich an DOS-Interupts, die man gewöhnlich in Assembler behandelte. Kann man sicher noch machen, nur wozu?
-
"DOS-Interrupts" sind eine API, die behandelt man nicht die verwendet man.
Die Interrupts die man in DOS behandeln kann sind ganz normale Interrupts.
Die werden ja auch nicht zu "Windows-Interrupts" oder "Linux-Interrupts" nur weil man ein anderes OS installiert hat.