Best way to get latest value to sub task?

cmauler wrote on Sunday, May 29, 2011:

Task 1: higher priority, frequent and performing a calculation to get X
Task 2: lower priority, infrequent and needs to work on the latest value of X (low latency)

I hoped a queue size of one, possibly “sending to front” on each task1 iteration and ignoring the overflow would then have the value ready for when task2 needed it.
BUT from tests running a constantly overflowing one place queue doesn’t yield the same value as a  long* queue and draining it to the last! (*jigged to 100 for the test but not practical for target situation)
I cannot find a explicit statement of what would happen in the overflow situation, as all the text/examples avoid this.
Thanks for your consideration and I was wondering is there an elegant solution?

richard_damon wrote on Sunday, May 29, 2011:

Queue when full will just not write the new value, so your method will give Task 2 the value of X that was first computed after it grabbed a value of X.

What you want is basically a mailbox. Declare a global variable for X, and a mutex to guard it.
When Task 1 has a new value of X, it acquires the mutex, quickly stuffs the value in, then releases the mutex. When Task 2 wants a new value, it acquires the mutex, quickly copies it somewhere private to use, and releases the mutex.

Because it it protected by the mutex, Task 2 can’t get a corrupted value by having X updated in the middle of being read,  and due to the priority methods of th mutex, if task 2 has the mutex for coping out the value, and task 1 interrupts it and computes a new value, task 2 will get a temporary priority boost when task 1 is blocked from writing the new value of X, which is why task 2 needs to be quick at copying the value.

cmauler wrote on Sunday, May 29, 2011:

Thanks for your response

>>Queue when full will just not write the new value, so your method will
>>give Task 2 the value of X that was first computed after it grabbed a value of X.
I hoped for a text book implementation but I guess it’s the easiest

>>What you want is basically a mailbox. Declare a global variable for X, and a mutex to guard it.
It’s just seems inelegant, roll your own and cumbersome when I intend to keep it cooperative.
I’ll give it a try, Thanks

rtel wrote on Monday, May 30, 2011:

Queues are just that, queues.  Things are taken out in the order in which they are put in (unless you post to the front).

richard_damon’s solution is not inelegant, and you could encapsulate the behaviour very easily in an ‘object’.

I would add to richard_dmaon’s solution that, if the size of the variable is equal to the natural size of the microcontroller (i.e. a 32 bit variable on a 32 bit architecture, or a 16 bit variable on a 16 bit architecture, etc.) and task A only ever writes to the variable and task B only ever reads from the variable, then you don’t need to mutex even.

Regards.