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.

[DM8148] IPC_BITSINLINK:!WARNING!

Dear Experts,

I use DVRRDK3.5/DM8148. M3VPSS/M3Video/C6XDSP handle encode process. A8 handle encoded data.

I got some problem about IPC.

When below messages occurs, A8 cannot communicate with M3.

It seems IPC has some problems.

How can I fix this problem??

=== Error Message ===

...(many)...

[host] IPC_BITSINLINK:!WARNING!.Commands not being processed by link.TimeSinceLastAlloc:3834,TimeSinceLastFree:3834
[host] IPC_BITSINLINK:!WARNING!.Commands not being processed by link.TimeSinceLastAlloc:3834,TimeSinceLastFree:3834
[host] IPC_BITSINLINK:!WARNING!.Commands not being processed by link.TimeSinceLastAlloc:3836,TimeSinceLastFree:3836

...

thx ~

HB

  • The warning indicates ipcBitsInLink main thread is not getting scheduled. Do you have ipc notify enabled between ipcBitsOut and ipcBitsIn or do you use noNotifyMode ?

    What is your application callback function  from ipcBitsInLink doing ? Is it just posting a semaphore to trigger another thread or do you do some operation in the callback ?

    You will have to check why the ipcBitsInLink thread is not getting scheduled by adding some debug code.

  • Dear Badri,


    1) We don't use notify Mode. We are using noNotifyMode.

    2) We don't use callback function. At IpcBitsInLink_getFullBitBufs (ipcBitsInLink_tsk.c (dvr_rdk\mcfw\src_linux\links\ipcbitsin), we use

    status =  OSA_queGet(&pObj->outBitBufQue,
                         (Int32 *) (&pBitBufList->bufs[idx]), OSA_TIMEOUT_FOREVER);

    3) What debug code could be add to debug such issues? Could you provide us suggestion or example code.

    /*******************************************************************************
     *                                                                             *
     * Copyright (c) 2009 Texas Instruments Incorporated - http://www.ti.com/      *
     *                        ALL RIGHTS RESERVED                                  *
     *                                                                             *
     ******************************************************************************/
    #include <stddef.h>
    #include "ipcBitsInLink_priv.h"
    #include <ti/syslink/utils/IHeap.h>
    #include <ti/syslink/utils/Memory.h>
    #include <ti/syslink/utils/Cache.h>
    
    IpcBitsInLink_Obj gIpcBitsInLink_obj[IPC_BITS_IN_LINK_OBJ_MAX];
    
    static
    Int32 IpcBitsInLink_getFullBitBufs(IpcBitsInLink_Obj * pObj,
                                       Bitstream_BufList * pBitBufList);
    
    static
    Int32 IpcBitsInLink_putEmptyBitBufs(IpcBitsInLink_Obj * pObj,
                                        Bitstream_BufList * pBitBufList);
    
    Void IpcBitsInLink_notifyCb(OSA_TskHndl * pTsk)
    {
        OSA_tskSendMsg(pTsk, NULL, SYSTEM_CMD_NEW_DATA, NULL, 0);
    }
    
    Void *IpcBitsInLink_periodicTaskFxn(Void * prm)
    {
        IpcBitsInLink_Obj *pObj = (IpcBitsInLink_Obj *) prm;
        Int32 status;
    
        while (FALSE == pObj->prd.exitThread)
        {
            OSA_waitMsecs(IPC_BITS_IN_PROCESS_PERIOD_MS);
            if (pObj->prd.numPendingCmd < IPC_BITS_IN_MAX_PENDING_NEWDATA_CMDS)
            {
                pObj->prd.numPendingCmd++;
                status = System_sendLinkCmd(pObj->tskId, SYSTEM_CMD_NEW_DATA);
            }
            else
            {
                UInt32 curTime = OSA_getCurTimeInMsec();
    
                OSA_printf("IPC_BITSINLINK:!WARNING!.Commands not being processed by link."
                           "TimeSinceLastAlloc:%d,TimeSinceLastFree:%d\n",
                           (curTime - pObj->stats.lastGetBufTime),
                           (curTime - pObj->stats.lastFreeBufTime));
            }
        }
        return NULL;
    }
    
    static Void IpcBitsInLink_initStats(IpcBitsInLink_Obj * pObj)
    {
        memset(&pObj->stats, 0, sizeof(pObj->stats));
    }
    
    static
    Int32 IpcBitsInLink_createPrdObj(IpcBitsInLink_Obj * pObj)
    {
        pObj->prd.numPendingCmd = 0;
        pObj->prd.exitThread = FALSE;
        OSA_thrCreate(&pObj->prd.thrHandle,
                      IpcBitsInLink_periodicTaskFxn,
                      IPC_LINK_TSK_PRI, IPC_LINK_TSK_STACK_SIZE, pObj);
        return IPC_BITS_IN_LINK_S_SUCCESS;
    }
    
    static
    Int32 IpcBitsInLink_deletePrdObj(IpcBitsInLink_Obj * pObj)
    {
        pObj->prd.exitThread = TRUE;
        OSA_thrDelete(&pObj->prd.thrHandle);
        pObj->prd.numPendingCmd = 0;
        return IPC_BITS_IN_LINK_S_SUCCESS;
    }
    
    Int32 IpcBitsInLink_create(IpcBitsInLink_Obj * pObj,
                               IpcBitsInLinkHLOS_CreateParams * pPrm)
    {
        Int32 status;
        System_LinkInQueParams *pInQueParams;
    
    #ifdef SYSTEM_DEBUG_IPC
        OSA_printf(" %d: IPC_BITS_IN   : Create in progress !!!\n",
                   OSA_getCurTimeInMsec());
    #endif
        memcpy(&pObj->createArgs, pPrm, sizeof(pObj->createArgs));
    
        OSA_printf(" %d: IPC_BITS_IN   : ListMPOpen start !!!\n",
                   OSA_getCurTimeInMsec());
        status =
            System_ipcListMPOpen(pObj->createArgs.baseCreateParams.inQueParams.
                                 prevLinkId, &pObj->listMPOutHndl,
                                 &pObj->listMPInHndl);
        OSA_assert(status == OSA_SOK);
        OSA_assert(pObj->listMPInHndl != NULL);
    
        OSA_printf(" %d: IPC_BITS_IN   : ListMPOpen done !!!\n",
                   OSA_getCurTimeInMsec());
    
        while(!ListMP_empty(pObj->listMPInHndl))
        {
            Ptr listElem =
            ListMP_getHead(pObj->listMPInHndl);
            if (listElem != NULL)
            {
                IPCBITSINLINK_INFO_LOG(pObj->tskId,
                                       "InList not empty!!!"
                                       "Stale entry:[%p]",
                                       listElem);
            }
        }
    
        status = OSA_queCreate(&pObj->outBitBufQue, SYSTEM_IPC_BITS_MAX_LIST_ELEM);
        OSA_assert(status == OSA_SOK);
    
        pInQueParams = &pObj->createArgs.baseCreateParams.inQueParams;
    
        status = System_linkGetInfo(pInQueParams->prevLinkId, &pObj->inQueInfo);
        OSA_assert(status == OSA_SOK);
        OSA_printf(" %d: IPC_BITS_IN   : System_linkGetInfo done !!!\n",
                   OSA_getCurTimeInMsec());
    
        IpcBitsInLink_initStats(pObj);
        if (pObj->createArgs.baseCreateParams.noNotifyMode)
        {
            IpcBitsInLink_createPrdObj(pObj);
        }
    
    #ifdef SYSTEM_DEBUG_IPC
        OSA_printf(" %d: IPC_BITS_IN   : Create Done !!!\n",
                   OSA_getCurTimeInMsec());
    #endif
    
        return IPC_BITS_IN_LINK_S_SUCCESS;
    }
    
    Int32 IpcBitsInLink_delete(IpcBitsInLink_Obj * pObj)
    {
        Int32 status;
    
        if (pObj->createArgs.baseCreateParams.noNotifyMode)
        {
            IpcBitsInLink_deletePrdObj(pObj);
        }
        IPCBITSINLINK_INFO_LOG(pObj->tskId,
                               "RECV:%d\tFREE:%d,DROPPED:%d,AVGLATENCY:%d,AVG_APP_CB_TIME:%d\n",
                               pObj->stats.recvCount,
                               pObj->stats.freeCount,
                               pObj->stats.droppedCount,
                        OSA_DIV(pObj->stats.totalRoundTrip ,
                                pObj->stats.freeCount),
                        OSA_DIV(pObj->stats.totalAppCallbackTime,
                                pObj->stats.numFreeBufCalls));
    #ifdef SYSTEM_DEBUG_IPC
        OSA_printf(" %d: IPC_BITS_IN   : Delete in progress !!!\n",
                   OSA_getCurTimeInMsec());
    #endif
    
        status = System_ipcListMPClose(&pObj->listMPOutHndl, &pObj->listMPInHndl);
        OSA_assert(status == OSA_SOK);
    
        OSA_queDelete(&pObj->outBitBufQue);
    
    #ifdef SYSTEM_DEBUG_IPC
        OSA_printf(" %d: IPC_BITS_IN   : Delete Done !!!\n",
                   OSA_getCurTimeInMsec());
    #endif
    
        return IPC_BITS_IN_LINK_S_SUCCESS;
    }
    
    static Int32 IpcBitsInLink_getBitBuf(IpcBitsInLink_Obj * pObj,
                                         SystemIpcBits_ListElem * pListElem,
                                         Bitstream_Buf ** pBitBufPtr)
    {
        OSA_assert(pListElem != NULL);
        /* No cache ops done since pListElem is allocated from non-cached memory */
        OSA_assert(SharedRegion_isCacheEnabled(SharedRegion_getId(pListElem)) ==
                   FALSE);
        pListElem->bitBuf.addr = SharedRegion_getPtr(pListElem->srBufPtr);
        if (pListElem->bitBuf.fillLength)
        {
            Cache_inv(pListElem->bitBuf.addr,
                      pListElem->bitBuf.fillLength, Cache_Type_ALL, TRUE);
        }
        if(pListElem->bitBuf.mvDataFilledSize)
    	{
            Cache_inv(pListElem->bitBuf.addr + pListElem->bitBuf.mvDataOffset,
                      pListElem->bitBuf.mvDataFilledSize, Cache_Type_ALL, TRUE);	
    	}
        
        *pBitBufPtr = &pListElem->bitBuf;
        return IPC_BITS_IN_LINK_S_SUCCESS;
    }
    
    Int32 IpcBitsInLink_processBitBufs(IpcBitsInLink_Obj * pObj)
    {
        Bitstream_Buf *pBitBuf;
        SystemIpcBits_ListElem *pListElem;
        UInt32 numBitBufs;
        Int32 status;
        UInt32 curTime;
    
        numBitBufs = 0;
        curTime = OSA_getCurTimeInMsec();
        while (1)
        {
            pListElem = ListMP_getHead(pObj->listMPOutHndl);
            if (pListElem == NULL)
                break;
            IpcBitsInLink_getBitBuf(pObj, pListElem, &pBitBuf);
            OSA_assert(SYSTEM_IPC_BITS_GET_BUFSTATE(pListElem->bufState)
                       == IPC_BITBUF_STATE_OUTQUE);
            SYSTEM_IPC_BITS_SET_BUFOWNERPROCID(pListElem->bufState);
            SYSTEM_IPC_BITS_SET_BUFSTATE(pListElem->bufState,
                                         IPC_BITBUF_STATE_DEQUEUED);
            pBitBuf->reserved[0] = curTime;
            pObj->stats.recvCount++;
            status =
                OSA_quePut(&pObj->outBitBufQue, (Int32) pBitBuf, OSA_TIMEOUT_NONE);
            OSA_assert(status == OSA_SOK);
    
            numBitBufs++;
        }
    
    #ifdef SYSTEM_DEBUG_IPC_RT
        OSA_printf(" %d: IPC_BITS_IN   : Recevived %d bitbufs !!!\n",
                   OSA_getCurTimeInMsec(), numBitBufs);
    #endif
    
        if (numBitBufs)
        {
            if (pObj->createArgs.cbFxn)
            {
                pObj->createArgs.cbFxn(pObj->createArgs.cbCtx);
            }
        }
    
        return IPC_BITS_IN_LINK_S_SUCCESS;
    }
    
    static
    Int32 IpcBitsInLink_getFullBitBufs(IpcBitsInLink_Obj * pObj,
                                       Bitstream_BufList * pBitBufList)
    {
        UInt32 idx;
        Int32 status;
        UInt32 curTime;
    #if 1
    	UInt32 bufNum=1;
    #else
    	UInt32 bufNum=VIDBITSTREAM_MAX_BITSTREAM_BUFS;
    #endif
        curTime = OSA_getCurTimeInMsec();
    
        for (idx = 0; idx < bufNum; idx++)
        {
    #if 0
            status =
                OSA_queGet(&pObj->outBitBufQue,
                           (Int32 *) (&pBitBufList->bufs[idx]), OSA_TIMEOUT_NONE);
    #else
    		status =  OSA_queGet(&pObj->outBitBufQue,
    					 (Int32 *) (&pBitBufList->bufs[idx]), OSA_TIMEOUT_FOREVER);
    
    #endif
            if (status != OSA_SOK)
                break;
    	    curTime = OSA_getCurTimeInMsec();
            pBitBufList->bufs[idx]->reserved[1] = curTime;
        }
    
        pBitBufList->numBufs = idx;
        pObj->stats.numGetBufCalls++;
        pObj->stats.lastGetBufTime = curTime;
        return IPC_BITS_IN_LINK_S_SUCCESS;
    }
    
    static
    Int32 IpcBitsInLink_putEmptyBitBufs(IpcBitsInLink_Obj * pObj,
                                        Bitstream_BufList * pBitBufList)
    {
        UInt32 bufId;
        Bitstream_Buf *pBitBuf;
        Int32 status;
        SystemIpcBits_ListElem *pListElem = NULL;
        UInt32 curTime;
    
    #ifdef SYSTEM_DEBUG_IPC_RT
        OSA_printf(" %d: IPC_BITS_IN   : Releasing %d bitbufs !!!\n",
                   OSA_getCurTimeInMsec(), pBitBufList->numBitBufs);
    #endif
        curTime = OSA_getCurTimeInMsec();
        if (pBitBufList->numBufs)
        {
            OSA_assert(pBitBufList->numBufs <= VIDBITSTREAM_MAX_BITSTREAM_BUFS);
            pObj->stats.freeCount += pBitBufList->numBufs;
            for (bufId = 0; bufId < pBitBufList->numBufs; bufId++)
            {
                pBitBuf = pBitBufList->bufs[bufId];
                if (curTime > pBitBuf->reserved[0])
                {
                    pObj->stats.totalRoundTrip += (curTime - pBitBuf->reserved[0]);
                }
                if (curTime > pBitBuf->reserved[1])
                {
                    pObj->stats.totalAppCallbackTime += (curTime - pBitBuf->reserved[1]);
                }
                OSA_COMPILETIME_ASSERT(offsetof(SystemIpcBits_ListElem, bitBuf) ==
                                       0);
                pListElem = (SystemIpcBits_ListElem *) pBitBuf;
                OSA_assert(SharedRegion_getPtr(pListElem->srBufPtr) ==
                           pBitBuf->addr);
                SYSTEM_IPC_BITS_SET_BUFSTATE(pListElem->bufState,
                                             IPC_BITBUF_STATE_INQUE);
                status =
                    ListMP_putTail(pObj->listMPInHndl, (ListMP_Elem *) pListElem);
                OSA_assert(status == ListMP_S_SUCCESS);
            }
    
            if (pObj->createArgs.baseCreateParams.notifyPrevLink)
            {
                System_ipcSendNotify(pObj->createArgs.baseCreateParams.inQueParams.
                                     prevLinkId);
            }
        }
        pObj->stats.lastFreeBufTime = curTime;
        pObj->stats.numFreeBufCalls++;
        return IPC_BITS_IN_LINK_S_SUCCESS;
    }
    
    Int32 IpcBitsInLink_getLinkInfo(OSA_TskHndl * pTsk, System_LinkInfo * info)
    {
        IpcBitsInLink_Obj *pObj = (IpcBitsInLink_Obj *) pTsk->appData;
    
        memcpy(info, &pObj->inQueInfo, sizeof(*info));
    
        return IPC_BITS_IN_LINK_S_SUCCESS;
    }
    
    Int IpcBitsInLink_tskMain(struct OSA_TskHndl * pTsk, OSA_MsgHndl * pMsg,
                              Uint32 curState)
    {
        UInt32 cmd = OSA_msgGetCmd(pMsg);
        Bool ackMsg, done;
        Int status = IPC_BITS_IN_LINK_S_SUCCESS;
        IpcBitsInLink_Obj *pObj = (IpcBitsInLink_Obj *) pTsk->appData;
    
        OSA_printf("%s:Entered\n", __func__);
        if (cmd != SYSTEM_CMD_CREATE)
        {
            OSA_tskAckOrFreeMsg(pMsg, OSA_EFAIL);
            return status;
        }
    
        status = IpcBitsInLink_create(pObj, OSA_msgGetPrm(pMsg));
    
        OSA_tskAckOrFreeMsg(pMsg, status);
    
        if (status != OSA_SOK)
            return status;
    
        done = FALSE;
        ackMsg = FALSE;
    
        while (!done)
        {
            status = OSA_tskWaitMsg(pTsk, &pMsg);
            if (status != OSA_SOK)
                break;
    
            cmd = OSA_msgGetCmd(pMsg);
    
            switch (cmd)
            {
                case SYSTEM_CMD_DELETE:
                    done = TRUE;
                    ackMsg = TRUE;
                    break;
                case SYSTEM_CMD_NEW_DATA:
                    OSA_tskAckOrFreeMsg(pMsg, status);
                    if (pObj->createArgs.baseCreateParams.noNotifyMode)
                    {
                        OSA_assert(pObj->prd.numPendingCmd > 0);
                        pObj->prd.numPendingCmd--;
                    }
                    IpcBitsInLink_processBitBufs(pObj);
                    break;
    
                default:
                    OSA_tskAckOrFreeMsg(pMsg, status);
                    break;
            }
        }
    
        IpcBitsInLink_delete(pObj);
    
    #ifdef SYSTEM_DEBUG_IPC_BITS_IN
        OSA_printf(" %d: IPC_BITS_IN   : Delete Done !!!\n",
                   OSA_getCurTimeInMsec());
    #endif
    
        if (ackMsg && pMsg != NULL)
            OSA_tskAckOrFreeMsg(pMsg, status);
    
        return IPC_BITS_IN_LINK_S_SUCCESS;
    }
    
    Int32 IpcBitsInLink_init()
    {
        Int32 status;
        System_LinkObj linkObj;
        UInt32 ipcBitsInId;
        IpcBitsInLink_Obj *pObj;
        char tskName[32];
        UInt32 procId = System_getSelfProcId();
    
        OSA_COMPILETIME_ASSERT(offsetof(SystemIpcBits_ListElem, bitBuf) == 0);
        OSA_COMPILETIME_ASSERT(offsetof(Bitstream_Buf, reserved) == 0);
        OSA_COMPILETIME_ASSERT(sizeof(((Bitstream_Buf *) 0)->reserved) ==
                               sizeof(ListMP_Elem));
    
        for (ipcBitsInId = 0; ipcBitsInId < IPC_BITS_IN_LINK_OBJ_MAX; ipcBitsInId++)
        {
            pObj = &gIpcBitsInLink_obj[ipcBitsInId];
    
            memset(pObj, 0, sizeof(*pObj));
    
            pObj->tskId =
                SYSTEM_MAKE_LINK_ID(procId,
                                    SYSTEM_LINK_ID_IPC_BITS_IN_0) + ipcBitsInId;
    
            linkObj.pTsk = &pObj->tsk;
            linkObj.getLinkInfo = IpcBitsInLink_getLinkInfo;
    
            System_registerLink(pObj->tskId, &linkObj);
    
            OSA_SNPRINTF(tskName, "IPC_BITS_IN%d", ipcBitsInId);
    
            System_ipcRegisterNotifyCb(pObj->tskId, IpcBitsInLink_notifyCb);
    
            status = OSA_tskCreate(&pObj->tsk,
                                   IpcBitsInLink_tskMain,
                                   IPC_LINK_TSK_PRI,
                                   IPC_LINK_TSK_STACK_SIZE, 0, pObj);
            OSA_assert(status == OSA_SOK);
        }
    
        return status;
    }
    
    Int32 IpcBitsInLink_deInit()
    {
        UInt32 ipcBitsInId;
    
        for (ipcBitsInId = 0; ipcBitsInId < IPC_BITS_IN_LINK_OBJ_MAX; ipcBitsInId++)
        {
            OSA_tskDelete(&gIpcBitsInLink_obj[ipcBitsInId].tsk);
        }
        return IPC_BITS_IN_LINK_S_SUCCESS;
    }
    
    Int32 IpcBitsInLink_getFullVideoBitStreamBufs(UInt32 linkId,
                                                  Bitstream_BufList *bufList)
    {
        OSA_TskHndl * pTsk;
        IpcBitsInLink_Obj * pObj;
        Int status;
    
        OSA_assert(bufList != NULL);
        if (!((linkId  >= SYSTEM_HOST_LINK_ID_IPC_BITS_IN_0)
              &&
              (linkId  < (SYSTEM_HOST_LINK_ID_IPC_BITS_IN_0 + IPC_BITS_IN_LINK_OBJ_MAX))))
        {
            return IPC_BITS_IN_LINK_E_INVALIDLINKID;
        }
        pTsk = System_getLinkTskHndl(linkId);
        pObj = pTsk->appData;
        bufList->numBufs = 0;
        status = IpcBitsInLink_getFullBitBufs(pObj,bufList);
        return status;
    }
    
    
    Int32 IpcBitsInLink_putEmptyVideoBitStreamBufs(UInt32 linkId,
                                                   Bitstream_BufList *bufList)
    {
        OSA_TskHndl * pTsk;
        IpcBitsInLink_Obj * pObj;
        Int status;
    
        OSA_assert(bufList != NULL);
        if (!((linkId  >= SYSTEM_HOST_LINK_ID_IPC_BITS_IN_0)
              &&
              (linkId  < (SYSTEM_HOST_LINK_ID_IPC_BITS_IN_0 + IPC_BITS_IN_LINK_OBJ_MAX))))
        {
            return IPC_BITS_IN_LINK_E_INVALIDLINKID;
        }
        pTsk = System_getLinkTskHndl(linkId);
        pObj = pTsk->appData;
        status = IpcBitsInLink_putEmptyBitBufs(pObj,bufList);
        return status;
    }
    

    Thx ~

    HB

  • As I mentioned you have to figure out where the ipcBitsInLink task is blocked. The change you have done will not work if you have more than one channel being encoded but I don't think that is the cause of the ipcBitsInLink thread not being scheduled.

    You can have a variable in IpcBitsInLink instance object which indicates current stage of code .Attached is example code

    diff --git a/mcfw/src_linux/links/ipcBitsIn/ipcBitsInLink_priv.h b/mcfw/src_linux/links/ipcBitsIn/ipcBitsInLink_priv.h
    index 74b7eea..69e756d 100755
    --- a/mcfw/src_linux/links/ipcBitsIn/ipcBitsInLink_priv.h
    +++ b/mcfw/src_linux/links/ipcBitsIn/ipcBitsInLink_priv.h
    @@ -94,6 +94,22 @@ typedef enum IpcBitsInLink_State {
         IPC_BITS_IN_LINK_STATE_ACTIVE
     } IpcBitsInLink_State;
    
    +typedef enum IpcBitsInLink_Stage {
    +    IPC_BITS_IN_LINK_STAGE_RESET                         = 0,
    +    IPC_BITS_IN_LINK_STAGE_WAITMSG                       = (1u << 0),
    +    IPC_BITS_IN_LINK_STAGE_DELETEMSG_PROCESS             = (1u << 1),
    +    IPC_BITS_IN_LINK_STAGE_STOPMSG_PROCESS               = (1u << 2),
    +    IPC_BITS_IN_LINK_STAGE_DEFAULTMSG_PROCESS            = (1u << 3),
    +    IPC_BITS_IN_LINK_STAGE_OSAMSG_ACK                    = (1u << 4),
    +    IPC_BITS_IN_LINK_STAGE_PROCESS_BITBUF_ENTRY          = (1u << 5),
    +    IPC_BITS_IN_LINK_STAGE_PROCESS_BITBUF_PROCESSLOOP    = (1u << 6),
    +    IPC_BITS_IN_LINK_STAGE_PROCESS_BITBUF_LISTMPGET      = (1u << 7),
    +    IPC_BITS_IN_LINK_STAGE_PROCESS_BITBUF_BITBUFGET      = (1u << 8),
    +    IPC_BITS_IN_LINK_STAGE_PROCESS_BITBUF_OUTBITBUFPUT   = (1u << 9),
    +    IPC_BITS_IN_LINK_STAGE_PROCESS_BITBUF_IN_APPCB       = (1u << 10),
    +
    +} IpcBitsInLink_Stage;
    +
    
     /**
      * @brief   Structures defining members for supporting timer based periodic
    @@ -131,6 +147,7 @@ typedef struct IpcBitsInLink_Obj {
         IpcBitsInLink_PeriodicObj prd;/**< Periodic processing member */
    
         volatile IpcBitsInLink_State state;
    +    UInt32 execStage; /**< Execution stage of IPCBITSIN LINK thread */
     } IpcBitsInLink_Obj;
    
     
     
     diff --git a/mcfw/src_linux/links/ipcBitsIn/ipcBitsInLink_tsk.c b/mcfw/src_linux/links/ipcBitsIn/ipcBitsInLink_tsk.c
    index a115401..a632e2a 100755
    --- a/mcfw/src_linux/links/ipcBitsIn/ipcBitsInLink_tsk.c
    +++ b/mcfw/src_linux/links/ipcBitsIn/ipcBitsInLink_tsk.c
    @@ -10,6 +10,11 @@
     #include <ti/syslink/utils/Memory.h>
     #include <ti/syslink/utils/Cache.h>
    
    +#define IPC_BITSINLINK_INIT_STAGE(stageVar) ((stageVar) = IPC_BITS_IN_LINK_STAGE_RESET)
    +#define IPC_BITSINLINK_SET_STAGE(stageVar,stage) (stageVar = (stageVar) | (stage))
    +#define IPC_BITSINLINK_RESET_STAGE(stageVar,stage) (stageVar = (stageVar) & ~(stage))
    +
    +
     IpcBitsInLink_Obj gIpcBitsInLink_obj[IPC_BITS_IN_LINK_OBJ_MAX];
    
     static
    @@ -51,9 +56,11 @@ Void *IpcBitsInLink_periodicTaskFxn(Void * prm)
                     UInt32 curTime = OSA_getCurTimeInMsec();
    
                     OSA_printf("IPC_BITSINLINK:!WARNING!.Commands not being processed by link."
    -                           "TimeSinceLastAlloc:%d,TimeSinceLastFree:%d",
    +                           "TimeSinceLastAlloc:%d,TimeSinceLastFree:%d."
    +                           "IPBITSINEXECSTATE:0x%x",
                                (curTime - pObj->stats.lastGetBufTime),
    -                           (curTime - pObj->stats.lastFreeBufTime));
    +                           (curTime - pObj->stats.lastFreeBufTime),
    +                           pObj->execStage);
                 }
             }
         }
    @@ -138,6 +145,7 @@ Int32 IpcBitsInLink_create(IpcBitsInLink_Obj * pObj,
             IpcBitsInLink_createPrdObj(pObj);
         }
         pObj->state = IPC_BITS_IN_LINK_STATE_ACTIVE;
    +    IPC_BITSINLINK_INIT_STAGE(pObj->execStage);
     #ifdef SYSTEM_DEBUG_IPC
         OSA_printf(" %d: IPC_BITS_IN   : Create Done !!!\n",
                    OSA_getCurTimeInMsec());
    @@ -185,7 +193,7 @@ Int32 IpcBitsInLink_delete(IpcBitsInLink_Obj * pObj)
         OSA_assert(status == OSA_SOK);
    
         OSA_queDelete(&pObj->outBitBufQue);
    -
    +    IPC_BITSINLINK_INIT_STAGE(pObj->execStage);
     #ifdef SYSTEM_DEBUG_IPC
         OSA_printf(" %d: IPC_BITS_IN   : Delete Done !!!\n",
                    OSA_getCurTimeInMsec());
    @@ -226,15 +234,22 @@ Int32 IpcBitsInLink_processBitBufs(IpcBitsInLink_Obj * pObj)
         Int32 status;
         UInt32 curTime;
    
    +    IPC_BITSINLINK_SET_STAGE(pObj->execStage,IPC_BITS_IN_LINK_STAGE_PROCESS_BITBUF_ENTRY);
         numBitBufs = 0;
         curTime = OSA_getCurTimeInMsec();
    +
    +    IPC_BITSINLINK_SET_STAGE(pObj->execStage,IPC_BITS_IN_LINK_STAGE_PROCESS_BITBUF_PROCESSLOOP);
         while (1)
         {
    +        IPC_BITSINLINK_SET_STAGE(pObj->execStage,IPC_BITS_IN_LINK_STAGE_PROCESS_BITBUF_LISTMPGET);
             pListElem = ListMP_getHead(pObj->listMPOutHndl);
    +        IPC_BITSINLINK_RESET_STAGE(pObj->execStage,IPC_BITS_IN_LINK_STAGE_PROCESS_BITBUF_LISTMPGET);
             if (pListElem == NULL)
                 break;
    
    +        IPC_BITSINLINK_SET_STAGE(pObj->execStage,IPC_BITS_IN_LINK_STAGE_PROCESS_BITBUF_BITBUFGET);
             IpcBitsInLink_getBitBuf(pObj, pListElem, &pBitBuf);
    +        IPC_BITSINLINK_RESET_STAGE(pObj->execStage,IPC_BITS_IN_LINK_STAGE_PROCESS_BITBUF_BITBUFGET);
             OSA_assert(SYSTEM_IPC_BITS_GET_BUFSTATE(pListElem->bufState)
                        == IPC_BITBUF_STATE_OUTQUE);
             SYSTEM_IPC_BITS_SET_BUFOWNERPROCID(pListElem->bufState);
    @@ -242,12 +257,15 @@ Int32 IpcBitsInLink_processBitBufs(IpcBitsInLink_Obj * pObj)
                                          IPC_BITBUF_STATE_DEQUEUED);
             pBitBuf->reserved[0] = curTime;
             pObj->stats.recvCount++;
    +        IPC_BITSINLINK_SET_STAGE(pObj->execStage,IPC_BITS_IN_LINK_STAGE_PROCESS_BITBUF_OUTBITBUFPUT);
             status =
                 OSA_quePut(&pObj->outBitBufQue, (Int32) pBitBuf, OSA_TIMEOUT_NONE);
    +        IPC_BITSINLINK_RESET_STAGE(pObj->execStage,IPC_BITS_IN_LINK_STAGE_PROCESS_BITBUF_OUTBITBUFPUT);
             OSA_assert(status == OSA_SOK);
    
             numBitBufs++;
         }
    +    IPC_BITSINLINK_RESET_STAGE(pObj->execStage,IPC_BITS_IN_LINK_STAGE_PROCESS_BITBUF_PROCESSLOOP);
    
     #ifdef SYSTEM_DEBUG_IPC_RT
         OSA_printf(" %d: IPC_BITS_IN   : Recevived %d bitbufs !!!\n",
    @@ -258,10 +276,12 @@ Int32 IpcBitsInLink_processBitBufs(IpcBitsInLink_Obj * pObj)
         {
             if (pObj->createArgs.cbFxn)
             {
    +            IPC_BITSINLINK_SET_STAGE(pObj->execStage,IPC_BITS_IN_LINK_STAGE_PROCESS_BITBUF_IN_APPCB);
                 pObj->createArgs.cbFxn(pObj->createArgs.cbCtx);
    +            IPC_BITSINLINK_RESET_STAGE(pObj->execStage,IPC_BITS_IN_LINK_STAGE_PROCESS_BITBUF_IN_APPCB);
             }
         }
    -
    +    IPC_BITSINLINK_RESET_STAGE(pObj->execStage,IPC_BITS_IN_LINK_STAGE_PROCESS_BITBUF_ENTRY);
         return IPC_BITS_IN_LINK_S_SUCCESS;
     }
    
    @@ -352,6 +372,13 @@ Int32 IpcBitsInLink_getLinkInfo(OSA_TskHndl * pTsk, System_LinkInfo * info)
         return IPC_BITS_IN_LINK_S_SUCCESS;
     }
    
    +static Void IpcBitsInLink_ackMsg(OSA_MsgHndl * pMsg,Int status,UInt32 execStage)
    +{
    +    IPC_BITSINLINK_SET_STAGE(execStage,IPC_BITS_IN_LINK_STAGE_OSAMSG_ACK);
    +    OSA_tskAckOrFreeMsg(pMsg,status);
    +    IPC_BITSINLINK_RESET_STAGE(execStage,IPC_BITS_IN_LINK_STAGE_OSAMSG_ACK);
    +}
    +
     Int IpcBitsInLink_tskMain(struct OSA_TskHndl * pTsk, OSA_MsgHndl * pMsg,
                               Uint32 curState)
     {
    @@ -369,13 +396,13 @@ Int IpcBitsInLink_tskMain(struct OSA_TskHndl * pTsk, OSA_MsgHndl * pMsg,
    
         if (cmd != SYSTEM_CMD_CREATE)
         {
    -        OSA_tskAckOrFreeMsg(pMsg, OSA_EFAIL);
    +        IpcBitsInLink_ackMsg(pMsg, OSA_EFAIL,pObj->execStage);
             return status;
         }
    
         status = IpcBitsInLink_create(pObj, OSA_msgGetPrm(pMsg));
    
    -    OSA_tskAckOrFreeMsg(pMsg, status);
    +    IpcBitsInLink_ackMsg(pMsg, status,pObj->execStage);
    
         if (status != OSA_SOK)
             return status;
    @@ -385,7 +412,9 @@ Int IpcBitsInLink_tskMain(struct OSA_TskHndl * pTsk, OSA_MsgHndl * pMsg,
    
         while (!done)
         {
    +        IPC_BITSINLINK_SET_STAGE(pObj->execStage,IPC_BITS_IN_LINK_STAGE_WAITMSG);
             status = OSA_tskWaitMsg(pTsk, &pMsg);
    +        IPC_BITSINLINK_RESET_STAGE(pObj->execStage,IPC_BITS_IN_LINK_STAGE_WAITMSG);
             if (status != OSA_SOK)
                 break;
    
    @@ -394,11 +423,12 @@ Int IpcBitsInLink_tskMain(struct OSA_TskHndl * pTsk, OSA_MsgHndl * pMsg,
             switch (cmd)
             {
                 case SYSTEM_CMD_DELETE:
    +                IPC_BITSINLINK_SET_STAGE(pObj->execStage,IPC_BITS_IN_LINK_STAGE_DELETEMSG_PROCESS);
                     done = TRUE;
                     ackMsg = TRUE;
                     break;
                 case SYSTEM_CMD_NEW_DATA:
    -                OSA_tskAckOrFreeMsg(pMsg, status);
    +                IpcBitsInLink_ackMsg(pMsg, status,pObj->execStage);
                     if (pObj->createArgs.baseCreateParams.noNotifyMode)
                     {
                         OSA_assert(pObj->prd.numPendingCmd > 0);
    @@ -407,17 +437,22 @@ Int IpcBitsInLink_tskMain(struct OSA_TskHndl * pTsk, OSA_MsgHndl * pMsg,
                     IpcBitsInLink_processBitBufs(pObj);
                     break;
                 case SYSTEM_CMD_STOP:
    +                IPC_BITSINLINK_SET_STAGE(pObj->execStage,IPC_BITS_IN_LINK_STAGE_STOPMSG_PROCESS);
                     IpcBitsInLink_stop(pObj);
    -                OSA_tskAckOrFreeMsg(pMsg, status);
    +                IPC_BITSINLINK_RESET_STAGE(pObj->execStage,IPC_BITS_IN_LINK_STAGE_STOPMSG_PROCESS);
    +                IpcBitsInLink_ackMsg(pMsg, status,pObj->execStage);
                     break;
    
                 default:
    -                OSA_tskAckOrFreeMsg(pMsg, status);
    +                IPC_BITSINLINK_SET_STAGE(pObj->execStage,IPC_BITS_IN_LINK_STAGE_DEFAULTMSG_PROCESS);
    +                IpcBitsInLink_ackMsg(pMsg, status,pObj->execStage);
    +                IPC_BITSINLINK_RESET_STAGE(pObj->execStage,IPC_BITS_IN_LINK_STAGE_DEFAULTMSG_PROCESS);
                     break;
             }
         }
    
         IpcBitsInLink_delete(pObj);
    +    IPC_BITSINLINK_RESET_STAGE(pObj->execStage,IPC_BITS_IN_LINK_STAGE_DELETEMSG_PROCESS);
    
     #ifdef SYSTEM_DEBUG_IPC_BITS_IN
         OSA_printf(" %d: IPC_BITS_IN   : Delete Done !!!\n",
    @@ -425,7 +460,7 @@ Int IpcBitsInLink_tskMain(struct OSA_TskHndl * pTsk, OSA_MsgHndl * pMsg,
     #endif
    
         if (ackMsg && pMsg != NULL)
    -        OSA_tskAckOrFreeMsg(pMsg, status);
    +        IpcBitsInLink_ackMsg(pMsg, status,pObj->execStage);
    
         return IPC_BITS_IN_LINK_S_SUCCESS;
     }

    If you have gdb running on target refer these stackoverflow  posts on how to get backtrace for a specific thread to determine where it is blocked

    http://stackoverflow.com/questions/6671330/get-programmatic-info-on-threads-using-gdb-and-pthreads

    http://stackoverflow.com/questions/4765158/printing-a-stack-trace-from-another-thread/4778874#4778874

    http://stackoverflow.com/questions/6402160/getting-a-backtrace-of-other-thread

    Answers to other questions you raised in emai

    Do all IPC links use same Gate between M3-VPSS/M3-VIDEO/A8/DSP in syslink?

    No . Refer /dvr_rdk/mcfw/src_linux/links/system/system_ipc_listMP.c ListMP creation code. Each IPC link uses separate gate for each ListMP instance. The issue has got nothing to do with IPC gates. Your application if causing the ipcBitsInLink thread to get blocked

    Is there any relationship between ListMP and MessageQ? Will one part affect another part?

    No. MessageQ uses its own instance of ListMP different from the ListMP instance used for IPC links.

    Syslink have latest 2.21 version. Current we use 2.20 (DVR_RDK 3.5). Can we upgrade syslink to 2.21 in DVR_RDK3.5? Do you think we need to update it?

    It is better you migrate since there are some memory leaks fixed in last syslink release. The issue you are seeing will not get resolved simply by migrating syslink version. Migrating syslink version is not trivial. You will have to migrate lot of dependent components like cgtools,ipc,bios,xdc etc.

     

  • Dear Badri,

    By applying your dvr_rdk_ipcbitsin_exectrack.patch, here is the log that indicate "ListMP_getHead" is blocked.

    We are not familiar with these dvr_rdk code.

    Could you plz help us to clarify and resolve there issues?!

    thx ~

    ...

    [host] IPC_BITSINLINK:!WARNING!.Commands not being processed by link.TimeSinceLastAlloc:2880080,TimeSinceLastFree:2880080.IPBITSINEXECSTATE:0xe0

    [host] IPC_BITSINLINK:!WARNING!.Commands not being processed by link.TimeSinceLastAlloc:546,TimeSinceLastFree:546.IPBITSINEXECSTATE:0xe0

    [host] IPC_BITSINLINK:!WARNING!.Commands not being processed by link.TimeSinceLastAlloc:675,TimeSinceLastFree:675.IPBITSINEXECSTATE:0xe0

    [host] IPC_BITSINLINK:!WARNING!.Commands not being processed by link.TimeSinceLastAlloc:562,TimeSinceLastFree:562.IPBITSINEXECSTATE:0xe0

    (repeat)

    ....

    My modified ipcBitsInLink_tsk.c:

    /*******************************************************************************
     *                                                                             *
     * Copyright (c) 2009 Texas Instruments Incorporated - http://www.ti.com/      *
     *                        ALL RIGHTS RESERVED                                  *
     *                                                                             *
     ******************************************************************************/
    #include <stddef.h>
    #include "ipcBitsInLink_priv.h"
    #include <ti/syslink/utils/IHeap.h>
    #include <ti/syslink/utils/Memory.h>
    #include <ti/syslink/utils/Cache.h>
    
    #if 1 // debug_code
    #define IPC_BITSINLINK_INIT_STAGE(stageVar) ((stageVar) = IPC_BITS_IN_LINK_STAGE_RESET)
    #define IPC_BITSINLINK_SET_STAGE(stageVar,stage) (stageVar = (stageVar) | (stage))
    #define IPC_BITSINLINK_RESET_STAGE(stageVar,stage) (stageVar = (stageVar) & ~(stage))
    #endif
    
    
    IpcBitsInLink_Obj gIpcBitsInLink_obj[IPC_BITS_IN_LINK_OBJ_MAX];
    
    static
    Int32 IpcBitsInLink_getFullBitBufs(IpcBitsInLink_Obj * pObj,
                                       Bitstream_BufList * pBitBufList);
    
    static
    Int32 IpcBitsInLink_putEmptyBitBufs(IpcBitsInLink_Obj * pObj,
                                        Bitstream_BufList * pBitBufList);
    
    Void IpcBitsInLink_notifyCb(OSA_TskHndl * pTsk)
    {
        OSA_tskSendMsg(pTsk, NULL, SYSTEM_CMD_NEW_DATA, NULL, 0);
    }
    
    Void *IpcBitsInLink_periodicTaskFxn(Void * prm)
    {
        IpcBitsInLink_Obj *pObj = (IpcBitsInLink_Obj *) prm;
        Int32 status;
    
        while (FALSE == pObj->prd.exitThread)
        {
            OSA_waitMsecs(IPC_BITS_IN_PROCESS_PERIOD_MS);
            if (pObj->prd.numPendingCmd < IPC_BITS_IN_MAX_PENDING_NEWDATA_CMDS)
            {
                pObj->prd.numPendingCmd++;
                status = System_sendLinkCmd(pObj->tskId, SYSTEM_CMD_NEW_DATA);
            }
            else
            {
                UInt32 curTime = OSA_getCurTimeInMsec();
    #if 1 // debug_code
                 OSA_printf("IPC_BITSINLINK:!WARNING!.Commands not being processed by link."
               "TimeSinceLastAlloc:%d,TimeSinceLastFree:%d."
               "IPBITSINEXECSTATE:0x%x\n",
                (curTime - pObj->stats.lastGetBufTime),
               (curTime - pObj->stats.lastFreeBufTime),
               pObj->execStage);
    #else
                OSA_printf("IPC_BITSINLINK:!WARNING!.Commands not being processed by link."
                           "TimeSinceLastAlloc:%d,TimeSinceLastFree:%d\n",
                           (curTime - pObj->stats.lastGetBufTime),
                           (curTime - pObj->stats.lastFreeBufTime));
    #endif
            }
        }
        return NULL;
    }
    
    static Void IpcBitsInLink_initStats(IpcBitsInLink_Obj * pObj)
    {
        memset(&pObj->stats, 0, sizeof(pObj->stats));
    }
    
    static
    Int32 IpcBitsInLink_createPrdObj(IpcBitsInLink_Obj * pObj)
    {
        pObj->prd.numPendingCmd = 0;
        pObj->prd.exitThread = FALSE;
        OSA_thrCreate(&pObj->prd.thrHandle,
                      IpcBitsInLink_periodicTaskFxn,
                      IPC_LINK_TSK_PRI, IPC_LINK_TSK_STACK_SIZE, pObj);
        return IPC_BITS_IN_LINK_S_SUCCESS;
    }
    
    static
    Int32 IpcBitsInLink_deletePrdObj(IpcBitsInLink_Obj * pObj)
    {
        pObj->prd.exitThread = TRUE;
        OSA_thrDelete(&pObj->prd.thrHandle);
        pObj->prd.numPendingCmd = 0;
        return IPC_BITS_IN_LINK_S_SUCCESS;
    }
    
    Int32 IpcBitsInLink_create(IpcBitsInLink_Obj * pObj,
                               IpcBitsInLinkHLOS_CreateParams * pPrm)
    {
        Int32 status;
        System_LinkInQueParams *pInQueParams;
    
    #ifdef SYSTEM_DEBUG_IPC
        OSA_printf(" %d: IPC_BITS_IN   : Create in progress !!!\n",
                   OSA_getCurTimeInMsec());
    #endif
        memcpy(&pObj->createArgs, pPrm, sizeof(pObj->createArgs));
    
        OSA_printf(" %d: IPC_BITS_IN   : ListMPOpen start !!!\n",
                   OSA_getCurTimeInMsec());
        status =
            System_ipcListMPOpen(pObj->createArgs.baseCreateParams.inQueParams.
                                 prevLinkId, &pObj->listMPOutHndl,
                                 &pObj->listMPInHndl);
        OSA_assert(status == OSA_SOK);
        OSA_assert(pObj->listMPInHndl != NULL);
    
        OSA_printf(" %d: IPC_BITS_IN   : ListMPOpen done !!!\n",
                   OSA_getCurTimeInMsec());
    
        while(!ListMP_empty(pObj->listMPInHndl))
        {
            Ptr listElem =
            ListMP_getHead(pObj->listMPInHndl);
            if (listElem != NULL)
            {
                IPCBITSINLINK_INFO_LOG(pObj->tskId,
                                       "InList not empty!!!"
                                       "Stale entry:[%p]",
                                       listElem);
            }
        }
    
        status = OSA_queCreate(&pObj->outBitBufQue, SYSTEM_IPC_BITS_MAX_LIST_ELEM);
        OSA_assert(status == OSA_SOK);
    
        pInQueParams = &pObj->createArgs.baseCreateParams.inQueParams;
    
        status = System_linkGetInfo(pInQueParams->prevLinkId, &pObj->inQueInfo);
        OSA_assert(status == OSA_SOK);
        OSA_printf(" %d: IPC_BITS_IN   : System_linkGetInfo done !!!\n",
                   OSA_getCurTimeInMsec());
    
        IpcBitsInLink_initStats(pObj);
        if (pObj->createArgs.baseCreateParams.noNotifyMode)
        {
            IpcBitsInLink_createPrdObj(pObj);
        }
    
    #if 1 // debug_code
    	pObj->state = IPC_BITS_IN_LINK_STATE_ACTIVE;
    	IPC_BITSINLINK_INIT_STAGE(pObj->execStage);
    #endif	
    
    #ifdef SYSTEM_DEBUG_IPC
        OSA_printf(" %d: IPC_BITS_IN   : Create Done pObj->execStage(0x%x)!!!\n",
                   OSA_getCurTimeInMsec(),pObj->execStage);
    #endif
    
        return IPC_BITS_IN_LINK_S_SUCCESS;
    }
    
    #if 1 // debug_code
    static
    Int32 IpcBitsInLink_stop(IpcBitsInLink_Obj * pObj)
    {
        pObj->state = IPC_BITS_IN_LINK_STATE_INACTIVE;
    #ifdef SYSTEM_DEBUG_IPC
        OSA_printf(" %d: IPC_BITS_IN   : Stop Done !!!\n",
                   OSA_getCurTimeInMsec());
    #endif
        return IPC_BITS_IN_LINK_S_SUCCESS;
    }
    
    #endif
    
    Int32 IpcBitsInLink_delete(IpcBitsInLink_Obj * pObj)
    {
        Int32 status;
    
        if (pObj->createArgs.baseCreateParams.noNotifyMode)
        {
            IpcBitsInLink_deletePrdObj(pObj);
        }
        IPCBITSINLINK_INFO_LOG(pObj->tskId,
                               "RECV:%d\tFREE:%d,DROPPED:%d,AVGLATENCY:%d,AVG_APP_CB_TIME:%d\n",
                               pObj->stats.recvCount,
                               pObj->stats.freeCount,
                               pObj->stats.droppedCount,
                        OSA_DIV(pObj->stats.totalRoundTrip ,
                                pObj->stats.freeCount),
                        OSA_DIV(pObj->stats.totalAppCallbackTime,
                                pObj->stats.numFreeBufCalls));
    #ifdef SYSTEM_DEBUG_IPC
        OSA_printf(" %d: IPC_BITS_IN   : Delete in progress !!!\n",
                   OSA_getCurTimeInMsec());
    #endif
    
        status = System_ipcListMPClose(&pObj->listMPOutHndl, &pObj->listMPInHndl);
        OSA_assert(status == OSA_SOK);
    
        OSA_queDelete(&pObj->outBitBufQue);
    
    #if 1// debug_code
    	IPC_BITSINLINK_INIT_STAGE(pObj->execStage);
    #endif
    
    #ifdef SYSTEM_DEBUG_IPC
        OSA_printf(" %d: IPC_BITS_IN   : Delete Done !!!\n",
                   OSA_getCurTimeInMsec());
    #endif
    
        return IPC_BITS_IN_LINK_S_SUCCESS;
    }
    
    static Int32 IpcBitsInLink_getBitBuf(IpcBitsInLink_Obj * pObj,
                                         SystemIpcBits_ListElem * pListElem,
                                         Bitstream_Buf ** pBitBufPtr)
    {
        OSA_assert(pListElem != NULL);
        /* No cache ops done since pListElem is allocated from non-cached memory */
        OSA_assert(SharedRegion_isCacheEnabled(SharedRegion_getId(pListElem)) ==
                   FALSE);
        pListElem->bitBuf.addr = SharedRegion_getPtr(pListElem->srBufPtr);
        if (pListElem->bitBuf.fillLength)
        {
            Cache_inv(pListElem->bitBuf.addr,
                      pListElem->bitBuf.fillLength, Cache_Type_ALL, TRUE);
        }
        if(pListElem->bitBuf.mvDataFilledSize)
    	{
            Cache_inv(pListElem->bitBuf.addr + pListElem->bitBuf.mvDataOffset,
                      pListElem->bitBuf.mvDataFilledSize, Cache_Type_ALL, TRUE);	
    	}
        
        *pBitBufPtr = &pListElem->bitBuf;
        return IPC_BITS_IN_LINK_S_SUCCESS;
    }
    
    Int32 IpcBitsInLink_processBitBufs(IpcBitsInLink_Obj * pObj)
    {
        Bitstream_Buf *pBitBuf;
        SystemIpcBits_ListElem *pListElem;
        UInt32 numBitBufs;
        Int32 status;
        UInt32 curTime;
    #if 1//def debug_code	
    	UInt32 t1,t2;//debug code
    #endif	
    
    #if 1 //debug_code
    	IPC_BITSINLINK_SET_STAGE(pObj->execStage,IPC_BITS_IN_LINK_STAGE_PROCESS_BITBUF_ENTRY);
    #endif
    
        numBitBufs = 0;
        curTime = OSA_getCurTimeInMsec();
    #if 1// debug_code
    	IPC_BITSINLINK_SET_STAGE(pObj->execStage,IPC_BITS_IN_LINK_STAGE_PROCESS_BITBUF_PROCESSLOOP);
    #endif
        while (1)
        {
    #if 1//def debug_code  
        	t1=OSA_getCurTimeInMsec();//debug code
    #endif    	
    #if 1 // debug_code
    		IPC_BITSINLINK_SET_STAGE(pObj->execStage,IPC_BITS_IN_LINK_STAGE_PROCESS_BITBUF_LISTMPGET);
    #endif
            pListElem = ListMP_getHead(pObj->listMPOutHndl);
    #if 1 // debug_code
    		IPC_BITSINLINK_RESET_STAGE(pObj->execStage,IPC_BITS_IN_LINK_STAGE_PROCESS_BITBUF_LISTMPGET);
    #endif
    
            if (pListElem == NULL)
                break;
    #if 1 // debug_code
    		IPC_BITSINLINK_SET_STAGE(pObj->execStage,IPC_BITS_IN_LINK_STAGE_PROCESS_BITBUF_BITBUFGET);
    #endif
    		
            IpcBitsInLink_getBitBuf(pObj, pListElem, &pBitBuf);	
    #if 1 // debug_code
    		IPC_BITSINLINK_RESET_STAGE(pObj->execStage,IPC_BITS_IN_LINK_STAGE_PROCESS_BITBUF_BITBUFGET);
    #endif
    
    #if 1//def debug_code	
        	t2=OSA_getCurTimeInMsec();
    		
    		if((t2-t1)>16)//debug code
    			OSA_Log(MCFW_LEVEL_LOG,"%s,id:%x,Diff:%d,Data from M3 to A8 too slow \n",__FUNCTION__,pObj->tskId,t2-t1);
    #endif		
            OSA_assert(SYSTEM_IPC_BITS_GET_BUFSTATE(pListElem->bufState)
                       == IPC_BITBUF_STATE_OUTQUE);
            SYSTEM_IPC_BITS_SET_BUFOWNERPROCID(pListElem->bufState);
            SYSTEM_IPC_BITS_SET_BUFSTATE(pListElem->bufState,
                                         IPC_BITBUF_STATE_DEQUEUED);
            pBitBuf->reserved[0] = curTime;
            pObj->stats.recvCount++;
    #if 1 // debug_code
    		IPC_BITSINLINK_SET_STAGE(pObj->execStage,IPC_BITS_IN_LINK_STAGE_PROCESS_BITBUF_OUTBITBUFPUT);
    #endif		
            status =
                OSA_quePut(&pObj->outBitBufQue, (Int32) pBitBuf, OSA_TIMEOUT_NONE);
    #if 1 // debug_code
    		IPC_BITSINLINK_RESET_STAGE(pObj->execStage,IPC_BITS_IN_LINK_STAGE_PROCESS_BITBUF_OUTBITBUFPUT);
    #endif
    
            OSA_assert(status == OSA_SOK);
    
            numBitBufs++;
        }
    
    #if 1 // debug_code
    	IPC_BITSINLINK_RESET_STAGE(pObj->execStage,IPC_BITS_IN_LINK_STAGE_PROCESS_BITBUF_PROCESSLOOP);
    #endif
    
    #ifdef SYSTEM_DEBUG_IPC_RT
        OSA_printf(" %d: IPC_BITS_IN   : Recevived %d bitbufs !!!\n",
                   OSA_getCurTimeInMsec(), numBitBufs);
    #endif
    
        if (numBitBufs)
        {
            if (pObj->createArgs.cbFxn)
            {
    #if 1 // debug_code
    			IPC_BITSINLINK_SET_STAGE(pObj->execStage,IPC_BITS_IN_LINK_STAGE_PROCESS_BITBUF_IN_APPCB);
    #endif
                pObj->createArgs.cbFxn(pObj->createArgs.cbCtx);
    #if 1 // debug_code
    			IPC_BITSINLINK_RESET_STAGE(pObj->execStage,IPC_BITS_IN_LINK_STAGE_PROCESS_BITBUF_IN_APPCB);
    #endif
    
            }
        }
    #if 1 // debug_code
    	IPC_BITSINLINK_RESET_STAGE(pObj->execStage,IPC_BITS_IN_LINK_STAGE_PROCESS_BITBUF_ENTRY);
    #endif
    
        return IPC_BITS_IN_LINK_S_SUCCESS;
    }
    
    static
    Int32 IpcBitsInLink_getFullBitBufs(IpcBitsInLink_Obj * pObj,
                                       Bitstream_BufList * pBitBufList)
    {
        UInt32 idx;
        Int32 status;
        UInt32 curTime;
    #if 1
    	UInt32 bufNum=1;
    #else
    	UInt32 bufNum=VIDBITSTREAM_MAX_BITSTREAM_BUFS;
    #endif
        curTime = OSA_getCurTimeInMsec();
    
        for (idx = 0; idx < bufNum; idx++)
        {
    #if 0
            status =
                OSA_queGet(&pObj->outBitBufQue,
                           (Int32 *) (&pBitBufList->bufs[idx]), OSA_TIMEOUT_NONE);
    #else
    		status =  OSA_queGet(&pObj->outBitBufQue,
    					 (Int32 *) (&pBitBufList->bufs[idx]), OSA_TIMEOUT_FOREVER);
    
    #endif
            if (status != OSA_SOK)
                break;
    	    curTime = OSA_getCurTimeInMsec();
            pBitBufList->bufs[idx]->reserved[1] = curTime;
        }
    
        pBitBufList->numBufs = idx;
        pObj->stats.numGetBufCalls++;
        pObj->stats.lastGetBufTime = curTime;
        return IPC_BITS_IN_LINK_S_SUCCESS;
    }
    
    static
    Int32 IpcBitsInLink_putEmptyBitBufs(IpcBitsInLink_Obj * pObj,
                                        Bitstream_BufList * pBitBufList)
    {
        UInt32 bufId;
        Bitstream_Buf *pBitBuf;
        Int32 status;
        SystemIpcBits_ListElem *pListElem = NULL;
        UInt32 curTime;
    
    #ifdef SYSTEM_DEBUG_IPC_RT
        OSA_printf(" %d: IPC_BITS_IN   : Releasing %d bitbufs !!!\n",
                   OSA_getCurTimeInMsec(), pBitBufList->numBitBufs);
    #endif
        curTime = OSA_getCurTimeInMsec();
        if (pBitBufList->numBufs)
        {
            OSA_assert(pBitBufList->numBufs <= VIDBITSTREAM_MAX_BITSTREAM_BUFS);
            pObj->stats.freeCount += pBitBufList->numBufs;
            for (bufId = 0; bufId < pBitBufList->numBufs; bufId++)
            {
                pBitBuf = pBitBufList->bufs[bufId];
                if (curTime > pBitBuf->reserved[0])
                {
                    pObj->stats.totalRoundTrip += (curTime - pBitBuf->reserved[0]);
                }
                if (curTime > pBitBuf->reserved[1])
                {
                    pObj->stats.totalAppCallbackTime += (curTime - pBitBuf->reserved[1]);
                }
                OSA_COMPILETIME_ASSERT(offsetof(SystemIpcBits_ListElem, bitBuf) ==
                                       0);
                pListElem = (SystemIpcBits_ListElem *) pBitBuf;
                OSA_assert(SharedRegion_getPtr(pListElem->srBufPtr) ==
                           pBitBuf->addr);
                SYSTEM_IPC_BITS_SET_BUFSTATE(pListElem->bufState,
                                             IPC_BITBUF_STATE_INQUE);
                status =
                    ListMP_putTail(pObj->listMPInHndl, (ListMP_Elem *) pListElem);
                OSA_assert(status == ListMP_S_SUCCESS);
            }
    
            if (pObj->createArgs.baseCreateParams.notifyPrevLink)
            {
                System_ipcSendNotify(pObj->createArgs.baseCreateParams.inQueParams.
                                     prevLinkId);
            }
        }
        pObj->stats.lastFreeBufTime = curTime;
        pObj->stats.numFreeBufCalls++;
        return IPC_BITS_IN_LINK_S_SUCCESS;
    }
    
    Int32 IpcBitsInLink_getLinkInfo(OSA_TskHndl * pTsk, System_LinkInfo * info)
    {
        IpcBitsInLink_Obj *pObj = (IpcBitsInLink_Obj *) pTsk->appData;
    
        memcpy(info, &pObj->inQueInfo, sizeof(*info));
    
        return IPC_BITS_IN_LINK_S_SUCCESS;
    }
    
    #if 1 // debug_code
    static Void IpcBitsInLink_ackMsg(OSA_MsgHndl * pMsg,Int status,UInt32 execStage)
    {
        IPC_BITSINLINK_SET_STAGE(execStage,IPC_BITS_IN_LINK_STAGE_OSAMSG_ACK);
        OSA_tskAckOrFreeMsg(pMsg,status);
        IPC_BITSINLINK_RESET_STAGE(execStage,IPC_BITS_IN_LINK_STAGE_OSAMSG_ACK);
    }
    #endif
    
    Int IpcBitsInLink_tskMain(struct OSA_TskHndl * pTsk, OSA_MsgHndl * pMsg,
                              Uint32 curState)
    {
        UInt32 cmd = OSA_msgGetCmd(pMsg);
        Bool ackMsg, done;
        Int status = IPC_BITS_IN_LINK_S_SUCCESS;
        IpcBitsInLink_Obj *pObj = (IpcBitsInLink_Obj *) pTsk->appData;
    
        OSA_printf("%s:Entered\n", __func__);
        if (cmd != SYSTEM_CMD_CREATE)
        {
    #if 1 // debug_code
    		IpcBitsInLink_ackMsg(pMsg, OSA_EFAIL,pObj->execStage);
    #else
            OSA_tskAckOrFreeMsg(pMsg, OSA_EFAIL);
    #endif
            return status;
        }
    
        status = IpcBitsInLink_create(pObj, OSA_msgGetPrm(pMsg));
    
    #if 1 // debug_code
    	IpcBitsInLink_ackMsg(pMsg, status,pObj->execStage);
    #else
        OSA_tskAckOrFreeMsg(pMsg, status);
    #endif
    
        if (status != OSA_SOK)
            return status;
    
        done = FALSE;
        ackMsg = FALSE;
    
        while (!done)
        {
    #if 1 // debug_code
    		 IPC_BITSINLINK_SET_STAGE(pObj->execStage,IPC_BITS_IN_LINK_STAGE_WAITMSG);
    #endif
            status = OSA_tskWaitMsg(pTsk, &pMsg);
    #if 1 // debug_code
    		 IPC_BITSINLINK_RESET_STAGE(pObj->execStage,IPC_BITS_IN_LINK_STAGE_WAITMSG);
    #endif
    
            if (status != OSA_SOK)
                break;
    
            cmd = OSA_msgGetCmd(pMsg);
    
            switch (cmd)
            {
                case SYSTEM_CMD_DELETE:
    #if 1 // debug_code
    				IPC_BITSINLINK_SET_STAGE(pObj->execStage,IPC_BITS_IN_LINK_STAGE_DELETEMSG_PROCESS);
    #endif
                    done = TRUE;
                    ackMsg = TRUE;
                    break;
                case SYSTEM_CMD_NEW_DATA:
    #if 1 // debug_code
    				IpcBitsInLink_ackMsg(pMsg, status,pObj->execStage);
    #else
                    OSA_tskAckOrFreeMsg(pMsg, status);
    #endif
                    if (pObj->createArgs.baseCreateParams.noNotifyMode)
                    {
                        OSA_assert(pObj->prd.numPendingCmd > 0);
                        pObj->prd.numPendingCmd--;
                    }
                    IpcBitsInLink_processBitBufs(pObj);
                    break;
    #if 1 // debug_code
    			case SYSTEM_CMD_STOP:
                    IPC_BITSINLINK_SET_STAGE(pObj->execStage,IPC_BITS_IN_LINK_STAGE_STOPMSG_PROCESS);
                    IpcBitsInLink_stop(pObj);
                    IPC_BITSINLINK_RESET_STAGE(pObj->execStage,IPC_BITS_IN_LINK_STAGE_STOPMSG_PROCESS);
                    IpcBitsInLink_ackMsg(pMsg, status,pObj->execStage);
                     break;
    #endif
    
    
                default:
    #if 1 // debug_code
    				IPC_BITSINLINK_SET_STAGE(pObj->execStage,IPC_BITS_IN_LINK_STAGE_DEFAULTMSG_PROCESS);
    				IpcBitsInLink_ackMsg(pMsg, status,pObj->execStage);
    				IPC_BITSINLINK_RESET_STAGE(pObj->execStage,IPC_BITS_IN_LINK_STAGE_DEFAULTMSG_PROCESS);
    #else
                    OSA_tskAckOrFreeMsg(pMsg, status);
    #endif
                    break;
            }
        }
    
        IpcBitsInLink_delete(pObj);
    #if 1 // debug_code
    	IPC_BITSINLINK_RESET_STAGE(pObj->execStage,IPC_BITS_IN_LINK_STAGE_DELETEMSG_PROCESS);
    #endif
    
    #ifdef SYSTEM_DEBUG_IPC_BITS_IN
        OSA_printf(" %d: IPC_BITS_IN   : Delete Done !!!\n",
                   OSA_getCurTimeInMsec());
    #endif
    
        if (ackMsg && pMsg != NULL)
        {
    #if 1 // debug_code
    		IpcBitsInLink_ackMsg(pMsg, status,pObj->execStage);
    #else
            OSA_tskAckOrFreeMsg(pMsg, status);
    #endif
        }
    
        return IPC_BITS_IN_LINK_S_SUCCESS;
    }
    
    Int32 IpcBitsInLink_init()
    {
        Int32 status;
        System_LinkObj linkObj;
        UInt32 ipcBitsInId;
        IpcBitsInLink_Obj *pObj;
        char tskName[32];
        UInt32 procId = System_getSelfProcId();
    
        OSA_COMPILETIME_ASSERT(offsetof(SystemIpcBits_ListElem, bitBuf) == 0);
        OSA_COMPILETIME_ASSERT(offsetof(Bitstream_Buf, reserved) == 0);
        OSA_COMPILETIME_ASSERT(sizeof(((Bitstream_Buf *) 0)->reserved) ==
                               sizeof(ListMP_Elem));
    
        for (ipcBitsInId = 0; ipcBitsInId < IPC_BITS_IN_LINK_OBJ_MAX; ipcBitsInId++)
        {
            pObj = &gIpcBitsInLink_obj[ipcBitsInId];
    
            memset(pObj, 0, sizeof(*pObj));
    
            pObj->tskId =
                SYSTEM_MAKE_LINK_ID(procId,
                                    SYSTEM_LINK_ID_IPC_BITS_IN_0) + ipcBitsInId;
    
            linkObj.pTsk = &pObj->tsk;
            linkObj.getLinkInfo = IpcBitsInLink_getLinkInfo;
    
            System_registerLink(pObj->tskId, &linkObj);
    
            OSA_SNPRINTF(tskName, "IPC_BITS_IN%d", ipcBitsInId);
    
            System_ipcRegisterNotifyCb(pObj->tskId, IpcBitsInLink_notifyCb);
    
            status = OSA_tskCreate(&pObj->tsk,
                                   IpcBitsInLink_tskMain,
                                   IPC_LINK_TSK_PRI,
                                   IPC_LINK_TSK_STACK_SIZE, 0, pObj);
            OSA_assert(status == OSA_SOK);
        }
    
        return status;
    }
    
    Int32 IpcBitsInLink_deInit()
    {
        UInt32 ipcBitsInId;
    
        for (ipcBitsInId = 0; ipcBitsInId < IPC_BITS_IN_LINK_OBJ_MAX; ipcBitsInId++)
        {
            OSA_tskDelete(&gIpcBitsInLink_obj[ipcBitsInId].tsk);
        }
        return IPC_BITS_IN_LINK_S_SUCCESS;
    }
    
    Int32 IpcBitsInLink_getFullVideoBitStreamBufs(UInt32 linkId,
                                                  Bitstream_BufList *bufList)
    {
        OSA_TskHndl * pTsk;
        IpcBitsInLink_Obj * pObj;
        Int status;
    
        OSA_assert(bufList != NULL);
        if (!((linkId  >= SYSTEM_HOST_LINK_ID_IPC_BITS_IN_0)
              &&
              (linkId  < (SYSTEM_HOST_LINK_ID_IPC_BITS_IN_0 + IPC_BITS_IN_LINK_OBJ_MAX))))
        {
            return IPC_BITS_IN_LINK_E_INVALIDLINKID;
        }
        pTsk = System_getLinkTskHndl(linkId);
        pObj = pTsk->appData;
        bufList->numBufs = 0;
        status = IpcBitsInLink_getFullBitBufs(pObj,bufList);
        return status;
    }
    
    
    Int32 IpcBitsInLink_putEmptyVideoBitStreamBufs(UInt32 linkId,
                                                   Bitstream_BufList *bufList)
    {
        OSA_TskHndl * pTsk;
        IpcBitsInLink_Obj * pObj;
        Int status;
    
        OSA_assert(bufList != NULL);
        if (!((linkId  >= SYSTEM_HOST_LINK_ID_IPC_BITS_IN_0)
              &&
              (linkId  < (SYSTEM_HOST_LINK_ID_IPC_BITS_IN_0 + IPC_BITS_IN_LINK_OBJ_MAX))))
        {
            return IPC_BITS_IN_LINK_E_INVALIDLINKID;
        }
        pTsk = System_getLinkTskHndl(linkId);
        pObj = pTsk->appData;
        status = IpcBitsInLink_putEmptyBitBufs(pObj,bufList);
        return status;
    }
    

    HB

  • ListMP_get is a non-blocking call. Control cant be inside ListMP_get. Add additional debug code and confirm ListMP_get  is invoked and didn't return for more than 500 ms or if control is not exiting the surrounding while loop. If control is really stuck inside ListMP_get it can only indicate ListMP_get is not able to acquire remote Gate which means remote ipc link on M3 acquired gate and crashed. THis is unlikely so first confirm where control is actually stuck.

  • Dear Badri,

    If we set kernel configuration "CONFIG_PREEMPT=y",

    will this setting cause the stuck of ListMP_get?

    HB

  • Have You found a solution for this issue ?
    I have a similar problem:
    e2e.ti.com/.../1378158