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.

TMS320C6678: Memory Leak Detection Generic Question

Part Number: TMS320C6678
Other Parts Discussed in Thread: SYSBIOS

Hello,

I am working with a version of a TI library (IPC) that has a known memory leak. I built a new version of the library using a newer IPC which claims to have

patched the memory leak along with a newer version of SYS/BIOS which also claims to have fixed a double mfence() issue.

My colleges are hesitant to change over to this new library I generated and insist upon seeing the memory leak manifest itself in currently released firmware

which uses the old IPC library with the known memory leak.

I am not sure how to test for this.

I see threads here in the e2e forum which link to dead pages.

Is there any available information on using CCS and or the Debugger to search for memory leaks?

Thanks,

Forrest

  • Hi Forrest,

      Please refer the  following link https://www.ti.com/lit/ug/spruex3v/spruex3v.pdf under "7.8 Heap Implementation" using "Heap Track: memory leak can be detected.

    Is there any available information on using CCS and or the Debugger to search for memory leaks?

    Yes, Using onboard debugger we can debug the code. In CCS, use debug window (view -> debug) and set break points (Debug -> Breakpoints) and also use Variable and Expression window (View -> Variable and View -> Expression). 

    Thanks,

    Rajarajan U

  • Hello Rajarajan,

    Thank you for the response. I have read the reference you provided a link to above. There is only a single page specific to the Heap Track class.

    The example code does not compile. I fixed some of the errors however I am confused on one particular error.

    Below is my code:

    // Existing Heap:

        HeapBufMP_Handle  heapHandle;
        HeapBufMP_Params  heapBufParams;

    // FJD. Adding Heap Track to existing above heap:
        HeapTrack_Params prms;
        HeapTrack_Handle hHeapTracker;
        Error_Block eb;

       /*
         *===== Create the heap that will be used to allocate messages =====
         */

        HeapBufMP_Params_init(&heapBufParams);
        heapBufParams.regionId       = 0;
        heapBufParams.name           = BACKEND_HEAP_NAME;
        heapBufParams.numBlocks      = NUMBER_IPC_BACKEND_BUFFERS;  // Number of backend message buffers.
        heapBufParams.blockSize      = MAX_IPC_PAYLOAD_LEN;
        heapHandle = HeapBufMP_create(&heapBufParams);
        if (heapHandle == NULL)
        {   // TODO: Add error handing here.
            System_abort("HeapBufMP_create failed\n" );
        }
        // FJD. Attach the heap tracker to the existing heap for memory leak testing purposes:
        // Create Heap Tracker:
        // HeapTrack_Handle HeapTrack_create(const HeapTrack_Params *params, Error_Block *eb);
        hHeapTracker= HeapTrack_create(& prms, &eb);
        // Validate Heap Tracker:
        if (hHeapTracker == NULL) {
            System_abort("HeapTrack create failed");
            // TODO: Handle Error and fall back up the call chain.
        }
        // Attach Heap Tracker to Existing Heap:
        // TODO: ???
        prms.heap = heapHandle;

    The above highlighted line throws an incompatibility error:
    #515 a value of type "HeapBufMP_Handle" cannot be assigned to an entity of type "xdc_runtime_IHeap_Handle" 

    So, what is to correct method of attaching the heap tracker to the pre-existing heap?

    I have reviewed the sparse materials on the subject and do not see an clear explanation of how this is done.

    Please Advise,

    Forrest

  • Forrest,

    Customer Says" I built a new version of the library using a newer IPC which claims to have

    patched the memory leak along with a newer version of SYS/BIOS which also claims to have fixed a double mfence() issue......

    I am not sure how to test for this."

    You can test your new version of library using the newer IPC by following the steps given below.

    For example, 

    If you use the IPC version, ipc_3_50_04_08, try using the immediate previous version, i.e., ipc_3_50_04_07 and check whether the same memory leak exist.  Because, sometimes, while fixing the bugs in the latest release, may in-turn introduce newer bugs...

    Or, if you want to switch from the lower version of IPC to higher version... etc

    Changing the IPC versions can be easily done with the steps below:

    1. Go to project properties

    2. Click general-->products

    3. Disable/Uncheck the ipc_3_50_04_08 and Enable/check the ipc_3_50_04_07 package.

    --

    Customer says"I see threads here in the e2e forum which link to dead pages."

    Post the dead links here. I will be able to provide you the right links.

     

    Regards

    Shankari G

  • Hello Shankari,

    Thanks for your response.

    I do not need help rebuilding the IPC library or selecting a different version of the IPC library in the CCS environment. These things are trivial.

    My question is simply how do I properly attach the Heap track to an existing heap.

    Please see my question above and respond to that specific issue.

    Thank You,

    Forrest

  • Forrest,

    In the configuration file, "*.cfg" in your project, please include the module to be used. And not in the ".c" file.

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

    After attaching the module in the cfg, you will be able to use the corresponding API of those modules in the *.c file.

    ---

    For example:-

    sample .cfg file:- 

    var HeapBufMP    = xdc.useModule('ti.sdo.ipc.heaps.HeapBufMP');

    Sample .c file

        /* Create the heap that will be used to allocate messages. */
        HeapBufMP_Params_init(&heapBufParams);
        heapBufParams.regionId       = 0;
        heapBufParams.name           = IMAGE_PROCESSING_HEAP_NAME;
        heapBufParams.numBlocks      = number_of_cores;
        heapBufParams.blockSize      = sizeof(process_message_t);
        heapHandle = HeapBufMP_create(&heapBufParams);
        if (heapHandle == NULL) {
            platform_write("Main: HeapBufMP_create failed\n" );
            goto close_n_exit;
        }

    Regards

    Shankari

  • Hi Shankari,

    I am rather confused by your answer.

    Initially I did try modifying the projects config file to attach to the Sys/BIos Heap by inserting the lines recommended by the Sys/Bios

    users manual:

    // 10/22/2021 FJD Enabling BIOS Heap tracking for memory leak testing:
    var BIOS = xdc.useModule('ti.sysbios.BIOS');
    BIOS.heapTrackEnabled = true;

    This produces the following warning during compilation of the project:

    WARNING: Can't call useModule('ti.sysbios.knl.Queue') after all packages are closed (phase 4 or above)

    Adding the var for the HeapBuff to the config file does not work either.

    I do not see in the sample .c file you listed above where the HeapTracker is attached to the pre-existing heap.

    Please advise,

    Forrest

  • Forrest,

    My apologize, if my answers confuses you. I have just given a reference example to module, HeapBufMP. So that, you can use the HeapTrack module similarly.

    Actually, What I meant was, 

    In the post above, in the sample cfg and sample .c, you will get to know

    1. how to attach the module of "HeapBufMP" and 

    2. how to use the API of HeapBufMP module.

    ------------

    Similarly, you can attach the module, "HeapTrack" in the *.cfg and make use of API of "HeapTrack" module in the .c file.

    1. In *.cfg to attach the module, "HeapTrack"

    var HeapTrack = xdc.useModule('ti.sysbios.heaps.HeapTrack');
    var heapTrackParams = new HeapTrack.Params();
    heapTrackParams.heap = heapHandle;
    Program.global.myHeap = HeapTrack.create(heapTrackParams);

    2. In *.c, try using the API, 

    HeapTrack_Params prms;
    HeapTrack_Handle heap;
    Error_Block eb;
    Error_init(&eb);
    HeapTrack_Params_init(&prms);
    prms.heap = heapHandle;
    heap = HeapTrack_create(&prms, &eb);
    if (heap == NULL) {
     System_abort("HeapTrack create failed");
    }

    IMPORTANT:- Please do check the availability of API according to the version of SYS/BIOS, you use....

    To check the API in your SYS/BIOS version, Please go to loaction : -- C:/ti/bios_6_76_03_01/docs/cdoc/index.html -- > Expand-->ti-->sysbios-->heaps-->Heaptrack --> List of APIs -- ( SYS/BIOS API Documentation )

    Hope this helps.

    Regards

    Shankari G

  • Hello Shankari,

    Thank you for the additional details. I did not know how to look up the heaps API. I was going on the release notes for the different revisions of the SYS/BIOS library. Yes, the version I am using does contain the Heap Tracker class as you have shown above.

    I have tried several variations of what I think you and the SYS/BIOS guide are saying and none of them compile.

    Placing the code only in the config file does not compile.

    Placing the code only in the source code does not compile.

    Using combinations of both does not compile.

    Is there an actual functional example that you can share?

    Thank You,

    Forrest

  • Forrest,

    Customer says " I did not know how to look up the heaps API. I was going on the release notes for the different revisions of the SYS/BIOS library. Yes, the version I am using does contain the Heap Tracker class as you have shown above. "

    Ok, I understand.

    Please let me know, the SYS/BIOS library version, you use. let me search for you on the heap track or the available API details.

    To know the sysbios version--> Go to project properties-->General-->products-->SYS/BIOS version

    Regards

    Shankari G

  • Hello Shankari,

    I do not think you understood my last message so let try and explain it in more detail.

    I found the API reference in the cdoc folder and was thanking you for showing me that feature.

    The revision of the SYS/BIOS I am using is 6.34.4.22 and as I stated above it does support the Heap track class.

    I am simply looking for a way to attach the heap tracker to an existing heap stack.

    The example in the SYS/BIOS users guide has errors. I corrected some of them however I still have one remaining error and wish to resolve it so that I can test my code.

    Thank You,

    Forrest.

    By the way, you have marked this issue as"Resolved." That should not be so.

  • Forrest,

    Ok, then, let me try to implement that "Heap tracker" API in any of the working example of SYS/BIOS project.

    and let me check whether, attaching the existing heap handle to the " prms.heap = heapHandle of Heap Tracker " is working or not.

    I will get back to you soon.

    Regards

    Shankari G

  • Forrest,

    To implement the HeapTracker, I have taken the working example, "transportSrioBenchmarkC6657C66ExampleProject".

    I hope, am able to attach the existing heap handle to the prms.heap of Heap tracker and able to build successfully without errors.

     I have tested and checked in the "debug - Expression window of CCS", whether the value of the existing heap-handle gets reflected in the prms.heap.

    Attached the source file too for your reference. ---- 

    bench_srio.c
    /**
     * @file  bench_srio.c
     *
     * @brief   
     *    Example application that uses the SRIO IPC transport to send
     *    MessageQ messages between two DSP cores.  Latency and
     *    throughput statistics are collected for the transmitted
     *    messages.
     *
     * Copyright (c) 2011-2015, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    #include <xdc/std.h>
    #include <xdc/cfg/global.h>
    
    /* XDC include */
    #include <xdc/runtime/System.h>
    #include <xdc/runtime/IHeap.h>
    #include <xdc/runtime/Timestamp.h>
    #include <xdc/runtime/Error.h>
    //shankari
    #include <xdc/runtime/Memory.h>
    //shankari
    
    /* BIOS6 include */
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Task.h>
    
    //shankari
    #include <ti/sysbios/heaps/HeapTrack.h>
    //shankari
    
    
    /* IPC include */
    #include <ti/ipc/Ipc.h>
    #include <ti/ipc/MultiProc.h>
    #include <ti/ipc/MessageQ.h>
    #include <ti/ipc/GateMP.h>
    #include <ti/ipc/HeapBufMP.h>
    #include <ti/ipc/SharedRegion.h>
    
    
    /* CSL include */
    #include <ti/csl/csl_cacheAux.h>
    #include <ti/csl/csl_psc.h>
    #include <ti/csl/csl_pscAux.h>
    #include <ti/csl/csl_chip.h>
    
    /* QMSS LLD */
    #include <ti/drv/qmss/qmss_drv.h>
    #include <ti/drv/qmss/qmss_firmware.h>
    
    /* CPPI LLD */
    #include <ti/drv/cppi/cppi_drv.h>
    
    /* SRIO LLD */
    #include <ti/drv/srio/srio_drv.h>
    
    /* RM LLD */
    #include <ti/drv/rm/rm.h>
    #include <ti/drv/rm/rm_services.h>
    
    /* Transport SRIO includes */
    #include <ti/transport/ipc/c66/srio/TransportSrio.h>
    
    #include <ti/transport/ipc/c66/example/common_src/bench_common.h>
    
    /************************ USER DEFINES ********************/
    
    #define RM_PRINT_STATS        0
    #define SYSINIT               0
    #define NUM_DSP_CORES         2
    #if (defined(DEVICE_C6657) || defined(DEVICE_C6678))
    #define NUM_CORES             2 /* 2 DSPs */
    #else
    #define NUM_CORES             3 /* Host + DSPs */
    #endif
    #define TEST_ITERATIONS_STD   3
    #define TEST_ITERATIONS_FRAG  3
    #define TEST_ITERATIONS_TOT   (TEST_ITERATIONS_STD + TEST_ITERATIONS_FRAG)
    #if defined(DEVICE_C6657)
    #define NUM_MSGS_TO_PREALLOC  8
    #else
    #define NUM_MSGS_TO_PREALLOC  64
    #endif
    
    #define HOST_DESC_SIZE_BYTES  128
    #if defined(DEVICE_C6657)
    #define HOST_DESC_NUM         128
    #define TRANS_RCV_DESC        24
    #else
    #define HOST_DESC_NUM         512
    #define TRANS_RCV_DESC        120
    #endif
    #define TRANS_SEND_DESC       4
    #define TRANS_FRAG_DESC       4
    #define HOST_DESC_MEM_REGION  0
    
    /* Number of HeapBufMP buffers to be allocated for transport instance and test
     * usage
     * T11 instance receive  --> (  TRANS_RCV_DESC
     * T9 instance receive   -->  + TRANS_RCV_DESC
     * T11 fragment buffers  -->  + TRANS_FRAG_DESC
     * T9 fragment buffers   -->  + TRANS_FRAG_DESC
     * Number of DSP cores   -->  * NUM_DSP_CORES)
     * Test buffer overheard --> + NUM_MSGS_TO_PREALLOC * 2 (snd/rcv)
     * Extra buffer space    --> + (16 should be enough) */
    #define TEST_BUF_NUM          (((TRANS_RCV_DESC + TRANS_RCV_DESC +    \
                                     TRANS_FRAG_DESC + TRANS_FRAG_DESC) * \
                                    NUM_DSP_CORES) +                      \
                                   (NUM_MSGS_TO_PREALLOC * 2) + 16)
    #define TEST_BUF_SIZE         4096
    
    #define SRIO_MTU_SIZE         4096
    /* Use smaller MTU size so that fragmentation kicks in when sending a buffer
     * of size sizeof(TstMsg) */
    #define SRIO_MTU_SIZE_FRAG    (4096-128)
    
    #define SRIO_MSGQ_HEAP_NAME   "srioIpcHeapBuf"
    #define SRIO_MSGQ_HEAP_ID     1
    
    #define SRIO_T11_TRANS_NET_ID 1
    #define SRIO_T9_TRANS_NET_ID  2
    
    
    /* Number of times to run the loop */
    #define NUMLOOPS              100
    #define NUMIGNORED            5
    #define NUM_MSGS              10
    
    #define TEST_PASS             0
    #define TEST_FAIL             1
    
    /************************ GLOBAL VARIABLES ********************/
    
    uint32_t testIterations;
    uint32_t testFailed;
    
    /* Queue parameters */
    char localQueueName[6];
    char nextQueueName[6];
    
    /* Core definitions according to IPC */
    uint16_t ipcCoreId = 0;
    uint16_t ipcPrevCoreId = 0;
    uint16_t ipcNumDspCores = 0;
    
    /* Core number according to the device (DNUM) */
    uint32_t coreNum;
    
    Task_Handle initTskHandle = NULL;
    Task_Handle testTskHandle = NULL;
    Task_Handle cleanupTskHandle = NULL;
    
    uint64_t     timeAdj = 0;
    uint64_t     timeLength = 0;
    Types_FreqHz timerFreq, cpuFreq;
    float        cpuTimerFreqRatio;
    Statistics   latencyStats;
    uint32_t     rawtimestamps[NUMLOOPS];
    uint32_t     latencies[NUMLOOPS - 1];
    
    MessageQ_Handle      localMessageQ = NULL;
    MessageQ_QueueId     nextQueueId, prevQueueId;
    GateMP_Handle        gateMpHandle;
    HeapBufMP_Handle     heapHandle;
    TransportSrio_Handle srioT11TransHandle = NULL;
    TransportSrio_Handle srioT9TransHandle = NULL;
    
    //shankari
       HeapTrack_Params prms;
       HeapTrack_Handle heap;
       Error_Block eb;
    
    //shankari
    
    /* These are the device identifiers used in the test Application */
    uint32_t DEVICE_ID1_16BIT = 0xBEEF;
    uint32_t DEVICE_ID2_16BIT = 0x4560;
    uint32_t DEVICE_ID3_16BIT = 0x1234;
    uint32_t DEVICE_ID4_16BIT = 0x5678;
    uint32_t DEVICE_ID1_8BIT  = 0xAB;
    uint32_t DEVICE_ID2_8BIT  = 0xCD;
    uint32_t DEVICE_ID3_8BIT  = 0x12;
    uint32_t DEVICE_ID4_8BIT  = 0x34;
    
    TransportSrio_srioSockParams         t11socketParams;
    TransportSrio_srioSockParams         t9socketParams;
    TransportSrio_srioSockType11EpParams t11EpParams[NUM_CORES];
    TransportSrio_srioSockType9EpParams  t9EpParams[NUM_CORES];
    
    /* Descriptors aligned and padded to cache line */
    #pragma DATA_SECTION (hostDesc, ".desc");
    #pragma DATA_ALIGN (hostDesc, 128)
    /* Total size must be multiple of cache line */
    uint8_t hostDesc[HOST_DESC_NUM * HOST_DESC_SIZE_BYTES];
    
    /* Sync indices into the syncInit array */
    #define SYNC_INDEX_SYS_INIT      0
    #define SYNC_INDEX_RM_INIT       1
    #define SYNC_INDEX_SHM_TPUT      2
    #define SYNC_INDEX_SRIO_T11_TPUT 3
    #define SYNC_INDEX_SRIO_T9_TPUT  4
    /* Sync block for initialization barriers */
    #pragma DATA_SECTION (syncInit, ".sync");
    #pragma DATA_ALIGN (syncInit, 128)
    volatile uint8_t syncInit[128];
    
    /* Sync block for cleanup barriers */
    #pragma DATA_SECTION (syncCleanup, ".sync");
    #pragma DATA_ALIGN (syncCleanup, 128)
    volatile uint8_t syncCleanup[NUM_DSP_CORES][128];
    
    /* RM instance handle */
    Rm_Handle         rmHandle = NULL;
    Rm_ServiceHandle *rmServiceHandle = NULL;
    
    /*************** EXTERN VARIABLES & FUNCTIONS *****************/
    /* QMSS device specific configuration */
    extern Qmss_GlobalConfigParams qmssGblCfgParams;
    /* CPPI device specific configuration */
    extern Cppi_GlobalConfigParams cppiGblCfgParams;
    
    /* TransportSrio device specification configuration */
    extern TransportSrio_DeviceConfigParams srioTransCfgParams;
    
    /* Global Resource List (GRL) */
    extern const char rmGlobalResourceList[];
    
    #if defined(LINUX_NO_BOOT) ||(defined(DEVICE_C6657) || defined(DEVICE_C6678))
    /* DSP only Policy provided to RM Server */
    extern const char rmDspOnlyPolicy[];
    #else
    /* ARM+DSP Policy provided to RM Server */
    extern const char rmDspPlusArmPolicy[];
    #endif
    
    /* RM instance transport code */
    extern int setupRmTransConfig(uint32_t numTestCores, uint32_t systemInitCore,
                                  Task_FuncPtr testTask);
    
    /* SRIO initialization function */
    extern int32_t SrioDevice_init(uint8_t pathMode);
    extern int32_t SrioDevice_deinit(void);
    
    /*************************** FUNCTIONS ************************/
    
    void initTsk(UArg arg0, UArg arg1);
    void proxyInitTsk(UArg arg0, UArg arg1);
    
    static void wb(void *addr, uint32_t sizeBytes)
    {
    #ifdef L2_CACHE
        /* Writeback L2 */
        CACHE_wbL2(addr, sizeBytes, CACHE_WAIT);
    #else
        /* Writeback L1D */
        CACHE_wbL1d(addr, sizeBytes, CACHE_WAIT);
    #endif
    }
    
    static void inv(void *addr, uint32_t sizeBytes)
    {
    #ifdef L2_CACHE
        /* Invalidate L2 */
        CACHE_invL2(addr, sizeBytes, CACHE_WAIT);
    #else
        CACHE_invL1d(addr, sizeBytes, CACHE_WAIT);
    #endif
    }
    
    /**
     *  @b Description
     *  @n
     *      This function enables the power/clock domains for SRIO. 
     *
     *  @retval
     *      Success     - 0
     *  @retval
     *      Error       - <0
     */
    static int32_t enableSrio(void)
    {
    #ifndef SIMULATOR_SUPPORT
        /* SRIO power domain is turned OFF by default. It needs to be turned on
         * before doing any SRIO device register access. This not required for the
         * simulator. */
    
        /* Set SRIO Power domain to ON */
        CSL_PSC_enablePowerDomain(CSL_PSC_PD_SRIO);
    
        /* Enable the clocks too for SRIO */
        CSL_PSC_setModuleNextState(CSL_PSC_LPSC_SRIO, PSC_MODSTATE_ENABLE);
    
        /* Start the state transition */
        CSL_PSC_startStateTransition(CSL_PSC_PD_SRIO);
    
        /* Wait until the state transition process is completed. */
        while (!CSL_PSC_isStateTransitionDone(CSL_PSC_PD_SRIO));
    
        /* Return SRIO PSC status */
        if ((CSL_PSC_getPowerDomainState(CSL_PSC_PD_SRIO) == PSC_PDSTATE_ON) &&
            (CSL_PSC_getModuleState(CSL_PSC_LPSC_SRIO) == PSC_MODSTATE_ENABLE)) {
            /* SRIO ON. Ready for use */
            return(0);
        } else {
            /* SRIO Power on failed. Return error */
            return(-1);
        }
    #else
        /* PSC is not supported on simulator. Return success always */
        return(0);
    #endif
    }
    
    /**
     *  @b Description
     *  @n
     *      Configures the descriptor region and initializes CPPI, QMSS, and SRIO.
     *      This function should only be called once across all DSP cores.
     *
     *  @retval
     *      Success     - 0
     *  @retval
     *      Error       - <0
     */
    int32_t systemInit(void)
    {
        Qmss_InitCfg    qmssInitConfig; /* QMSS configuration */
        Qmss_MemRegInfo memInfo; /* Memory region configuration information */
        Qmss_Result     result;
        Cppi_StartCfg   cppiStartCfg;
    
        System_printf("Core %d : L1D cache size %d. L2 cache size %d.\n", coreNum,
                      CACHE_getL1DSize(), CACHE_getL2Size());
    
        /* Start the timestamp counter */
        TSCL = 0;
    
        memset((void *) &qmssInitConfig, 0, sizeof (Qmss_InitCfg));
        /* Set up the linking RAM. Use the internal Linking RAM. LLD will configure
         * the internal linking RAM address and maximum internal linking RAM size
         * if a value of zero is specified.  Linking RAM1 is not used */
        qmssInitConfig.linkingRAM0Base = 0;
        qmssInitConfig.linkingRAM0Size = 0;
        qmssInitConfig.linkingRAM1Base = 0;
        qmssInitConfig.maxDescNum      = HOST_DESC_NUM;
    #if defined(LINUX_NO_BOOT) || (defined(DEVICE_C6657) || defined(DEVICE_C6678))
    #ifdef xdc_target__bigEndian
        qmssInitConfig.pdspFirmware[0].pdspId = Qmss_PdspId_PDSP1;
        qmssInitConfig.pdspFirmware[0].firmware = (void *) &acc48_be;
        qmssInitConfig.pdspFirmware[0].size = sizeof (acc48_be);
    #else
        qmssInitConfig.pdspFirmware[0].pdspId = Qmss_PdspId_PDSP1;
        qmssInitConfig.pdspFirmware[0].firmware = (void *) &acc48_le;
        qmssInitConfig.pdspFirmware[0].size = sizeof (acc48_le);
    #endif
    #else
        /* Download PDSP3 firmware.  PDSP1 will not be used to avoid potential
         * firmware lockup caused by usage contention with Linux */
    #ifdef xdc_target__bigEndian
        qmssInitConfig.pdspFirmware[0].pdspId = Qmss_PdspId_PDSP3;
        qmssInitConfig.pdspFirmware[0].firmware = (void *) &acc48_be;
        qmssInitConfig.pdspFirmware[0].size = sizeof (acc48_be);
    #else
        qmssInitConfig.pdspFirmware[0].pdspId = Qmss_PdspId_PDSP3;
        qmssInitConfig.pdspFirmware[0].firmware = (void *) &acc48_le;
        qmssInitConfig.pdspFirmware[0].size = sizeof (acc48_le);
    #endif
    #endif
    
        qmssGblCfgParams.qmRmServiceHandle = rmServiceHandle;
    #if (!defined(LINUX_NO_BOOT)) && (!defined(DEVICE_C6657) && !defined(DEVICE_C6678))
        /* Bypass hardware initialization as it is done within Kernel */
        qmssInitConfig.qmssHwStatus = QMSS_HW_INIT_COMPLETE;
    #endif
    
        /* Initialize Queue Manager SubSystem */
        result = Qmss_init(&qmssInitConfig, &qmssGblCfgParams);
        if (result != QMSS_SOK) {
            System_printf("Error Core %d : "
                          "Initializing Queue Manager SubSystem error code : %d\n",
                          coreNum, result);
            return(-1);
        }
    
        /* Start the QMSS. */
        if (Qmss_start() != QMSS_SOK) {
            System_printf("Error Core %d : Unable to start the QMSS\n", coreNum);
            return(-1);
        }
    
        result = Cppi_init(&cppiGblCfgParams);
        if (result != CPPI_SOK) {
            System_printf("Error Core %d : "
                          "Initializing CPPI LLD error code : %d\n", coreNum,
                          result);
        }
    
        /* Register RM with CPPI */
        cppiStartCfg.rmServiceHandle = rmServiceHandle;
        Cppi_startCfg(&cppiStartCfg);
    
        /* Setup memory region for host descriptors */
        memset((void *) &hostDesc, 0, HOST_DESC_NUM * HOST_DESC_SIZE_BYTES);
        memset((void *) &memInfo, 0, sizeof(memInfo));
        memInfo.descBase       = (uint32_t *) hostDesc;
        memInfo.descSize       = HOST_DESC_SIZE_BYTES;
        memInfo.descNum        = HOST_DESC_NUM;
        memInfo.manageDescFlag = Qmss_ManageDesc_MANAGE_DESCRIPTOR;
        memInfo.memRegion      = (Qmss_MemRegion) HOST_DESC_MEM_REGION;
        result = Qmss_insertMemoryRegion(&memInfo);
        if (result < QMSS_SOK) {
            System_printf("Error Core %d : "
                          "Inserting memory region, error code : %d\n", coreNum,
                          result);
            return(-1);
        } else {
            System_printf("Core %d : Memory region %d inserted\n", coreNum,
                          HOST_DESC_MEM_REGION);
        }
    
        /* Writeback the descriptor pool. */
        wb((void *)hostDesc, HOST_DESC_NUM * HOST_DESC_SIZE_BYTES);
    
        return(0);
    }
    
    /**
     *  @b Description
     *  @n
     *      Deletes descriptor region and shuts down CPPI, QMSS, and SRIO.
     *      This function should only be called once across all DSP cores.
     *
     *  @retval
     *      Success     - 0
     *  @retval
     *      Error       - <0
     */
    int32_t systemDeInit(void)
    {
        Qmss_Result qmssResult;
        Cppi_Result cppiResult;
    
        /* Remove the memory region. */
        qmssResult = Qmss_removeMemoryRegion(HOST_DESC_MEM_REGION, 0);
        if (qmssResult < QMSS_SOK) {
            System_printf("Error Core %d : Removing memory region: %d\n", coreNum,
                          qmssResult);
            return(-1);
        }
    
        /* De Initialize CPPI CPDMA */
        cppiResult = Cppi_exit();
        if (cppiResult != CPPI_SOK) {
            System_printf("Error Core %d : Deinitializing CPPI error code : %d\n",
                          coreNum, cppiResult);
            return(-1);
        }
    
        return(0);
    }
    
    /**
     *  @b Description
     *  @n
     *      This functions prints the statistics gathered for the transport during
     *      the latency test.
     */
    void printLatencyStats(void)
    {
        uint32_t timeElapsed;
        uint32_t i;
    
        /* Convert timestamps to CPU time */
        for (i = 0; i < NUMLOOPS; i++) {
            rawtimestamps[i] *= cpuTimerFreqRatio;
        }
    
        for (i = 0; i < NUMLOOPS - 1; i++) {
            latencies[i] = (rawtimestamps[i + 1] - rawtimestamps[i]) /
                           ipcNumDspCores;
        }
    
        getStats(latencies + NUMIGNORED, NUMLOOPS - NUMIGNORED - 2, &latencyStats);
    
        timeElapsed = rawtimestamps[NUMLOOPS - NUMIGNORED - 2] -
                      rawtimestamps[NUMIGNORED];
        /* Throughput = time elapsed divided by total #of of hops */
        
        System_printf("Core %d : "
                      "=============== LATENCY RESULTS =============\n", coreNum);
        System_printf("Core %d : Number of messages received:  %8d\n", coreNum,
                      latencyStats.numVals);
        System_printf("Core %d : "
                      "Average 1-way latency:        %8d (cycles/msg) %6d (ns/msg)"
                      "\n", coreNum, (uint32_t)latencyStats.mean,
                      CYCLES_TO_NS(latencyStats.mean, cpuFreq.lo));
        System_printf("Core %d : "
                      "Maximum 1-way latency:        %8d (cycles/msg) %6d (ns/msg)"
                      "\n", coreNum, latencyStats.max,
                      CYCLES_TO_NS(latencyStats.max, cpuFreq.lo));
        System_printf("Core %d : "
                      "Minimum 1-way latency:        %8d (cycles/msg) %6d (ns/msg)"
                      "\n", 
                      coreNum, latencyStats.min, CYCLES_TO_NS(latencyStats.min,
                      cpuFreq.lo)); 
        System_printf("Core %d : Standard deviation:           %8d (cycles/msg)\n",
                      coreNum, (uint32_t)latencyStats.stddev);
        System_printf("Core %d : "
                      "Total time elapsed:           %8d (cycles)     %6d (us)\n",
                      coreNum, timeElapsed, CYCLES_TO_US(timeElapsed, cpuFreq.lo));
    }
    
    /**
     *  @b Description
     *  @n
     *      This functions measures latency by sending a message from core0 to
     *      core1.  Core1 relays all received messages back to core 2.  Core0 will
     *      measure the roundtrip latency.
     */
    static uint32_t testLatency(MessageQ_Priority msgPriority, uint16_t transId)
    {
        int32_t      status;
        uint32_t     numReceived;
        MessageQ_Msg msg;
    
        if (coreNum == SYSINIT) {
            msg = MessageQ_alloc(SRIO_MSGQ_HEAP_ID, sizeof(TstMsg));
            if (msg == NULL) {
                System_printf("Error Core %d : MessageQ_alloc failed\n", coreNum);
                return(TEST_FAIL);
            }
    
            MessageQ_setTransportId(msg, transId);
            /* Priority is ignored if transport ID is set to a value between 1
             * and 7 */
            MessageQ_setMsgPri(msg, msgPriority);
    
            System_printf("Core %d : "
                          "IPC Core ID=%d calling MessageQ_put(nextQueueName=%s). "
                          "msg=0x%x\n",
                          coreNum, ipcCoreId, nextQueueName, msg);
            /* Kick off the loop */
            status = MessageQ_put(nextQueueId, msg);
            if (status < 0) {
                System_printf("Error Core %d : MessageQ_put failed\n", coreNum);
                return(TEST_FAIL);
            }
        }
    
        for (numReceived = 0; numReceived < NUMLOOPS; numReceived++) {
            status = MessageQ_get(localMessageQ, &msg, MessageQ_FOREVER);
            if (status < 0) {
                System_printf("Error Core %d : MessageQ_get failed\n", coreNum);
                return (TEST_FAIL);
            }
    
            if (coreNum == SYSINIT) {
                rawtimestamps[numReceived] = Timestamp_get32();
    
                if (numReceived == NUMLOOPS - 1) {
                    printLatencyStats();
                    MessageQ_free(msg);
                    break;
                }
            }
    
            status = MessageQ_put(nextQueueId, msg);
            if (status < 0) {
                System_printf("Error Core %d : MessageQ_put failed\n", coreNum);
                return (TEST_FAIL);
            }
        }
    
        return(TEST_PASS);
    }
    
    /**
     *  @b Description
     *  @n
     *      This functions allocate all messages to be sent up front on core0.
     *      Synchronize core 0 and core1.  Core 0 sends all messages to Core1
     *      in a burst.  Core 1 receives all the messages and measure the
     *      throughput over the time it took to send all the messages.
     */
    static uint32_t testTputAndDataIntegrity(MessageQ_Priority msgPriority,
                                             uint16_t transId)
    {
        uint32_t  i, j;
        TstMsg   *msg;
    
        if (coreNum == SYSINIT) {
            /* Last entry must be CORE_SYNC_NULL_CORE */
            int16_t   remoteCores[2] = {1, CORE_SYNC_NULL_CORE};
            TstMsg   *rxMsgPtrs[NUM_MSGS_TO_PREALLOC];
            TstMsg   *syncMsg = NULL;
            uint32_t  numReceived = 0;
            uint32_t  delay = 0;
            int32_t   status;
            uint64_t  timeStamp;
    
            System_printf("Core %d : Per message work delay is %dus\n", coreNum,
                          delay);
    
            /* Synchronize cores prior to starting test */
            syncReceiveCore(&remoteCores[0], localMessageQ, &nextQueueId,
                            msgPriority, transId);
    
            timeStamp = getStartTime64();
            numReceived = receiveMessages(&remoteCores[0], localMessageQ,
                                          &rxMsgPtrs[0], delay);
            timeLength = getExecutionTime64(timeStamp, timeAdj);
    
            if (numReceived != NUM_MSGS_TO_PREALLOC) {
                System_printf("Error Core %d : "
                              "Expected %d msgs but only received %d\n", coreNum,
                              NUM_MSGS_TO_PREALLOC, numReceived);
                return(TEST_FAIL);
            } else {
                System_printf("Core %d : Received a total of %d messages.\n",
                              coreNum, numReceived);
            }
    
            /* Check integrity of data in received messages */
            System_printf("Core %d : "
                          "Checking integrity of data in received messages...",
                          coreNum);
            for (i = 0; i < NUM_MSGS_TO_PREALLOC; i++) {
                msg = rxMsgPtrs[i];
                for (j = 0; j < TEST_MSG_DATA_LEN_WORDS; j++) {
                    uint32_t integrityMask = ((i << 16) | j);
    
                    if (msg->data[j] != integrityMask) {
                        System_printf("FAILED\n");
                        System_printf("Error Core %d : "
                                      "Data mismatch in receive message %d\n",
                                      coreNum, i);
                        return(TEST_FAIL);
                    }
                }
            }
            System_printf("PASSED\n");
            calculateThroughput(numReceived, timeLength, cpuFreq);
    
            status = freeMessages(numReceived, &rxMsgPtrs[0]);
            if (status < 0) {
                System_printf("Error Core %d : Message free failed\n", coreNum);
                return (TEST_FAIL);
            }
    
            /* Tell sender all messages have been received */
            syncMsg = (TstMsg *) MessageQ_alloc(SRIO_MSGQ_HEAP_ID, sizeof(TstMsg));
            if (syncMsg == NULL) {
                System_printf("Error Core %d : Failed to allocate sync msg\n",
                              coreNum);
                return(TEST_FAIL);
            }
            
            syncSendCore(&remoteCores[0], localMessageQ, &nextQueueId, &syncMsg,
                         BENCH_TRUE, msgPriority, transId);
        } else {
            /* Last entry must be CORE_SYNC_NULL_CORE */
            int16_t   remoteCores[2] = {0, CORE_SYNC_NULL_CORE};
            TstMsg   *syncMsg = NULL;
            uint32_t  numTxMsgs = NUM_MSGS_TO_PREALLOC;
            TstMsg   *txMsgPtrs[NUM_MSGS_TO_PREALLOC];
            int32_t   status;
            uint32_t  numSends = 0;
    
            syncMsg = (TstMsg *) MessageQ_alloc(SRIO_MSGQ_HEAP_ID, sizeof(TstMsg));
            if (syncMsg == NULL) {
                System_printf("Error Core %d : Failed to allocate sync msg\n",
                              coreNum);
                return(TEST_FAIL);
            }
            status = allocateMessages(NUM_MSGS_TO_PREALLOC, SRIO_MSGQ_HEAP_ID,
                                      &txMsgPtrs[0]);
            if (status != 0) {
                System_printf("Error Core %d : "
                              "Failed to preallocate msgs after allocating %d "
                              "messages.\n", coreNum, status);
                return(TEST_FAIL);
            }
    
            /* Populate msg's data with pattern for integrity check */
            for (i = 0; i < NUM_MSGS_TO_PREALLOC; i++) {
                msg = txMsgPtrs[i];
                for (j = 0; j < TEST_MSG_DATA_LEN_WORDS; j++) {
                    msg->data[j] = ((i << 16) | j);
                }
            }
    
            syncSendCore(&remoteCores[0], localMessageQ, &nextQueueId, &syncMsg,
                         BENCH_TRUE, msgPriority, transId);
    
            /* Send all messages to remote core.  The last message sent will have a
             * flag signifying to remote core that all messages have been sent. */
            numSends = sendMessages(1, &numTxMsgs, &nextQueueId, &txMsgPtrs[0],
                                    msgPriority, transId);
            System_printf("Core %d : Sent a total of %d messages.\n", coreNum,
                          numSends);
    
            syncReceiveCore(&remoteCores[0], localMessageQ, &nextQueueId,
                            msgPriority, transId);
        }
    
        return(TEST_PASS);
    }
    
    /**
     *  @b Description
     *  @n
     *      Cleanup task used to reset application to pre-initTsk state
     */
    void cleanupTsk(UArg arg0, UArg arg1)
    {
        Task_Params taskParams;
        Int         status;
        Qmss_Result qmssResult;
        int32_t     rmResult;
        int32_t     i;
        
        System_printf("Core %d : "
                      "================== CLEANUP ==================\n", coreNum);
    
        if (initTskHandle) {
            Task_delete(&initTskHandle);
            initTskHandle = NULL;
        }
    
        if (testTskHandle) {
            Task_delete(&testTskHandle);
            testTskHandle = NULL;
        }
    
        System_printf("Core %d : Closing remote MessageQ\n", coreNum);
        status = MessageQ_close(&nextQueueId);
        if (status != MessageQ_S_SUCCESS) {
            testFailed = BENCH_TRUE;
            System_printf ("Error Core %d : MessageQ_close\n", coreNum);
            goto cleanup_error;
        }
        System_printf("Core %d : Deleting local MessageQ\n", coreNum);
        status = MessageQ_delete(&localMessageQ);
        if (status != MessageQ_S_SUCCESS) {
            testFailed = BENCH_TRUE;
            System_printf ("Error Core %d : MessageQ_delete\n", coreNum);
            goto cleanup_error;
        }
    
        System_printf("Core %d : Deleting SRIO Type 11 IPC transport\n", coreNum);
        TransportSrio_delete(&srioT11TransHandle);
        srioT11TransHandle = NULL;
    
        System_printf("Core %d : Deleting SRIO Type 9 IPC transport\n", coreNum);
        TransportSrio_delete(&srioT9TransHandle);
        srioT9TransHandle = NULL;
    
        System_printf("Core %d : Unregistering MessageQ heap\n", coreNum);
        status = MessageQ_unregisterHeap(SRIO_MSGQ_HEAP_ID);
        if (status != MessageQ_S_SUCCESS) {
            testFailed = BENCH_TRUE;
            System_printf ("Error Core %d : MessageQ_unregisterHeap\n", coreNum);
            goto cleanup_error;
        }
    
        if (coreNum == SYSINIT) {
            /* Wait for other cores to complete cleanup */
            for (i = 0; i < NUM_DSP_CORES; i++) {
                if (i != coreNum) {
                    do {
                        inv((void *) &syncCleanup[i][0], sizeof(syncCleanup) /
                            NUM_DSP_CORES);
                    } while (!syncCleanup[i][0]);
                }
            }
    
            System_printf("Core %d : Closing HeapBufMP\n", coreNum);
            status = HeapBufMP_close(&heapHandle);
            if (status != HeapBufMP_S_SUCCESS) {
                testFailed = BENCH_TRUE;
                System_printf("Error Core %d : HeapBufMP_close\n", coreNum);
                goto cleanup_error;
            }
    
            System_printf("Core %d : Deleting GateMP used by HeapBufMP\n", coreNum);
            status = GateMP_delete(&gateMpHandle);
            if (status != GateMP_S_SUCCESS) {
                testFailed = BENCH_TRUE;
                System_printf("Error Core %d : GateMP_close\n", coreNum);
                goto cleanup_error;
            }
    
            System_printf("Core %d : Closing SRIO\n", coreNum);
            if (Srio_close() < 0) {
                testFailed = BENCH_TRUE;
                System_printf("Error Core %d : Srio_close() Failed\n", coreNum);
                goto cleanup_error;
            }
    
            System_printf("Core %d : De-initializing QMSS and CPPI\n", coreNum);
            status = systemDeInit();
            if (status < 0) {
                testFailed = BENCH_TRUE;
                goto cleanup_error;
            }
    
            if (SrioDevice_deinit() < 0) {
                testFailed = BENCH_TRUE;
                System_printf("Error Core %d : SrioDevice_deinit() Failed\n",
                              coreNum);
                goto cleanup_error;
            }
    
            /* Exit qmss */
            System_printf ("Core %d : exit QMSS\n", coreNum);
            if ((qmssResult = Qmss_exit ())) {
                testFailed = BENCH_TRUE;
                System_printf("Error Core %d : exit error code : %d\n", coreNum,
                              qmssResult);
                goto cleanup_error;
            }
        } else {
            System_printf("Core %d : Closing HeapBufMP\n", coreNum);
            status = HeapBufMP_close(&heapHandle);
            if (status != HeapBufMP_S_SUCCESS) {
                testFailed = BENCH_TRUE;
                System_printf("Error Core %d : HeapBufMP_close\n", coreNum);
                goto cleanup_error;
            }
        }
    
    cleanup_error:
    
        if (coreNum == SYSINIT) {
            if ((rmResult = Rm_resourceStatus(rmHandle, FALSE)) != 0) {
                System_printf("Error Core %d : Number of unfreed resources : %d\n",
                              coreNum, rmResult);
                /* Print them */
                Rm_resourceStatus (rmHandle, TRUE);
                testFailed = BENCH_TRUE;
            } else {
                System_printf("Core %d : All resources freed successfully\n",
                              coreNum);
            }
        }
    
        /* SYSINIT cannot cleanup until all other cores have completed cleanup */
        if (coreNum != SYSINIT) {
            syncCleanup[coreNum][0] = 1;
            wb((void *) &syncCleanup[coreNum][0], sizeof(syncCleanup) /
                                                         NUM_DSP_CORES);
        }
    
        System_printf("Core %d : *********************************************\n",
                      coreNum);
        System_printf("Core %d : Completed Test Iteration: %d - ", coreNum,
                      testIterations);
        if (testFailed) {
            System_printf("FAILED\n");
            System_printf("Core %d : Cleaning up and exiting...\n", coreNum);
        } else {
            System_printf("PASSED\n");
        }
        System_printf("Core %d : *********************************************\n",
                      coreNum);
    
        testIterations++;
        if ((!testFailed) && (testIterations < TEST_ITERATIONS_TOT)) {
            /* Secondary DSPs must wait for SYSINIT DSP to complete cleanup if test
             * is starting another iteration */
            if (coreNum == SYSINIT) {
                syncCleanup[coreNum][0] = 1;
                wb((void *) &syncCleanup[coreNum][0], sizeof(syncCleanup) /
                                                             NUM_DSP_CORES);
                /* Sleep so secondary cores can get barrier update for sync
                 * mechanism reset occurs */
                Task_sleep(1);
            } else {
                do {
                    inv((void *) &syncCleanup[SYSINIT][0], sizeof(syncCleanup) /
                                                                  NUM_DSP_CORES);
                } while (!syncCleanup[SYSINIT][0]); 
            }
    
            /* Reset all sync mechanisms */
            memset(&syncInit, 0, sizeof(syncInit));
            memset(&syncCleanup, 0, sizeof(syncCleanup));
            if (coreNum == SYSINIT) {
                wb((void *)&syncInit, sizeof(syncInit));
            } else {
                wb((void *)&syncCleanup[coreNum][0], sizeof(syncCleanup) /
                                                            NUM_DSP_CORES);
            }
    
            /* Restart test from initTsk */
            System_printf("Core %d : Recreating init task...\n", coreNum);
            Task_Params_init(&taskParams);
            taskParams.priority = 1;
            taskParams.stackSize = 4096;
            initTskHandle = Task_create(initTsk, &taskParams, NULL);
        } else {
            System_printf("Core %d : Testing complete! - ", coreNum);
            if (testFailed) {
                System_printf("FAILED\n");
            } else {
                System_printf("PASSED\n");
            }
        }
    }
    
    /**
     *  @b Description
     *  @n
     *      Task that runs the latency and throughput tests
     */
    void testTsk(UArg arg0, UArg arg1)
    {
        uint32_t    result;
        Task_Params taskParams;
    
        System_printf("Core %d : *********************************************\n",
                      coreNum);
        System_printf("Core %d : Starting Test Iteration: %d\n", coreNum,
                      testIterations);
        System_printf("Core %d : Test Packet Size: %d bytes\n", coreNum,
                      sizeof(TstMsg));
        System_printf("Core %d : *********************************************\n",
                      coreNum);
    
        System_printf("Core %d : ============== CORE ATTRIBUTES ==============\n",
                      coreNum);
        System_printf("Core %d : CPU Freq:        %d MHz\n", coreNum,
                      cpuFreq.lo / 1000000);
        System_printf("Core %d : Timer Freq:      %d MHz\n", coreNum,
                      timerFreq.lo / 1000000);
        System_printf("Core %d : nextQueueName:   %s\n", coreNum, nextQueueName);
        System_printf("Core %d : nextQueueId:     0x%08x\n", coreNum, nextQueueId);
        System_printf("Core %d : *********************************************\n\n",
                      coreNum);
    
        if (coreNum == SYSINIT) {
            System_printf("Core %d : "
                          "*********************************************\n",
                          coreNum);
            System_printf("Core %d : SHM transport latency measurement\n", coreNum);
        }
        result = testLatency(MessageQ_NORMALPRI, 0);
        if (result == TEST_FAIL) {
            testFailed = BENCH_TRUE;
            if (coreNum != SYSINIT) {
                System_printf("Core %d : SHM Latency Result\n", coreNum);
            }
            System_printf("Core %d : FAILED\n", coreNum);
            goto cleanup;
        }
    
        if (coreNum == SYSINIT) {
            System_printf("Core %d : PASSED\n", coreNum);
            System_printf("Core %d : "
                          "*********************************************\n\n",
                          coreNum);
    
            System_printf("Core %d : "
                          "*********************************************\n",
                          coreNum);
            System_printf("Core %d : SRIO Type 11 transport latency measurement\n",
                          coreNum);
        }
        result = testLatency(MessageQ_NORMALPRI, SRIO_T11_TRANS_NET_ID);
        if (result == TEST_FAIL) {
            testFailed = BENCH_TRUE;
            if (coreNum != SYSINIT) {
                System_printf("Core %d : SRIO Type 11 Latency Result\n", coreNum);
            }
            System_printf("Core %d : FAILED\n", coreNum);
            goto cleanup;
        }
    
        if (coreNum == SYSINIT) {
            System_printf("Core %d : PASSED\n", coreNum);
            System_printf("Core %d : "
                          "*********************************************\n\n",
                          coreNum);
    
            System_printf("Core %d : "
                          "*********************************************\n",
                          coreNum);
            System_printf("Core %d : SRIO Type 9 transport latency measurement\n",
                          coreNum);
        }
        result = testLatency(MessageQ_NORMALPRI, SRIO_T9_TRANS_NET_ID);
        if (result == TEST_FAIL) {
            testFailed = BENCH_TRUE;
            if (coreNum != SYSINIT) {
                System_printf("Core %d : SRIO Type 9 Latency Result\n", coreNum);
            }
            System_printf("Core %d : FAILED\n", coreNum);
            goto cleanup;
        }
    
        if (coreNum == SYSINIT) {
            System_printf("Core %d : PASSED\n", coreNum);
            System_printf("Core %d : "
                          "*********************************************\n\n",
                          coreNum);
    
            /* Wait for ready from secondary core */
            do {
                inv((void *) &syncInit, sizeof(syncInit));
            } while (!syncInit[SYNC_INDEX_SHM_TPUT]);
    
            System_printf("Core %d : "
                          "*********************************************\n",
                          coreNum);
            System_printf("Core %d : SHM transport throughput measurement\n",
                          coreNum);
        } else {
            /* Ready signal to primary DSP */
            syncInit[SYNC_INDEX_SHM_TPUT] = 1;
            wb((void *) &syncInit, sizeof(syncInit));
        }
        result = testTputAndDataIntegrity(MessageQ_NORMALPRI, 0);
        if (result == TEST_FAIL) {
            testFailed = BENCH_TRUE;
            if (coreNum != SYSINIT) {
                System_printf("Core %d : SHM Throughput Result\n", coreNum);
            }
            System_printf("Core %d : FAILED\n", coreNum);
            goto cleanup;
        }
    
        if (coreNum == SYSINIT) {
            System_printf("Core %d : PASSED\n", coreNum);
            System_printf("Core %d : "
                          "*********************************************\n\n",
                          coreNum);
    
            /* Wait for ready from secondary core */
            do {
                inv((void *) &syncInit, sizeof(syncInit));
            } while (!syncInit[SYNC_INDEX_SRIO_T11_TPUT]);
    
            System_printf("Core %d : "
                          "*********************************************\n",
                          coreNum);
            System_printf("Core %d : "
                          "SRIO Type 11 transport throughput measurement\n",
                          coreNum);
        } else {
            /* Ready signal to primary DSP */
            syncInit[SYNC_INDEX_SRIO_T11_TPUT] = 1;
            wb((void *) &syncInit, sizeof(syncInit));
        }
        result = testTputAndDataIntegrity(MessageQ_NORMALPRI,
                                          SRIO_T11_TRANS_NET_ID);
        if (result == TEST_FAIL) {
            testFailed = BENCH_TRUE;
            if (coreNum != SYSINIT) {
                System_printf("Core %d : SRIO Type 11 Throughput Result\n",
                              coreNum);
            }
            System_printf("Core %d : FAILED\n", coreNum);
            goto cleanup;
        }
    
        /* Cleanup any buffers that may be in transmit completion queue */
        TransportSrio_recycleUsedTxBufs(srioT11TransHandle);
    
        if (coreNum == SYSINIT) {
            System_printf("Core %d : PASSED\n", coreNum);
            System_printf("Core %d : "
                          "*********************************************\n",
                          coreNum);
            /* Wait for ready from secondary core */
            do {
                inv((void *) &syncInit, sizeof(syncInit));
            } while (!syncInit[SYNC_INDEX_SRIO_T9_TPUT]);
    
            System_printf("Core %d : "
                          "*********************************************\n",
                          coreNum);
            System_printf("Core %d : "
                          "SRIO Type 9 transport throughput measurement\n",
                          coreNum);
        } else {
            /* Ready signal to primary DSP */
            syncInit[SYNC_INDEX_SRIO_T9_TPUT] = 1;
            wb((void *) &syncInit, sizeof(syncInit));
        }
        result = testTputAndDataIntegrity(MessageQ_NORMALPRI, SRIO_T9_TRANS_NET_ID);
        if (result == TEST_FAIL) {
            testFailed = BENCH_TRUE;
            if (coreNum != SYSINIT) {
                System_printf("Core %d : SRIO Type 9 Throughput Result\n", coreNum);
            }
            System_printf("Core %d : FAILED\n", coreNum);
            goto cleanup;
        }
    
        /* Cleanup any buffers that may be in transmit completion queue */
        TransportSrio_recycleUsedTxBufs(srioT9TransHandle);
    
        if (coreNum == SYSINIT) {
            System_printf("Core %d : PASSED\n", coreNum);
        }
    
    cleanup:
        if (coreNum == SYSINIT) {
            System_printf("Core %d : "
                          "*********************************************\n\n",
                          coreNum);
        }
    
        /* Create the cleanup task */
        System_printf("Core %d : Creating cleanup task...\n", coreNum);
        Task_Params_init(&taskParams);
        taskParams.priority = 1;
        cleanupTskHandle = Task_create(cleanupTsk, &taskParams, NULL);
    }
    
    /**
     *  @b Description
     *  @n
     *      Application initialization task.
     */
    void initTsk(UArg arg0, UArg arg1)
    {
        Types_Timestamp64     time64;
        uint64_t              timeStamp;
        Task_Params           taskParams;
        Qmss_StartCfg         qmssStartCfg;
        Cppi_StartCfg         cppiStartCfg;
        Srio_InitConfig       srioInitCfg;
        int32_t               status;
        Error_Block           errorBlock;
        TransportSrio_Params  transSrioParamsT11;
        TransportSrio_Params  transSrioParamsT9;
        GateMP_Params         gateMpParams;
        HeapBufMP_Params      heapBufParams;
        uint8_t               pathMode;
        uint32_t              srioMaxMTU;
    
    //shankari
        Error_init(&eb);
        HeapTrack_Params_init(&prms);
    //shankari
    
        switch (testIterations) {
            case 0:
                /* Port 0 is 1x - from srioPortPathMode_e defined in
                 * device_srio.c */
                pathMode = 0;
                srioMaxMTU = SRIO_MTU_SIZE;
                System_printf("Core %d : Configuring SRIO port 0 as 1x "
                              "and MTU size as %d\n",
                              coreNum, srioMaxMTU);
                break;
            case 1:
                /* Port 0 is 2x - from srioPortPathMode_e defined in
                 * device_srio.c */
                pathMode = 3;
                srioMaxMTU = SRIO_MTU_SIZE;
                System_printf("Core %d : Configuring SRIO port 0 as 2x "
                              "and MTU size as %d\n",
                              coreNum, srioMaxMTU);
                break;
            case 2:
                /* Port 0 is 4x - from srioPortPathMode_e defined in
                 * device_srio.c */
                pathMode = 4;
                srioMaxMTU = SRIO_MTU_SIZE;
                System_printf("Core %d : Configuring SRIO port 0 as 4x "
                              "and MTU size as %d\n",
                              coreNum, srioMaxMTU);
                break;
            case 3:
                /* Port 0 is 1x - from srioPortPathMode_e defined in
                 * device_srio.c */
                pathMode = 0;
                srioMaxMTU = SRIO_MTU_SIZE_FRAG;
                System_printf("Core %d : Configuring SRIO port 0 as 1x "
                              "and MTU size as %d\n",
                              coreNum, srioMaxMTU);
                break;
            case 4:
                /* Port 0 is 2x - from srioPortPathMode_e defined in
                 * device_srio.c */
                pathMode = 3;
                srioMaxMTU = SRIO_MTU_SIZE_FRAG;
                System_printf("Core %d : Configuring SRIO port 0 as 2x "
                              "and MTU size as %d\n",
                              coreNum, srioMaxMTU);
                break;
            case 5:
                /* Port 0 is 4x - from srioPortPathMode_e defined in
                 * device_srio.c */
                pathMode = 4;
                srioMaxMTU = SRIO_MTU_SIZE_FRAG;
                System_printf("Core %d : Configuring SRIO port 0 as 4x "
                              "and MTU size as %d\n",
                              coreNum, srioMaxMTU);
                break;
            default:
                /* Port 0 is 1x for any further test iterations */
                pathMode = 0;
                srioMaxMTU = SRIO_MTU_SIZE;
                System_printf("Core %d : Configuring SRIO port 0 as 1x "
                              "and MTU size as %d\n",
                              coreNum, srioMaxMTU);
                break;
        }
    
        /* System initializations for each core. */
        if (coreNum == SYSINIT) {
            /* Run SRIO, QMSS, and CPPI system wide initializations */
            System_printf("Core %d : Initialize system peripherals\n", coreNum);
            status = systemInit();
            if (status != 0) {
                System_printf("Error Core %d : initializing system peripherals\n",
                              coreNum);
                return;
            }
    
            /* Power on SRIO peripheral */
            if (enableSrio() < 0) {
                System_printf("Error Core %d : SRIO PSC Initialization Failed\n",
                              coreNum);
                return;
            }
    
            /* Device Specific SRIO Initializations: This should always be called
             * before initializing the SRIO Driver. */
            if (SrioDevice_init(pathMode) < 0) {
                System_printf("Error Core %d : SRIO HW Initialization Failed\n",
                              coreNum);
                return;
            }
    
            /* Initialize SRIO driver */
            memset(&srioInitCfg, 0, sizeof(srioInitCfg));
            srioInitCfg.rmServiceHandle = rmServiceHandle;
            if (Srio_initCfg(&srioInitCfg) < 0) {
                System_printf("Error Core %d : SRIO Driver Initialization Failed\n",
                              coreNum);
                return;
            }
    
            System_printf("Core %d : SRIO Driver has been initialized\n", coreNum);
         
            /* Signal to other DSPs that system init is complete */
            syncInit[SYNC_INDEX_SYS_INIT] = 1;
            wb((void *) &syncInit, sizeof(syncInit));
        } else {
            System_printf("Core %d : Waiting for SRIO to be initialized.\n",
                          coreNum);
    
            /* Wait for SYSINIT core to complete system init */
            do {
                inv((void *) &syncInit, sizeof(syncInit));
            } while (!syncInit[SYNC_INDEX_SYS_INIT]);
    
            /* Start Queue Manager SubSystem with RM */
            qmssStartCfg.rmServiceHandle = rmServiceHandle;
            qmssStartCfg.pQmssGblCfgParams = &qmssGblCfgParams;
            status = Qmss_startCfg(&qmssStartCfg);
            if (status != QMSS_SOK) {
                System_printf("Error Core %d : Unable to start the QMSS\n",
                              coreNum);
                return;
            }
    
            /* Register RM with CPPI */
            cppiStartCfg.rmServiceHandle = rmServiceHandle;
            Cppi_startCfg(&cppiStartCfg);
    
            System_printf("Core %d : SRIO can now be used.\n", coreNum);
        }
    
        /* Timestamping setup */
        Timestamp_getFreq(&timerFreq);
        System_printf("Core %d : timerFreq.lo = %d. timerFreq.hi = %d\n", coreNum,
                      timerFreq.lo, timerFreq.hi);
        BIOS_getCpuFreq(&cpuFreq);
        System_printf("Core %d : cpuFreq.lo = %d. cpuFreq.hi = %d\n", coreNum,
                      cpuFreq.lo, cpuFreq.hi);
        cpuTimerFreqRatio = (Float)cpuFreq.lo / (Float)timerFreq.lo;
    
        Timestamp_get64(&time64);
        timeStamp = TIMESTAMP64_TO_UINT64(time64.hi,time64.lo);
        timeAdj = TIMESTAMP64_TO_UINT64(time64.hi,time64.lo) - timeStamp;
    
        if (coreNum == SYSINIT) {
            /* Create the heap that will be used to allocate messages. */
            GateMP_Params_init(&gateMpParams);
            gateMpParams.localProtect = GateMP_LocalProtect_INTERRUPT;
            gateMpHandle = GateMP_create(&gateMpParams);
            
            HeapBufMP_Params_init(&heapBufParams);
            heapBufParams.regionId  = 0;
            heapBufParams.name      = SRIO_MSGQ_HEAP_NAME;
            heapBufParams.numBlocks = TEST_BUF_NUM;
            heapBufParams.blockSize = TEST_BUF_SIZE;
            /* GateMP so allocation can take place within SRIO rx interrupt
             * context */
            heapBufParams.gate      = gateMpHandle;
            heapHandle = HeapBufMP_create(&heapBufParams);
            if (heapHandle == NULL) {
                System_printf("Error Core %d : HeapBufMP_create failed\n", coreNum);
                return;
            }
    
            //shankari
            prms.heap = (xdc_runtime_IHeap_Handle)&heapHandle;
            heap = HeapTrack_create(&prms, &eb);
            if (heap == NULL) {
              System_abort("HeapTrack create failed");
            }
    
            //shankari
    
    
        } else {
            /* Open the heap created by the other processor. Loop until opened. */
            do {
                status = HeapBufMP_open(SRIO_MSGQ_HEAP_NAME, &heapHandle);
            } while (status < 0);
        }
    
        /* Each core must register this heap with MessageQ */
        MessageQ_registerHeap((IHeap_Handle)heapHandle, SRIO_MSGQ_HEAP_ID);
    
        System_sprintf(localQueueName, "CORE%d", coreNum);
        System_sprintf(nextQueueName, "CORE%d", ((coreNum + 1) % ipcNumDspCores));
    
        System_printf("Core %d : "
                      "localQueueName=%s. nextQueueName=%s\n",
                      coreNum, localQueueName, nextQueueName);
    
        /* Create a message queue. */
        localMessageQ = MessageQ_create(localQueueName, NULL);
        if (localMessageQ == NULL) {
            System_printf("Error Core %d : MessageQ_create failed\n", coreNum);
            return;
        }
    
        /* Open the 'next' remote message queue. Spin until it is ready. */
        do {
            status = MessageQ_open(nextQueueName, &nextQueueId);
        } while (status < 0);
    
        /* Create SRIO type 11 & 9 transport instances.  They will be a network
         * transport so won't interfere with default MessageQ transport, shared
         * memory notify transport */
    
        /* Type 11 configuration */
        TransportSrio_Params_init(&transSrioParamsT11);
        /* Configure common parameters */
        transSrioParamsT11.deviceCfgParams   = &srioTransCfgParams;
        transSrioParamsT11.txMemRegion       = HOST_DESC_MEM_REGION;
        transSrioParamsT11.txNumDesc         = TRANS_SEND_DESC;
        transSrioParamsT11.txNumFragDesc     = TRANS_FRAG_DESC;
        transSrioParamsT11.txMsgQFragHeapId  = SRIO_MSGQ_HEAP_ID;
        transSrioParamsT11.txDescSize        = HOST_DESC_SIZE_BYTES;
        transSrioParamsT11.rxQType           = Qmss_QueueType_HIGH_PRIORITY_QUEUE;
        transSrioParamsT11.rxMemRegion       = HOST_DESC_MEM_REGION;
        transSrioParamsT11.rxNumDesc         = TRANS_RCV_DESC;
        transSrioParamsT11.rxDescSize        = HOST_DESC_SIZE_BYTES;
        transSrioParamsT11.rxMsgQHeapId      = SRIO_MSGQ_HEAP_ID;
        transSrioParamsT11.maxMTU            = srioMaxMTU;
        transSrioParamsT11.rmServiceHandle   = rmServiceHandle;
        /* Must map to a valid channel for each DSP core.  Follow sprugr9h.pdf
         * Table 5-7 for C6678 and Table 5-9 for K2HK */
        transSrioParamsT11.accumCh           = DNUM;
        transSrioParamsT11.accumTimerCount   = 0;
        transSrioParamsT11.transNetworkId    = SRIO_T11_TRANS_NET_ID;
        transSrioParamsT11.rxIntVectorId     = 8;
    
        memset(&t11EpParams, 0, sizeof(t11EpParams));
    #if (defined(DEVICE_C6657) || defined(DEVICE_C6678))
        /* DSP Core 0 */
        t11EpParams[0].tt       = 1;
        t11EpParams[0].deviceId = DEVICE_ID1_16BIT;
        t11EpParams[0].mailbox  = 0;
        t11EpParams[0].letter   = 0;
        t11EpParams[0].segMap   = (sizeof(TstMsg) > 256 ? 1 :0);
        /* DSP Core 1 */
        t11EpParams[1].tt       = 1;
        t11EpParams[1].deviceId = DEVICE_ID2_16BIT;
        t11EpParams[1].mailbox  = 0;
        t11EpParams[1].letter   = 0;
        t11EpParams[1].segMap   = (sizeof(TstMsg) > 256 ? 1 :0);
    #else
        /* ARMv7 Linux Host */
        t11EpParams[0].tt       = 1;
        t11EpParams[0].deviceId = DEVICE_ID1_16BIT;
        t11EpParams[0].mailbox  = 1;
        t11EpParams[0].letter   = 0;
        t11EpParams[0].segMap   = (sizeof(TstMsg) > 256 ? 1 :0);
        /* DSP Core 0 */
        t11EpParams[1].tt       = 1;
        t11EpParams[1].deviceId = DEVICE_ID1_16BIT;
        t11EpParams[1].mailbox  = 0;
        t11EpParams[1].letter   = 0;
        t11EpParams[1].segMap   = (sizeof(TstMsg) > 256 ? 1 :0);
        /* DSP Core 1 */
        t11EpParams[2].tt       = 1;
        t11EpParams[2].deviceId = DEVICE_ID2_16BIT;
        t11EpParams[2].mailbox  = 0;
        t11EpParams[2].letter   = 0;
        t11EpParams[2].segMap   = (sizeof(TstMsg) > 256 ? 1 :0);
    #endif
    
        memset(&t11socketParams, 0, sizeof(t11socketParams));
        t11socketParams.epListSize = NUM_CORES;
        t11socketParams.sockType = TransportSrio_srioSockType_TYPE_11;
        t11socketParams.u.pT11Eps = &t11EpParams[0];
    
        transSrioParamsT11.sockParams = &t11socketParams;
    
        Error_init(&errorBlock);
        System_printf("Core %d : "
                      "Creating SRIO Transport instance with Type 11 socket\n",
                      coreNum);
        srioT11TransHandle = TransportSrio_create(&transSrioParamsT11, &errorBlock);
        if (srioT11TransHandle == NULL) {
            System_printf("Error Core %d : "
                          "TransportSrio_create failed with id %d\n", coreNum,
                          errorBlock.id);
            return;
        }
    
        /* Type 9 configuration */
        TransportSrio_Params_init(&transSrioParamsT9);
        /* Configure common parameters */
        transSrioParamsT9.deviceCfgParams   = &srioTransCfgParams;
        transSrioParamsT9.txMemRegion       = HOST_DESC_MEM_REGION;
        transSrioParamsT9.txNumDesc         = TRANS_SEND_DESC;
        transSrioParamsT9.txNumFragDesc     = TRANS_FRAG_DESC;
        transSrioParamsT9.txMsgQFragHeapId  = SRIO_MSGQ_HEAP_ID;
        transSrioParamsT9.txDescSize        = HOST_DESC_SIZE_BYTES;
        transSrioParamsT9.rxQType           = Qmss_QueueType_HIGH_PRIORITY_QUEUE;
        transSrioParamsT9.rxMemRegion       = HOST_DESC_MEM_REGION;
        transSrioParamsT9.rxNumDesc         = TRANS_RCV_DESC;
        transSrioParamsT9.rxDescSize        = HOST_DESC_SIZE_BYTES;
        transSrioParamsT9.rxMsgQHeapId      = SRIO_MSGQ_HEAP_ID;
        transSrioParamsT9.maxMTU            = srioMaxMTU;
        transSrioParamsT9.rmServiceHandle   = rmServiceHandle;
        /* Type 9 instance specific parameters */
    #if defined(DEVICE_C6657)
        /* Must map to a valid channel for each DSP core.  Follow sprugr9h.pdf
         * Table 5-3 & 5-4 for C6657 */
        transSrioParamsT9.accumCh            = DNUM + 2; /* Next valid accum ch is
                                                          * number of device DSP
                                                          * cores away
                                                          * (2 for C6657) */
    #else
        /* Must map to a valid channel for each DSP core.  Follow sprugr9h.pdf
         * Table 5-7 for C6678 and Table 5-9 for K2HK */
        transSrioParamsT9.accumCh            = DNUM + 8; /* Next valid accum ch is
                                                          * number of device DSP
                                                          * cores away
                                                          * (8 for C6678 & K2HK) */
    #endif
        transSrioParamsT9.accumTimerCount    = 0;
        transSrioParamsT9.transNetworkId     = SRIO_T9_TRANS_NET_ID;
        transSrioParamsT9.rxIntVectorId      = 9;
    
        /* Type 9 specific */
        memset(&t9EpParams, 0, sizeof(t9EpParams));
    #if (defined(DEVICE_C6657) || defined(DEVICE_C6678))
        /* DSP Core 0 */
        t9EpParams[0].tt       = 1;
        t9EpParams[0].deviceId = DEVICE_ID1_16BIT;
        t9EpParams[0].cos      = 0;
        t9EpParams[0].streamId = 0;
        /* DSP Core 1 */
        t9EpParams[1].tt       = 1;
        t9EpParams[1].deviceId = DEVICE_ID2_16BIT;
        t9EpParams[1].cos      = 0;
        t9EpParams[1].streamId = 0;
    #else
        /* ARMv7 Linux Host */
        t9EpParams[0].tt       = 1;
        t9EpParams[0].deviceId = DEVICE_ID1_16BIT;
        t9EpParams[0].cos      = 0;
        t9EpParams[0].streamId = 1;
        /* DSP Core 0 */
        t9EpParams[1].tt       = 1;
        t9EpParams[1].deviceId = DEVICE_ID1_16BIT;
        t9EpParams[1].cos      = 0;
        t9EpParams[1].streamId = 0;
        /* DSP Core 1 */
        t9EpParams[2].tt       = 1;
        t9EpParams[2].deviceId = DEVICE_ID2_16BIT;
        t9EpParams[2].cos      = 0;
        t9EpParams[2].streamId = 0;
    #endif
    
        memset(&t9socketParams, 0, sizeof(t9socketParams));
        t9socketParams.epListSize = NUM_CORES;
        t9socketParams.sockType = TransportSrio_srioSockType_TYPE_9;
        t9socketParams.u.pT9Eps = &t9EpParams[0];
    
        transSrioParamsT9.sockParams = &t9socketParams;
    
        Error_init(&errorBlock);
        System_printf("Core %d : "
                      "Creating SRIO Transport instance with Type 9 socket\n",
                      coreNum);
        srioT9TransHandle = TransportSrio_create(&transSrioParamsT9, &errorBlock);
        if (srioT9TransHandle == NULL) {
            System_printf("Error Core %d : "
                          "TransportSrio_create failed with id %d\n", coreNum,
                          errorBlock.id);
            return;
        }
    
    #if RM_PRINT_STATS
        if (coreNum == SYSINIT) {
            Rm_resourceStatus(rmHandle, 1);
        }
        Rm_instanceStatus(rmHandle);
    #endif
    
        /* Delete a previous test iterations cleanup task */
        if (cleanupTskHandle) {
            Task_delete(&cleanupTskHandle);
            cleanupTskHandle = NULL;
        }
    
        /* Create the test task */
        System_printf("Core %d : Creating test task...\n", coreNum);
        Task_Params_init(&taskParams);
        taskParams.priority = 1;
        testTskHandle = Task_create(testTsk, &taskParams, NULL);
    }
    
    /**
     *  @b Description
     *  @n
     *      Proxy task for the initTsk.  The initTsk needs a larger stack.  The
     *      setupRmTransConfig function does not allow specification of post-setup
     *      task stack size.  This function takes care of that for the initTsk.
     */
    void proxyInitTsk(UArg arg0, UArg arg1)
    {
        Task_Params taskParams;
    
        /* Create the initialization task */
        Task_Params_init(&taskParams);
        taskParams.priority = 1;
        taskParams.stackSize = 4096;
        initTskHandle = Task_create(initTsk, &taskParams, NULL);
    }
    
    /**
     *  @b Description
     *  @n
     *      Main - Initialize the system and start BIOS
     */
    void main(int32_t argc, char *argv[])
    {
        int32_t     status;
        Rm_InitCfg  rmInitCfg;
        char        rmInstName[RM_NAME_MAX_CHARS];
        int32_t     rmResult;
    
        coreNum = CSL_chipReadReg(CSL_CHIP_DNUM);
        ipcCoreId = MultiProc_self();
        ipcNumDspCores = NUM_DSP_CORES;
        testIterations = 0;
        testFailed = BENCH_FALSE;
    
        System_printf("Core %d : ********************************************\n",
                      coreNum);
        System_printf("Core %d : *** IPC SRIO Transport Benchmark Example ***\n",
                      coreNum);
        System_printf("Core %d : ********************************************\n",
                      coreNum);
        System_printf("Core %d : Device name:               %s\n", coreNum,
                      DEVICENAME);
        System_printf("Core %d : Processor names:           %s\n", coreNum,
                      PROCNAMES);
        System_printf("Core %d : IPC Core ID:               %d\n", coreNum,
                      ipcCoreId);
        System_printf("Core %d : Number of DSPs             %d\n", coreNum,
                      ipcNumDspCores);
        System_printf("Core %d : Number of test iterations: %d\n", coreNum,
                      TEST_ITERATIONS_TOT);
        System_printf("Core %d : Starting IPC core %d with name (\"%s\")\n",
                      coreNum, ipcCoreId, MultiProc_getName(ipcCoreId));
    
        status = Ipc_start();
        if (status < 0) {
            System_printf("Error Core %d: Ipc_start failed\n", coreNum);
            return;
        }
    
        /* Initialize RM */
        if (coreNum == SYSINIT) {
            /* Create the Server instance */
            memset((void *)&rmInitCfg, 0, sizeof(Rm_InitCfg));
            System_sprintf(rmInstName, "RM_Server");
            rmInitCfg.instName = rmInstName;
            rmInitCfg.instType = Rm_instType_SERVER;
            rmInitCfg.instCfg.serverCfg.globalResourceList = (void *)rmGlobalResourceList;
    #if defined(LINUX_NO_BOOT) || (defined(DEVICE_C6657) || defined(DEVICE_C6678))
            rmInitCfg.instCfg.serverCfg.globalPolicy = (void *)rmDspOnlyPolicy;
    #else
            rmInitCfg.instCfg.serverCfg.globalPolicy = (void *)rmDspPlusArmPolicy;
    #endif
            rmHandle = Rm_init(&rmInitCfg, &rmResult);
            if (rmResult != RM_OK) {
                System_printf("Error Core %d : "
                              "Initializing Resource Manager error code : %d\n",
                              coreNum, rmResult);
                return;
            }
    
            syncInit[SYNC_INDEX_RM_INIT] = 1;
            wb((void *) &syncInit, sizeof(syncInit));
        } else {
            /* Create a RM Client instance */
            memset((void *)&rmInitCfg, 0, sizeof(Rm_InitCfg));
            System_sprintf(rmInstName, "RM_Client%d", coreNum);
            rmInitCfg.instName = rmInstName;
            rmInitCfg.instType = Rm_instType_CLIENT;
            rmHandle = Rm_init(&rmInitCfg, &rmResult);
            if (rmResult != RM_OK) {
                System_printf("Error Core %d : "
                              "Initializing Resource Manager error code : %d\n",
                              coreNum, rmResult);
                return;
            }
    
            /* Wait for RM Server to start */
            do {
                inv((void *) &syncInit, sizeof(syncInit));
            } while (!syncInit[SYNC_INDEX_RM_INIT]);
        }
    
        rmServiceHandle = Rm_serviceOpenHandle(rmHandle, &rmResult);
        if (rmResult != RM_OK) {
            System_printf("Error Core %d : "
                          "Creating RM service handle error code : %d\n", coreNum,
                          rmResult);
            return;
        }
    
        /* Configure the RM transport.  Will jump to specified task upon
         * completion */
        System_printf("Core %d : Configuring RM transport via IPC...\n", coreNum);
        if (setupRmTransConfig(ipcNumDspCores, SYSINIT, proxyInitTsk) < 0) {
            System_printf("Error Core %d : Transport setup for RM error\n",
                          coreNum);
            return;
        }
    
        System_printf("Core %d : Starting BIOS...\n", coreNum);
        BIOS_start();
    }
    
    

    This is what I did:-

    -------

    In the .cfg file

    var BIOS = xdc.useModule('ti.sysbios.BIOS');
    BIOS.heapSize = 0xF000;
    BIOS.heapTrackEnabled = true;

    ------

    In the .c file

    //shankari
    #include <xdc/runtime/Memory.h>

    #include <ti/sysbios/heaps/HeapTrack.h>
    -------------------------

    //Global variables

    HeapTrack_Params prms;
    HeapTrack_Handle heap;
    Error_Block eb;
    ---------------------

    Error_init(&eb);
    HeapTrack_Params_init(&prms);

    --------------------

    // The existing heap handle

    heapHandle = HeapBufMP_create(&heapBufParams);
    if (heapHandle == NULL) {
    System_printf("Error Core %d : HeapBufMP_create failed\n", coreNum);
    return;
    }

    //shankari
    prms.heap = (xdc_runtime_IHeap_Handle)&heapHandle; // Attaching the existing handle to the Heap tracker here.
    heap = HeapTrack_create(&prms, &eb);
    if (heap == NULL) {
    System_abort("HeapTrack create failed");
    }

    ------

    Output in debug window

    -----

    Alternatively, I have tested, HeapMemMP_getExtendedStats and the Memory_getStats functions too. And these functions are working too.

    Try these functions too, as these are comparitively easier than the heap tracker functions.

    Regards

    Shankari G

  • Thank you for the more detailed response. Currently I have equipment issues and am not able to try my new firmware. i will respond as soon as i am able.

  • Dear Customer,

    Ok.

    Sure, I will wait for your response.

    For the time being, I am closing this thread; Whenever you post a reply, automatically, it will get re-opened and I will receive an email.

    Regards

    Shankari G

  • Hello Shankari,

    I was able to attempt a run of the heap tracker code on my DSP platform recently.

    The DSP fails to boot up with the heap tracker instantiated.

    I have troubleshot the the problem down to the point in the code where the heap tracker pointer is tested for validation. This is where it fails and the firmware aborts:

     if (hHeapTracker == NULL) {
            System_abort("HeapTrack create failed"); // Firmware is aborting here.
            // TODO: Handle Error and fall back up the call chain.
        }

    The only real clue I have is a warning message about the Bios heap:

    The config file line:

    var BIOS = xdc.useModule('ti.sysbios.BIOS');

    Is generating a warning:

    Can't call useModule('ti.sysbios.knl.Queue') after all packages are closed (phase 4 or above)    Core0.cfg

    I am not sure what that means. I have nor been able to find reference to it in the documentation so far.

  • Forrest,

    OK.

    Alternatively, I have tested, HeapMemMP_getExtendedStats and the Memory_getStats functions . And these functions are working too.

    Please try "HeapMemMP_getExtendedStats" as an alternate option.

    Some sample code which displays the heap memory status 

    ...

    HeapMemMP_ExtendedStats gIpcMsgHeapStats;

    ...

    ...

    // Get the heap handle for the SL2 memory
    gHeapMemIpcMsgSL2Handle = SharedRegion_getHeap(SL2HEAPID);


    ErrorMgr_assertFatal( (gHeapMemIpcMsgSL2Handle != NULL), ERROR_TYPE_COMMON_HEAP_CREATE_ERR, (Uint32)gHeapMemIpcMsgSL2Handle);


    status = SharedRegion_getEntry(SL2HEAPID, &gSharedRegionEntry[1]);


    ErrorMgr_assertFatal(status == SharedRegion_S_SUCCESS, ERROR_TYPE_COMMON_HEAP_CREATE_ERR, status);

    Memory_getStats(gHeapMemIpcMsgSL2Handle, &gSharedRegionHeapMemStats[1]);

    HeapMemMP_getExtendedStats( gHeapMemIpcMsgSL2Handle, &gIpcMsgHeapStats );

    Regards

    Shankari G

  • Hello Shankari,

    I made an attempt to use your alternate method.

    The library function "SharedRegion_getHeap" does not exist in the version(1.25) of the IPC I am working with.

    I am forced to use that library to maintain compatibility with the other legacy libraries in the project.

    Even though the newest libraries support the DSP we are using and fix a multitude of bugs,

    my managers and coworkers are insistent upon not upgrading to newer libraries as they fear it will break something else.

    Even if that had worked I am still convinced that the invalid pointer to the heap is a fundamental issue that should be resolved.

    What are my other options?

    Thank You,

    Forrest

  • Forrest,

    I understand your constraints on upgrading/using the latest version of IPC.

    If these APIs are available and working solidly only on the latest IPC, then we have no choice other than using the latest.

    Fixing the bugs on the older versions of IPC may not be expected from TI. 

    But it can be customized by the customer referring to the latest version of IPC and implement in the older versions, used.

    Thanks for understanding!

    Regards

    Shankari G