Page 1 of 2

[solved] Queuing interrupts

Posted: Sun Jan 31, 2016 3:48 pm
by onlyonemac
Hi,

Seems like a silly question, but what is the situation if a second interrupt arrives to the PIC before the first one has been handled (signalled by the "end of interrupt" command)? Will the second interrupt be queued, or discarded? Does it make any difference if the second interrupt is disabled by the PIC's IMR?

Regards,

onlyonemac

Re: Queuing interrupts

Posted: Sun Jan 31, 2016 4:02 pm
by Brendan
Hi,
onlyonemac wrote:Seems like a silly question, but what is the situation if a second interrupt arrives to the PIC before the first one has been handled (signalled by the "end of interrupt" command)? Will the second interrupt be queued, or discarded?
Normally there's an IRQ priority scheme; and if the second interrupt is higher priority it'll be delivered to the CPU (interrupting the first IRQ's interrupt handler), and if the second interrupt is lower priority it will be queued.

Of course this is effected by multiple things (a few different "unusual" modes in the PIC chip itself, and the CPU's interrupt enable/disable flag).
onlyonemac wrote:Does it make any difference if the second interrupt is disabled by the PIC's IMR?
Yes; if it's disabled in the PIC's IMR then the PIC ignores it.


Cheers,

Brendan

Re: Queuing interrupts

Posted: Mon Feb 01, 2016 1:11 am
by onlyonemac
How many interrupts can the PIC queue? Like, if my PIT interrupt handler takes longer than the interval of the PIT, how many queued PIT interrupts will I get after I disable the PIT (note: not disabling it in the PIC but telling the PIT to stop firing that channel - I think it's channel 0)? What if another interrupt arrives and the queue is full?

Basically, how concerned should I be about (relatively) long interrupt handlers which aren't finished before the next interrupt comes?

Re: Queuing interrupts

Posted: Mon Feb 01, 2016 1:30 am
by iansjack
If your timer interrupt handling takes longer than the interval between timer ticks then you have BIG problems. I believe that only one outstanding interrupt is "queued" and further interrupts from the same source will be lost.

Re: Queuing interrupts

Posted: Mon Feb 01, 2016 1:39 am
by FusT
Strictly speaking you shouldn't be concerned about long handlers not finishing because handlers should be as short as possible (i.e. KB Interrupt occurs, Invoke keyboard handler, read scancode(s), write to buffer/pipe/whatever, send EOI, return)

As for how many interrupts it can queue I'd suggest reading the docs on the Intel 8259 (PIC).

EDIT: Did a quick read through the docs and can't find anything on buffering/queuing interrupts.
I do believe iansjack is right, never tested it though.

Re: Queuing interrupts

Posted: Mon Feb 01, 2016 4:07 am
by Brendan
Hi,
onlyonemac wrote:How many interrupts can the PIC queue? Like, if my PIT interrupt handler takes longer than the interval of the PIT, how many queued PIT interrupts will I get after I disable the PIT (note: not disabling it in the PIC but telling the PIT to stop firing that channel - I think it's channel 0)? What if another interrupt arrives and the queue is full?
The PIC has 2 sets of flags. When an interrupt occurs it sets the corresponding flag in its "Interrupt Received Register" (and if that flag was already set then an interrupt is lost). When the PIC sends the IRQ to the CPU it clears the flag in its "Interrupt Received Register" and sets the flag in its "In Service Register". When you send EOI to the PIC, it clears the flag in the "In Service Register".

This means that (for both PIC chips combined) you can have up to 15 IRQs in service (one of each), plus up to 15 IRQs pending (one of each).
onlyonemac wrote:Basically, how concerned should I be about (relatively) long interrupt handlers which aren't finished before the next interrupt comes?
Most devices can't/don't try to send a second IRQ to the PIC until you've given the device some attention. For PS/2 you have to read a byte from its buffer, for RTC you have to read its status register, for floppy you have to send a second command, etc. This means that if IRQs aren't handled quickly enough things get backed up somewhere else and not in the PIC chips (causing lost data for some devices and slow performance for other devices, and not lost IRQs).

There's only 2 situations (that I know of) where this isn't the case. For the PIT chip operating in a periodic mode (and not "one shot") you don't need to give the device any attention and it can send more IRQ to the PIC chip before you've handled the first.

For serial ports, you do need to give the device some attention (fetch bytes from its FIFO) before the same serial port can send a second IRQ; but you can have 2 serial ports using the same IRQ and that can cause lost IRQs (e.g. COM1 and COM3 both send IRQs at the same and there's nothing you can do to prevent an IRQ from being lost). This requires a little tricky handling to avoid race conditions (always check both serial port's status registers and be prepared to receive a "nothing to do" IRQ because you handled the cause during the previous IRQ).


Cheers,

Brendan

Re: Queuing interrupts

Posted: Mon Feb 01, 2016 6:33 am
by onlyonemac
Thanks Brendan, that makes sense now.

Re: Queuing interrupts

Posted: Mon Feb 01, 2016 6:43 am
by onlyonemac
On re-reading the wiki page, I just don't know how the PIC handles the following condition:
  • First interrupt comes
  • During execution of handler for first interrupt, second interrupt (different IRQ) comes
  • Handler for second interrupt sends EOI and returns (to first interrupt handler)
  • Handler for first interrupt sends EOI and returns (to whatever was happening when first interrupt occurred)
How does the PIC know which EOI belongs to which interrupt? Must I send just one EOI, after both handlers have completed? Should I disable interrupts on entry to the first handler (at the risk of missing a higher-priority interrupt)?

Re: Queuing interrupts

Posted: Mon Feb 01, 2016 6:49 am
by iansjack

Re: Queuing interrupts

Posted: Mon Feb 01, 2016 7:06 am
by onlyonemac
iansjack wrote:The documentation explains it all: https://pdos.csail.mit.edu/6.828/2005/r ... /8259A.pdf
That document isn't really readable with my screenreader - how hard can it be for someone to answer a simple question? I'm sure someone already knows the answer anyway.

Re: Queuing interrupts

Posted: Mon Feb 01, 2016 7:12 am
by iansjack
Sorry, but I believe in pointing people at the right answer rather than spoonfeeding them. That way they learn more and are better equipped to solve their own problems.

I'll leave it for someone with a different perspective on education to spoonfeed you the answer.

Re: Queuing interrupts

Posted: Mon Feb 01, 2016 7:50 am
by Combuster
iansjack wrote:I'll leave it for someone with a different perspective on education to spoonfeed you the answer.
onlyonemac wrote:That document isn't really readable with my screenreader
I think it's pretty rude to claim spoonfeeding when you insist on someone visually impaired to read something that's of such a quality that it's just barely legible for normal people to start with.

Re: Queuing interrupts

Posted: Mon Feb 01, 2016 8:07 am
by Combuster
For reference, the chapter in question. Minus all the garbage that ctrl+c/ctrl+v from a PDF introduces.
The In Service (IS) bit can be reset either automatically following the trailing edge of the last in sequence INTA pulse (when AEOI bit in ICW1 is set) or by a command word that must be issued to the 8259A before returning from a service routine (EOI command). An EOI command must be issued twice if in the Cascade mode, once for the master and once for the corresponding slave.

There are two forms of EOI command: Specific and Non-Specific. When the 8259A is operated in modes which perserve the fully nested structure, it can determine which IS bit to reset on EOI. When a Non-Specific EOI command is issued the 8259A will automatically reset the highest IS bit of those that are set, since in the fully nested mode the highest IS level was necessarily the last level acknowledged and serviced. A non-specific EOI can be issued with OCW2 (EOI = 1, SL = 0, R = 0).

When a mode is used which may disturb the fully nested structure, the 8259A may no longer be able to determine the last level acknowledged. In this case a Specific End of Interrupt must be issued which includes as part of the command the IS level to be reset. A specific EOI can be issued with OCW2 (EOI = 1, SL = 1, R = 0, and L0-L2 is the binary level of the IS bit to be reset).

It should be noted that an IS bit that is masked by an IMR bit will not be cleared by a non-specific EOI if the 8259A is in the Special Mask Mode

Re: Queuing interrupts

Posted: Mon Feb 01, 2016 8:15 am
by iansjack
Combuster wrote:
iansjack wrote:I'll leave it for someone with a different perspective on education to spoonfeed you the answer.
onlyonemac wrote:That document isn't really readable with my screenreader
I think it's pretty rude to claim spoonfeeding when you insist on someone visually impaired to read something that's of such a quality that it's just barely legible for normal people to start with.
You're right. I'm in the wrong place.

Re: Queuing interrupts

Posted: Mon Feb 01, 2016 12:31 pm
by onlyonemac
Combuster wrote:For reference, the chapter in question. Minus all the garbage that ctrl+c/ctrl+v from a PDF introduces.
The In Service (IS) bit can be reset either automatically following the trailing edge of the last in sequence INTA pulse (when AEOI bit in ICW1 is set) or by a command word that must be issued to the 8259A before returning from a service routine (EOI command). An EOI command must be issued twice if in the Cascade mode, once for the master and once for the corresponding slave.

There are two forms of EOI command: Specific and Non-Specific. When the 8259A is operated in modes which perserve the fully nested structure, it can determine which IS bit to reset on EOI. When a Non-Specific EOI command is issued the 8259A will automatically reset the highest IS bit of those that are set, since in the fully nested mode the highest IS level was necessarily the last level acknowledged and serviced. A non-specific EOI can be issued with OCW2 (EOI = 1, SL = 0, R = 0).

When a mode is used which may disturb the fully nested structure, the 8259A may no longer be able to determine the last level acknowledged. In this case a Specific End of Interrupt must be issued which includes as part of the command the IS level to be reset. A specific EOI can be issued with OCW2 (EOI = 1, SL = 1, R = 0, and L0-L2 is the binary level of the IS bit to be reset).

It should be noted that an IS bit that is masked by an IMR bit will not be cleared by a non-specific EOI if the 8259A is in the Special Mask Mode
Should I assume that the higher-order interrupts thus take priority over the lower-order ones? In other words, if I get a second interrupt before I've returned from the first, may I assume that it is a higher-order interrupt? Another way to word this is: if I get an interrupt and I haven't yet sent an EOI, may I assume that only higher-order interrupts will be passed to the CPU and that lower-order ones will be discarded/queued until the first interrupt is handled? (Sorry for asking this so many different ways but I'm wanting to make sure that I'm clear on this because accessible documentation on the topic seems scant.)