Handling issue 146 will further diverge performance on ports above F, which already required more code. It struck me overnight that this MIGHT be a reason for continued existence of digitalWriteFast beyond implementation of faster digitalWrite in the core. After all, the vast majority of code I write does not turn the interrupt on. Worth some thought.
It also strikes me that I should probably create test code for whether issue 146 is solved. Maybe I can just add Tone to my current test programs, or something like that. I need something that will generate interrupts 10-1000 times per second, I think. If anyone understands how to write that, or can point me to a forum item I would appreciate that.
Ah... issue #146. (I was the one that asked Paul to post this bug)
There should be no need to write & run test code to see if this is resolved.
Either the foreground bit set/clear operations are atomic or they
aren't. A simple code inspection can determine this.
(Ideally, look at the assembler output, it will be obvious)
I recommend code inspection over test code because it is super easy and because with test code there is no guarantee that the exact timing scenario will ever exist to create a problem.
Keep in mind that ensuring that the i/o operation is atomic
is not about protecting bits set/cleared in registers by the users foreground (loop) code from being interrupted by interrupt code, it is about protecting the bits set/cleared by the other code done in interrupt routines from the users foreground (loop) code.
It does not matter if the user does not have any
code that runs as an interrupt. It will be his foreground (loop) code
that clobbers the bits set/cleared/used by the interrupt routine.
The users foreground (loop) code i/o operations will always complete and work flawlessly with or without the atomic code masking
And so Ironically, the code that runs at interrupt level like the servo library code does not need to have the additional code overhead of masking/clearing interrupts to make the operation "atomic" since the code is running at interrupt level, it is by definition atomic but
the foreground (loop) code running must have it, if they share the
same i/o register.
And that is the dilemma, sometimes you need the extra code overhead
to ensure the operation is atomic and sometimes you don't need
it to still have atomicity, and yet other times, you may not need atomicity at all.
The problem is the only time you can be ensured that you don't need
it, is if the code is part of an interrupt routine.
In my view, ALL the i/o operations need to be atomic.
Anything else, doesn't really work, and eventually will cause
Yes there are situations where you can be guaranteed that the
additional code to mask/restore interrupt masks isn't needed but
those are only in interrupts routines which are typically library code
and usually not done by the normal/casual arduino user.
If it were desirable to support some thinner/faster i/o routines to be used
by ISR routines, then that is definitely possible
but again, this goes back to my original suggestion of using
layering and _ (underbar) functions/macros so that the code writer can pick and choose what level of support his code needs.