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.

Multiple Tasks with Heap collision

Other Parts Discussed in Thread: SYSBIOS

I am trying to get multiple tasks working with a MessageQ created on Core0 using a heap created in shared memory.  This has already been implemented with a working MessageQ between Core0 and Core1.  Core1 has a single task that uses the MessageQ between core0 and core1.  The Shared MQ Heap is created on Core0 and then opened in Core1 without any problems when only that one task is running on core1.  The issue I am having is I am trying to create a second task on Core1 that uses quite a few large mallocs/callocs.  In order to get the mallocs and callocs to run in the task I created a Default heap entry to use DDR memory.  This task when running alone on Core1 also works fine by itself.  As soon as I try to run both tasks and perform any mallocs or callocs it causes the MessageQ heap to not open.  

This raises the first question as to are memory allocs thread safe between multiple threads.  If multiple threads accessing the default heap in memory are not thread safe is there a way to specify the MessageQ heap_handle to not use the default heap but a second heap I can create in LL2RAM.  

This is the excerpt of opening the shared memoryQ on core 1 that fails when we run the second task.

   do {

      status = HeapBufMP_open("MQHeap", &heap_handle);

   } while (status < 0);

   // register the heap with message queue

   MessageQ_registerHeap((IHeap_Handle)heap_handle, 0);

   //MessageQ_registerHeap(SharedRegion_getHeap(0), 0);

The problem I can see is that heap_handle in HeapBufMP_open is getting a handle to our local DDR heap and this call is conflicting with mallocs on the other task.  Is it at all possible to have heap_handle use another heap besides the default DDR heap we have create?  Or possibly a way to have a separate Default heaps for each individual task running on the same Core?

Any help or ideas to point me in the right direction would be appreciated.  I should also mention we are using BIOS  6.31.04.27.

 

