digaboy wrote on Thursday, June 06, 2019:
I need some advice on a new design I’m working on.
My design is based on 3 tasks and is mostly event based.
Each tasks can be wake up by message (short fixe or long variable length) comming from multiple source (task or interrupt) but each message will be re read by only 1 task.
My question is: what is the best and cleaniest solution to build the communication frame ?
Solution A: 1 queue buffer for each task to read in and data is a struct with message type and a pointer to data
Solution B: 1 queue buffer for each writer (so either fix length or pointer type) and a queue set
Solution C: 1 message buffer for each writer and each task is wake up by notification and will look into each message buffer.
From what I know, A is better than B.
So the question is A or C ?
Which one is the best and why ?
richarddamon wrote on Thursday, June 06, 2019:
My base design practice is A. My preference is that I design a task to handle something, and it will typically be blocked waiting for that something.
A key point to see this is that generally the writter will know what task it want to send a given messge to (and in C it still needs to so it wakes up the right one), and so in A it uses that knowledge to put the message in the right queue. In C, it sort of throws that information out, and the task has to look around to find the work that was given it. You also have a problem that the reader needs to first peek at the message to see if it is something it can handle, or if it is for someone else, and there is no way to really handle a writer wanting to send a message to two different tasks, the second one will be hidden until the first is taken.
The one reason I can see to have a queue/buffer per writter is if you need to process the messages wiith a priority based on writer. Queue are strictly either FIFO or LIFO (depending which end you add the new message), and can’t sort messages based on priority.
Queue sets can be better if a task needs to handle multiple types of notification that would be inefficient trying to reshape into a single queue, If you had multiple identical readers, and were using them as a thread pool, (and processing was I/O bound, so the tasks did a lot of blocking in processing the message) then the Queue set could work, that way the writers wouldn’t need to figutre out which of the identical threads was ready to be woken.
digaboy wrote on Thursday, June 06, 2019:
Tanks for the detail answer !
My first impulse was also solution A and then I remenber about the notification and message buffer introduce in V10 and told myself that it could be a clean solution (because I usually have only one reader for a message)
And so a combination of multiple message buffer and task notification (or event) could solve the X writers / 1 reader scenario.
But it’s only valid for a static design where all task are clearly identified.
You also have a problem that the reader needs to first peek at the message to see if it is something it can handle, or if it is for someone else, and there is no way to really handle a writer wanting to send a message to two different tasks, the second one will be hidden until the first is taken.
I’m not sure to properly understand this part, because for me a message buffer is for a 1 writer / 1 reader scenario. So there is no need to peek at the message because your know that this message is for you by design.
richarddamon wrote on Friday, June 07, 2019:
My description had the presumption that you have multiple tasks that you might want to be able to talk to. (since in case A, you have an ‘each task’). If tasks have just a single outbox, then either they can only ever talk to a single task, or you have the posibility of multiple tasks needing to check that outbox (or they need multiple out boxes, which sort of gets back to multiplication of A and C)
Note that message buffers can have more than one reader or writer, it just needs to be only one AT A TIME, and there be someting like a mutex (maybe one for each end) that makes it so that there is only one task attempting to read or write the buffer at a time.
digaboy wrote on Friday, June 07, 2019:
My description wasn’t very clear so I draw a quick overview of my task and message between them
(blue mail are short fixe message and green are variable length)