/************************************************************************************************************* There is a well known problem with reading multi-byte volatile variables atomically on an 8-bit system, ie an ISR could update the variable's bytes half way through a read, causing a corrupted value to be read. Standard solution is to disable interrupts during reads, but this could affect critical ISR response times. In the case of the 1ms timer interrupt, if two back to back reads produce different results, the timer _was_ updated by the ISR and hence either read may have been corrupted. However, in this case, a subsequent 3rd read performed within 1ms of the previous reads will not be updated (or corrupted) by the ISR, so we can return this 3rd read instead. *************************************************************************************************************/ unsigned long millis(void) { // get clean millisecond count ( ISR may have stomped on us) volatile unsigned long m=timer0_millis; // volatile, else code is optimized away if (m == timer0_millis) { // check if 2 reads agree (might have been updated) return m; // was OK so return unchanged value } else { // else was modified by ISR during one of the above reads return timer0_millis; // so can't be changed by ISR for another ms, so read it again } }