This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Problem with multiple calls to MessageQ_registerHeap() for the same heap

Hi,

We've come across a problem with calling MessageQ_registerHeap() multiple times for the same heap.

I've tried to write an abstraction for SYS/BIOS heaps and message-queues. We want each message-queue to have it's own heap, so I've written two functions : one to create the message-queue and one to open an existing message-queue.

The create-message-queue function creates a heap (via a call to HeapMemMP_create()), creates a message-queue (via a call to MessageQ_create()) and then links the message-queue to the heap (via a call to MessageQ_registerHeap()). So far so good.

The open-message-queue function opens an existing heap (via a call to HeapMemMP_open()) and opens an existing message-queue (via a call to MessageQ_open()). I then also link the opened message-queue to the opened heap (via a call to MessageQ_registerHeap()).

This works fine if the receive and send sides of the message-queue are on different cores.

However, I've found that if both ends of the message-queue are on the SAME core (i.e. using two threads/tasks), the second call to MessageQ_registerHeap() (in the open-message-queue function) fails with MessageQ_E_ALREADYEXISTS.

If I take out the call to MessageQ_registerHeap() from the open-message-queue function, then the code with both ends of the message-queue on the SAME core works, but the code with the receive and send sides of the message-queue on different cores then fails with an assert.

So, I've left the code to invoke MessageQ_registerHeap() in the open-message-queue function.

I suspect that MessageQ_registerHeap() would also fail with MessageQ_E_ALREADYEXISTS if I also had multiple writers for the message-queue on the same core (and the single reader of the message-queue on a different core) ...

I've put code in my open-message-queue function to ignore the MessageQ_E_ALREADYEXISTS error when calling MessageQ_registerHeap(), but I'm worried that this will MISS any real errors where there really has been a mismatch of heap-handle and heap-id.

Is the REAL problem with the code for MessageQ_registerHeap() not comparing the existing heap-handle with the proposed new heap-handle and only reporting an error if they differ ?

So, instead of (this snippet from the implementation of MessageQ_registerHeap()):

 if (MessageQ_module->heaps[heapId] == NULL) {
MessageQ_module->heaps[heapId] = iheap;
status = MessageQ_S_SUCCESS;
}
else {
status = MessageQ_E_ALREADYEXISTS;
}

we could have:

 if (MessageQ_module->heaps[heapId] == NULL) {
MessageQ_module->heaps[heapId] = iheap;
status = MessageQ_S_SUCCESS;
}
 else if (MessageQ_module->heaps[heapId] == iheap) {
 status = MessageQ_S_SUCCESS;
}
 else {
status = MessageQ_E_ALREADYEXISTS;
}

Or, have I got the wrong end of the stick ?

Regards,

Graham.

P. S. This is coded against MCSDK 2.0.4.16 (aka SYS/BIOS 6.32.04.49 and IPC 1.23.01.26)

  • Graham,

    In summary, you are correct, the same heap handle cannot be registered with the same heapId multiple times. Your suggestion above would work, but, since there is no reference counting, when the first thread calls MessageQ_unregisterHeap, it will leave the second thread stranded without a heap. I think you need to keep track of the number of clients wanting to register heap handles in your abstraction layer. You can use the heapId as an index into an array which tracks a reference count and heap handle. If a second call comes in for the same heapId with the same heap handle, just increment the reference count, otherwise it's an error. Only the first register and last unregister calls will actually call into MessageQ.

    Be sure to protect this code with a gate in case multiple threads are registering and unregistering at the same time.

    ~ Ramsey

  • Ramsey,

    Doh!

    I completely forgot about MessageQ_unregisterHeap() ! Or, rather, I don't use it.

    Your suggestion for how to fix this makes perfect sense. Sadly.

    You could build all of this into the MessageQ code for registering and unregistering heaps. However, I guess this would add a lot of unneccessary baggage (overhead) for all users of MessageQ when only a small minority would want to make use of reference-counted registered heaps. In which case, wrapping an abstraction around the MessageQ code that also adds reference-counting would be the way to go.

    If this was C++, you could introduce some handy "RefCounted" policy templates !

    Thanks for the help,

    Graham.

  • Graham,

    I think that you have a valid use-case. I've filed an enhancement request: "MessageQ heap registry should be reference counted". I'll advocate to implement this feature in MessageQ.

    ~ Ramsey