Opened on 01/22/23 at 22:07:56
Last modified on 02/13/23 at 06:30:05
#4804 new defect
broadcasting message to single task with higher importance priority can generate multiple messages
Reported by: | Martin Erik Werner | Owned by: | |
---|---|---|---|
Priority: | normal | Milestone: | |
Component: | score | Version: | 4.11 |
Severity: | normal | Keywords: | |
Cc: | Blocked By: | ||
Blocking: |
Description
When a task with lower importance priority broadcasts a single message via a message queue to a task with higher importance priority, it can cause multiple messages to be received.
This seems to occur if the broadcasting task is completely blocked while the receiving task performs multiple receives.
A speculative guess would be that the broadcasting task ends up in a loop where it copies the message and unblocks tasks, but does not keep track of which tasks it has sent to? Thus, if a receiving task is unblocked with the message and then returns to waiting on the message queue again without the broadcasting task being allowed to exit the loop, the receiving task will be unblocked with the same message again.
I have attached the source code of a minimal-ish application which has been able to reproduce this issue on RTEMS 4.11 running on leon3 hardware.
(I had a quick look through Git and could not see any changes to the broadcast code between 4.11 and the latest master that seemed directly related, so possibly the behaviour is still present.)
In this application, the potential amount of messages received from a single broadcast to a single task is seemingly infinite (the application stops it after an arbitrary set limit of 12345 messages).
Enabling the following section makes the behaviour disappear and only 1 message is received.
#if 0 /* If unblocking broadcaster, multiple messages are no longer received. */ status = rtems_task_wake_after(1); assert(status == RTEMS_SUCCESSFUL); #endif
Attachments (1)
Change History (3)
Changed on 01/22/23 at 22:09:26 by Martin Erik Werner
Attachment: | broadcast_prio_maybe_bug.c added |
---|
comment:1 Changed on 01/23/23 at 06:51:02 by Sebastian Huber
Yes, this can happen. I am not sure if this behaviour should be fixed, because if we want to do the message broadcast atomically, we have to disable interrupts around all the message copy operations to the receivers of the broadcast.
comment:2 Changed on 02/13/23 at 06:24:34 by Sebastian Huber
In uniprocessor configurations, the current behaviour could be fixed by disabling thread dispatching for the entire broadcast. This should be acceptable. The disabled thread dispatching prevents that new waiting threads show up in the queue.
In SMP configurations, this is not sufficient (new waiting threads can show up on other processors). We could add a 32-bit generation number to the message queue. When a waiting thread is enqueued, it increments and gets the generation number. In the broadcast we dequeue only threads with a generation number less than the one at broadcast start (modulo operation).
Application which reproduces the behaviour