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.

Memory allocation/deallocation

I'm using: DSP/BIOS 5.31.02, Code Composer Studio 3.3, and Code Generation Tools v6.1.7, C6416 in big endian mode.

I'm having issues with memory allocation/deallocation.  Over time, a time-critical section of my code goes from very quick and consistent (300us overall, very fixed amount of time to execute 'delete' on the objects during this time) to much slower and inconsistent (over 1ms, with just the calls to 'delete' taking an order of magnitude longer or more) while executing the exact same code.  It seems like the heap is becoming fragmented and/or filled with many small objects, causing the processes of freeing the memory back to take a longer, more inconsistent amount of time.  I'm trying to find out how memory allocation works when using new/delete with DSP/BIOS.

At first I thought all I needed to do was modify the run-time support (RTS) library, as my *.tcf generated *.cmd file is including rts6400e.lib.  So I figured out how to rebuild the RTS library (rts6400e.lib) and modified malloc()/free() in memory.c.  However, none of my changes are taking affect.  After some investigating done in my previously posted thead, it looks like the linker is using the malloc()/free() routines found in the bios.a64e library that a DSP/BIOS project wants to use.  How do I either: A) force the linker to use the versions of malloc()/free() found in the RTS library or B) modify the malloc()/free() routines found in the bios.a64e library or C) provided an over-rided version of malloc()/free() as part of a source file added to the project?

Thanks!

  • Hi Mark,

    Are you calling the new/delete or MEM_alloc/MEM_free from a SWI or HWI? See:

    http://processors.wiki.ti.com/index.php/DSP_BIOS_FAQ#Q:_Can_runtime_support_.28RTS.29_functions_be_called_when_using_DSP.2FBIOS.3F

    http://processors.wiki.ti.com/index.php/DSP_BIOS_FAQ#Q:_Why_users_are_not_allowed_to_call_MEM_functions_.28MEM_alloc.2C_MEM_stat_etc.29_from_an_HWI_or_SWI.3F

    Please alse see page 279 of document:

    http://www-s.ti.com/sc/techlit/spru403

    Mark Jansen said:
    Over time, a time-critical section of my code goes from very quick and consistent (300us overall, very fixed amount of time to execute 'delete' on the objects during this time) to much slower and inconsistent (over 1ms, with just the calls to 'delete' taking an order of magnitude longer or more) while executing the exact same code.  It seems like the heap is becoming fragmented and/or filled with many small objects, causing the processes of freeing the memory back to take a longer, more inconsistent amount of time.  I'm trying to find out how memory allocation works when using new/delete with DSP/BIOS.

    This should not be a fragmentation issue, because MEM_alloc will return you a contiguous memory segment. The issue you are experiencing might not be related to fragmentation at all, do you agree?

    Please see:

    http://e2e.ti.com/support/embedded/f/355/p/48587/171957.aspx#171957

  • I am not calling new/delete from a SWI or HWI.  I am not explicitly calling MEM_alloc/MEM_free from anywhere.

    I believe the issue is fragmentation.  I am not simply new-ing or MEM_alloc-ing a single memory block.  I am new-ing/delete-ing many objects.  Currently, during my time-critical section, delete is called about 140 times.  The duration of delete is initially small and consistent, but eventually grows and becomes much more variable.  When this starts occuring, I traverse the free-list and count the number of entries in it, which represent how fragmented the free memory blocks are.  I get over 600 entries in the free list.  I'm currently in the process of counting the total number of memory blocks, both allocated and unallocated.

    Without access to the malloc()/free() routines used by the bios.a64 library, I am unable to directly determine the algorithms used and provide a new one to be used.

  • Hi Mark,

    I see your point, and I agree with you.

    Please see chapter 5 (specially 5.1.7) of the:

    http://www-s.ti.com/sc/techlit/spru303

    Can you try making different memory segments?

    So DSP/BIOS is not open source, and like stated in this page I would not advise to use the new/delete directly from the RTS:

    "For instance, the new and delete operators are implemented with MEM_alloc and MEM_free in order to support reentrancy."

    If you wanted to try to use RTS directly (again, do not recommend), you could probably include the C source that contains the malloc function into your project directly. 

  • The recommendation provided by spru303 section 5.1.7 is not feasible for this program.  Portions of the code base is common across different platforms that are expecting calls to new/delete to allocate and deallocate memory.

    Does the RTS library not prevent reentrancy via the _lock()/_unlock() calls?

    Also, including the RTS memory.c directly into the project does not work as-is.  In particular, this section of code:

    /*---------------------------------------------------------------------------*/
    /* _SYSMEM_SIZE is a symbol whose *address* is set by the linker to the      */
    /* size of the heap, via the -heap flag.                                     */
    /*---------------------------------------------------------------------------*/
    extern _DATA_ACCESS int _SYSMEM_SIZE;              /* address = size of heap */
     
    /*---------------------------------------------------------------------------*/
    /* Size of the heap area as defined by the linker.                           */
    /*---------------------------------------------------------------------------*/
    static _DATA_ACCESS int _memory_size = (int)&_SYSMEM_SIZE;
     
    /*---------------------------------------------------------------------------*/
    /* Define the heap memory area.  Note that allocated space is actually       */
    /* (re)allocated in the linker.  The object must appear in the ".sysmem"     */
    /* data section, and it must be aligned properly.                            */
    /*---------------------------------------------------------------------------*/
    /* Autoinitialize the first packet to indicate a single heap packet whose    */
    /* size is equal to the total heap minus the size of the header (a PACKET).  */
    /* This is equivalent to calling minit() at boot time.                       */
    /*---------------------------------------------------------------------------*/
    #pragma DATA_SECTION(_sys_memory, ".sysmem")
    #pragma DATA_ALIGN(_sys_memory, 8)
    far PACKET _sys_memory[1] = { ((size_t)&_SYSMEM_SIZE) - sizeof(PACKET), 0 };
     
    #define heap_mem ((char *)_sys_memory)

    The method in which the memory segment to be used is acquired does not play well if this file is simply included into the project, and I'm not sure how to work around it.