Safe Interrupt Enable / Disable

Having trouble switching from cooperative tasking? One of the easiest oversights is your “sei” and “cli” sections.

The diagram below shows how you can run into problems within the critical sections of code. In this example when the memory allocation ends the interrupts are enabled with “cli” removing the critical section around the linked list manager. Once this happens RTI ISR fires and switches in thread 2. This example shows thread 2 popping an item from this list breaking the flow inside of thread 1.


To solve this problem we use a counting semaphore that allows us to keep track of the depth of the critical section.

unsigned int CriticalDepth = 0;
 
void DisableInterrupts( void )
{
   asm volatile("sei");
   ++CriticalDepth;
}
 
void EnableInterrupts( bool force )
{
   --CriticalDepth;
 
   if( CriticalDepth < 1 || force )
   {
      CriticalDepth = 0;
      asm volatile("cli");
   }
}

Leave a Reply