title: Rock solid timer interrupt handling
body: <p>I need to execute a procedure at constant time intervals. The procedure takes a long to execute and during that time other interrupt must be active. Also, it is critical that the procedure is executed at each timer overflow.</p>
  
  <p>Take a look at this pseudo-code:</p>
  
  <pre><code>ISR(timer_overflow)
  {
    timer_flag = 1;
  }
  
  main_loop()
  {
    if (timer_flag)
    {
       long_time_consuming_procedure();
       timer_flag = 0;
    }
    (* if a timer interrupt fires here, will the procedure be executed? *)
    sleep();
  }
  </code></pre>
  
  <p>If the above won't work, will the below code make things rock-solid?</p>
  
  <pre><code>main_loop()
  {
    cli();
    if (timer_flag)
    {
       sei();
       long_time_consuming_procedure();
       timer_flag = 0;
    }
    sei();
    sleep();
  }
  </code></pre>
  
  <p>Or maybe this will be better, as other interrupt are handled very quickly:</p>
  
  <pre><code>ISR(timer_overflow)
  {
    sei();
    long_time_consuming_procedure();
  }
  
  main_loop()
  {
    sleep();
  }
  </code></pre>
  
  <p>I'm using avr-gcc</p>
  
  <p><strong>EDIT</strong></p>
  
  <p>Looks like I shared too little detail. I'm afraid of this worst-case scenario:</p>
  
  <ul>
  <li>some interrupt (other than timer overflow) wakes up the uc</li>
  <li>long_time_consuming_procedure is not called as there was no timer overflow</li>
  <li>just before the moment cpu goes back to sleep (betwen <code>if (timerflag)</code> and <code>sleep()</code>) the timer overflows </li>
  <li>timer interrupt is executed correctly</li>
  <li>after returning from ISR cpu goes to sleep without executing <code>long_time_consuming_procedure</code>, because we've already passed <code>if (timerflag)</code></li>
  <li>there are no other interrupts in the following timer cycle, thus cpu is woken up after the next overflow</li>
  </ul>
  
  <p>This way there are two timer interrupts and only one <code>long_time_consuming_procedure</code> execution. There is a very small chance for that to happen, but if something can go wrong it'll go even worse.</p>