Thanks

  • Edward,

    You can register multiple heaps with MessageQ.  When you call MessageQ_alloc() the first parameter specifies from which heap you want to do the alloc.  Are you alloc'ing from the heap that you want?

    Yes doing MessageQ_alloc or any memory alloc in SYSBIOS/IPC should be thread safe...By default there is a GateMutex for protection.

    Judah

  • Thank you for your reply.  Hopefully I can try and give some more detail on the problem we are having trying to get these multiple tasks on core1 running together.  The problem seems to be that we are creating a HeapMem in DDR and setting this to the default heap instance on core1.  In one task of the core1 we are attempting to use HeapBufMP_open call to get a handle to a shared memory heap created on core0 that will be used for the MessageQ.

     After doing some reading it seems that the handle to for the heap of the shared memory region used by both core0 and core1 is stored in the local heap of the cores.  Please correct me if I misunderstood but I read this in the IPC User Guide section 3.8.  

    So when this call is made on core0, HeapBufMP_open("MQHeap", &heap_handle); The heap_handle is pointing into the default heap which is in DDR.  But when another task is allocating into the default DDR heap that HeapBufMP_open call fails and no heap_handle is made.  

    So why would calling the HeapBufMP_open call fail? Could this be a conflict when using a default heap.  

    This is the default heap we have set up in our core1 .cfg file. Not sure if this wil help point out our problem or not.

    /*core1.cfg*/

    var ti_sysbios_heaps_HeapMem = xdc.useModule('ti.sysbios.heaps.HeapMem');

    var instti_sysbios_heaps_HeapMem1Params0 = new ti_sysbios_heaps_HeapMem.Params();

    instti_sysbios_heaps_HeapMem1Params0.sectionName = ".DDRHeap";

    instti_sysbios_heaps_HeapMem1Params0.size = 0x300000;

    Program.global.DDR_Heap = ti_sysbios_heaps_HeapMem.create(instti_sysbios_heaps_HeapMem1Params0);

    xdc_runtime_Memory.defaultHeapInstance = Program.global.DDR_Heap;

    Program.sectMap[".DDRHeap"] = "DDR";

    Program.heap = 0x300000;

    xdc_runtime_Memory.defaultHeapSize = 0x300000;

    /*core1.cfg*/

     

     

     

  • Edward,

    Edward Crampton said:

    Thank you for your reply.  Hopefully I can try and give some more detail on the problem we are having trying to get these multiple tasks on core1 running together.  The problem seems to be that we are creating a HeapMem in DDR and setting this to the default heap instance on core1.  In one task of the core1 we are attempting to use HeapBufMP_open call to get a handle to a shared memory heap created on core0 that will be used for the MessageQ.

     After doing some reading it seems that the handle to for the heap of the shared memory region used by both core0 and core1 is stored in the local heap of the cores.  Please correct me if I misunderstood but I read this in the IPC User Guide section 3.8.  

    When you create a SYSBIOS or IPC object, there's always an instance of the object that is created in the local heap of each core.  If the object uses shared memory, [ie..HeapBufMP] there will be a pointer in the instance that points to the shared memory its using.  So I think your understanding is correct.  There is a handle in the local heap for the instance.

    Edward Crampton said:

    So when this call is made on core0, HeapBufMP_open("MQHeap", &heap_handle); The heap_handle is pointing into the default heap which is in DDR.  But when another task is allocating into the default DDR heap that HeapBufMP_open call fails and no heap_handle is made.

    Are you calling HeapBufMP_open() on core0?  So you created the HeapBufMP on core0 and then you are callling HeapBufMP_open() to open the heap from another thread? This is okay, just want to make sure this is what you meant?

    Where is your "heap_handle" declared?  Is this a local variable?  After doing a HeapBufMP_open(), heap_handle will have a pointer within its instance state that points to the shared memory used by the "MQHeap" instance.  

    I'm confused by the statement "But when another task is allocating into the default DDR heap that HeapBufMP_open call fails".  Are you allocating from the default Heap or are you trying to allocate from the HeapBufMP heap?

    Edward Crampton said:

    So why would calling the HeapBufMP_open call fail? Could this be a conflict when using a default heap.  

    This is the default heap we have set up in our core1 .cfg file. Not sure if this wil help point out our problem or not.

    So now your saying HeapBufMP_open() is failing?  I thought it was the allocation before.  From which core is this failing?  You need to be a bit clearer here, I'm getting all confused on which core is creating/opening/allocating and from which heap.

    Edward Crampton said:

    /*core1.cfg*/

    var ti_sysbios_heaps_HeapMem = xdc.useModule('ti.sysbios.heaps.HeapMem');

    var instti_sysbios_heaps_HeapMem1Params0 = new ti_sysbios_heaps_HeapMem.Params();

    instti_sysbios_heaps_HeapMem1Params0.sectionName = ".DDRHeap";

    instti_sysbios_heaps_HeapMem1Params0.size = 0x300000;

    Program.global.DDR_Heap = ti_sysbios_heaps_HeapMem.create(instti_sysbios_heaps_HeapMem1Params0);

    xdc_runtime_Memory.defaultHeapInstance = Program.global.DDR_Heap;

    Program.sectMap[".DDRHeap"] = "DDR";

    Program.heap = 0x300000;

    xdc_runtime_Memory.defaultHeapSize = 0x300000;

    /*core1.cfg*/

     

    Please take a look at the MessageQ example.  We do a HeapBufMP_create() from one core and we do a HeapBufMP_open from another core.  If you want to use it on multiple tasks on the same core, just do another HeapBufMP_open from that task.

    Judah

  • Edward,

    Going back to your original posts.  What you are doing here looks correct to me?

    Are you then calling MessageQ_alloc(0, sizeofMessage);?  This would allocate from the HeapBufMP and not the local heap.

    Could it be that you are registering the local heap with MessageQ also?

      do {

          status = HeapBufMP_open("MQHeap", &heap_handle);

       } while (status < 0);

       // register the heap with message queue

       MessageQ_registerHeap((IHeap_Handle)heap_handle, 0);

    Judah

  • it turns out caching was our problem.  Our program was running out of LL2, but also has 256k set aside for L2 cache.  So certain DDR accesses would cache over the top of our program memory and cause a lot of strange problems.  We didn't previously see this problem, because we weren't using the DDR heap yet so there weren't any L2 cache accesses.

     

    This brings up another question.  Is there an easy way to partition sections of DDR for each core's program/data memory?  I can set code/data/stack to DDR in our platform file, but then each core will try to use the same piece of DDR.

     

     

  • Kevin,

    In not familar with being able to do this at runtime, although it might be possible with load/run constructs for the linker command file.

    Statically, I think you have 2 options. 

    #1.  You build different exectuables for different cores and in each *.cfg file you specify which core you are building for and use a portion of DDR.

    #2.  If you want your *.cfg to be the same then you need to create different platforms for each core.

    This is another way of saying, I don't think you can build a single executable to make this happen.

    Judah