Nadav Har'El
authored
When some code section happens to be called from both thread context and interrupt context, and we need mutual exclusion (we don't want the interrupt context to start while the critical section is in the middle of running in thread context), we surround the critical code section with CLI and STI. But we need the compiler to assure us that writes to memory done between the calls to CLI and STI stay between them. For example, if we have thread context: interrupt handler: CLI; a--; a++; STI; We don't want the a++ to be moved by the compiler before the CLI. We also don't want the compiler to save a's value in a register and only actually write it back to the memory location 'a' after the STI (when an interrupt handler might be concurrently writing). We also don't want the compiler to remember a's last value in a register and use it again after the next CLI. To ensure these things, we need the "memory clobber" option on both the CLI and STI instructions. The "volatile" keyword is not enough - it guarantees that the instruction isn't deleted or moved, but not that stuff that should have been in memory isn't just in registers. Note that Linux also has these memory clobbers on sti() and cli(). Linus Torvals explains in a post from 1996 why these were necessary: http://lkml.indiana.edu/hypermail/linux/kernel/9605/0214.html All that being said, we never noticed a bug caused by the missing "memory" clobbers. But better safe than sorry....