Hello,
I have a pretty generic question about embedded RTOS systems and data integrity.
I'm using RTX and I have several instances of structures that need to be read/written from several task.
As an example, take:
struct demo { int var_a; int var_b; int var_a_max; int var_a_min; }
If I have several global demo instances, what is the 'danger' in allowing several tasks to R/W the global instances?
I understand that the values could change mid execution but say you implemented a simple "lock and copy" procedure before each tasks loop execution.
Would mailboxes really be required in this case?
Further, what if all tasks only ever read/write one of the fields (var_a) do you even need a lock and copy or would simple copy do?
Finally, say I did want to implement a generic mailbox pattern so that any task could request a copy from a managing task and send updates to a managing task. Does any one have an example of such a pattern?
Thanks. I appreciate any discussion and opinion on this topic, I'm looking for the most efficient (time and complexity) way to proceed while still being 'safe' in my logic.
M
Because assignment/read operations that involve memory are generally not atomic, register values might get corrupted due to a context switch while such an operation is in progress.
I would say a mutex would be a better choice - but that totally depends on the details of your application.
Any write operation requires synchronization primitives. It might be safer to lock the entire instance considering possible future developments and maintenance.
Thanks for the input Andrew and Tamir.
If I'm not mistaken 32bit reads and writes are atomic on Cortex M3 devices.
This is why I'm unclear as to the need to synchronize access if precaution is taken to always copy the value before using the value in each task?
Tamir - in your experience do you always synchronize access to any global data in a multi task environment? Wouldn't this bloat quite quickly.
(Note I realize good design and all that would lead to minimal synch needed but realistically you often need global data...)
Do you guys use any neat macro wrappers or anything. This really concerns me as I'm only designing half of a system and I need to document the interface for the other half...
Tamir - can you explain how a register value might get corrupted during a context switch? Have you ever experienced this? Wouldn't this be a major concern above and beyond data integrity?
Let's say that task1 needs to increment a value of a variable and that the accesses are not atomic. Typically, it will load the value from memory first - let's assume the variable has an initial value 10. A context switch occurs after the load operation and before task1 can decrement the value, allowing task2 to increment the value to 11 without interruption. Task1, having made a copy of the variable before the context switch, decrements the value to 9 and write it to memory. Task2 will then have to deal with what might represent an undefined situation.
Of course not. In some cases such as when using a circular buffer (producer-consumer design pattern) no synchronization is needed. Pure read access do not require synchronization, of course.
Yes, but see the example above. Typically, the data addressed needs to be changed in some way which is the source of the trouble.
This can save time by reducing overhead, but still requires the usage of synchronization primitives while making the copy to a local variable and when writing back to shared memory.
View all questions in Keil forum