Flushing buffer cache from ISR
I'm working on an ARM-based embedded system that uses the FIQ interrupt to signal a loss of power. When this interrupt occurs, there will be a few seconds flush the buffer cache. I originally thought that calling sync() from the ISR might do the trick, but I want to force the flushing of dirty buffers to disk immediately, not just mark the pages dirty 开发者_Python百科and wait for the system to flush the dirty buffers (which is apparently what sync() does). Thanks in advance for any advice.
djw
The first rule of embedded systems programming is:
Never, ever, ever ever, do any work from an ISR.
ISRs operate in really weird processor modes and you can't access operating system services from them. You certainly can't do anything that blocks from them (such as disk access). About the only thing most OSes will let you do is to post events and release semaphores.
The usual way to structure this kind of problem is to have a normal user-space task that sits waiting on a semaphore. When the interrupt comes in the ISR will release the semaphore and exit; the task will become runnable and then it's just user-space code.
isr()
{
clear_interrupt_condition(); // to avoid the interrupt being retriggered
post(semaphore);
}
task()
{
for (;;)
{
wait(semaphore);
sync();
}
}
Depending on the OS, you may have specific help for doing this kind of thing. I've used OSes that did all the above for you, automatically, if you asked it to. Or they'd let you structure it as an event mechanism where the ISR would post a message to a queue and the work would be done from an event handler.
Incidentally, sync()
doesn't (or at least shouldn't) just mark the pages dirty; Posix specifies that it mustn't return until the data has been flushed to disk (inasmuch as the kernel can).
精彩评论