richard_damon wrote on Friday, April 06, 2018:
The fundamental issue with sharing variables between tasks is that you need to be sure that every access sees a ‘valid’ value. If all the operations are effictively atomic, this isn’t an issue, so adding protection isn’t needed.
As an example, lets look at a case where it would be needed. Let us assume we have a counter counting in minures and seconds as two distinct variables. Let us say that the counter is currently at 1 minute and 59 seconds, and one task is going to read this value and another increment it. The incrementing task will first change the seconds from 59 adding 1 to get 60, see that it is time to roll over and set it to 00 and then go and increment the minutes from 1 to 2. That says that the counter existed with sequential values of
1:59
1:00
2:00
So if something of a higher priority came in between setting to 1:00 and 2:00 it would see the wrong value.
Another issue is a lower priority reader might first grab the seconds, and then the minutes, and if this was interrupted by the increment, it might get the value 2:59, which again is wrong.
With this sort of non-atomic read/update, you need to guard the accesses so that you can’t interrupt a read or update to get an inconistant value.
IF on the other hand, this value was stored in something that was read or written in a single atomic cycle, then these issues couldn’t happen, as the increment couldn’t break into the ‘middle’ of the read, and if the update is atomic then the 1:00 value was never written into the variable, so nothing could have gotten that value.
SIngle writter is normally important, as writers often need to read the value, do something with it and then write back the new value. And from a writer prospective this needs to be atomic too. If there is only one writer, this isn’t an issue, but if multiple tasks might update the value, they normally need to guard things such that nobody else can modify the value between when they read the old value and wrote the new value.
If the value being read and written is accessed/changed with a single instruction, then by the design of the hardware, this will happen atomically. You can’t get part of the result, then go off and do another task, and then come back and finish the rest of the instruction’s access. The only way to be absolutely 100% positive of this, is to inspect the assembly code generated, but generally, access to ‘int’ variables will be atomic on virtually all processors.