While I would highly discourage messing with the core code's timers and variables,
in this case, whether you use volatile or not will not really matter.
All volatile does is ensure that the value in memory is really read or really written to memory
each time you reference it.
The code that references the volatile variables is
in a function and the compiler will not "remember" or defer the storage of the contents
of those variables to memory beyond the function call so the contents of memory will get updated
just fine even without the use of volatile.
However, what is more important relates to atomicity.
Not only is it important to ensure that the 16 bit variables on 8 bit systems like the AVR
get updated atomically (which is not what volatile does),
but in this case the function itself needs to be fully atomic
because it is mucking around with low level hardware that affects interrupts and
messing variables that are updated inside the ISR routines all while interrupts are still running.
So you have two choices you can either wrap the function with atomicity control
or add it to the function itself.
For example instead of just calling Timer0_reset();
you could wrap it like this:
Or use the ATOMIC_BLOCK() around all the code inside of Timer0_reset();
See this for more about ATOMIC_BLOCK:http://www.nongnu.org/avr-libc/user-manual/group__util__atomic.html
The main reason to avoid mucking around with stuff at this level
is that it makes your code highly unportable.
For example, what if you later decide you want to run your code on an Maple or chipKit "arduino" board?
Both of those support the Arduino s/w environment yet by doing AVR specific low level code
like this you are locked into the AVR and more specifically certain AVR chips.
As you have seen from others, there are other more portable ways to implement the equivalent
of a "reset" of the timer.