urxae wrote:
Mine simple implementation is basically:
- A counter (starts at 0)
- An IRQ handler that simply increments that counter.
- Another counter which keeps track of the last counter value waited for. This should ensure correct behavior in cases like a thread-switch occurring (or the hardware is unexpectedly fast) causing the IRQ to fire before IRQ_wait() gets executed. In my implementation, this is a static variable in IRQ_wait. It's incremented just before exiting from IRQ_wait.
- IRQ_wait itself then just loops until the counter is different. It should probably call yield() to schedule another thread while it waits, to avoid wasting CPU time waiting for the floppy that could be better spent doing useful stuff.
Actually one can get away with even more simple implementation, for which you only need one bit flag: as long as you make sure to clear the flag before you start an operation which could cause an interrupt, you only need to wait until the interrupt handler sets the flag. All interrupts you should get in your floppy handler should be known beforehand, so the only potential race-condition would be when the interrupt comes before you cleared the flag. If the flag is cleared when the interrupting operation is started, there should be little to worry about, unless you want to prepare for the possibility of getting interrupts which have nothing to do with the floppy drive.
Anyway, you should probably consider using a semaphores instead, since then you don't need to loop/yield anything, because you get scheduled only when something happens (timeout or post()). If you don't have semaphores, I suggest you implement them, as they are very nice for building all kinds of more advanced synchronization primitives, and very flexible, allowing you to easily come up with different policies.
My floppy driver's interrupt handler actually checks that the semaphore is zero (using trywait(), the non-blocking wait(), until it returns with an error indicating that wait() would block) before post()ing, so that the value of the semaphore will never be more than one. That way I make sure that at least extra interrupts will never accumulate; in the worst case they confuse the driver, which then has to reset the drive to recover a known state.