示例#1
0
/*
 *  ======== Notify_disable ========
 */
UInt Notify_disable(UInt16 procId, UInt16 lineId)
{
    UInt key;
    UInt modKey;
    UInt16 clusterId = ti_sdo_utils_MultiProc_getClusterId(procId);
    ti_sdo_ipc_Notify_Object *obj;

    Assert_isTrue(procId < ti_sdo_utils_MultiProc_numProcessors &&
                  lineId < ti_sdo_ipc_Notify_numLines,
                  ti_sdo_ipc_Notify_A_invArgument);

    obj = (ti_sdo_ipc_Notify_Object *)
          Notify_module->notifyHandles[clusterId][lineId];

    Assert_isTrue(obj != NULL, ti_sdo_ipc_Notify_A_notRegistered);

    /* Nesting value and enable state have to be in sync */
    modKey = Gate_enterModule();

    obj->nesting++;
    if (obj->nesting == 1) {
        /* Disable receiving all events */
        if (procId != MultiProc_self()) {
            INotifyDriver_disable(obj->driverHandle);
        }
    }

    key = obj->nesting;

    Gate_leaveModule(modKey);

    return (key);
}
示例#2
0
/*
 *  ======== HeapMem_getStats ========
 */
Void HeapMem_getStats(HeapMem_Object *obj, Memory_Stats *stats)
{
    IArg key;
    HeapMem_Header *curHeader;

    stats->totalSize         = obj->head.size;
    stats->totalFreeSize     = 0;                   /* determined later */
    stats->largestFreeSize   = 0;                   /* determined later */

    key = Gate_enterModule();

    curHeader = obj->head.next;

    while (curHeader != NULL) {
        stats->totalFreeSize += curHeader->size;
        if (stats->largestFreeSize < curHeader->size) {
            stats->largestFreeSize = curHeader->size;
        }
        curHeader = curHeader->next;
    }

    Gate_leaveModule(key);

    return;
}
示例#3
0
/*
 *  ======== Notify_restore ========
 */
Void Notify_restore(UInt16 procId, UInt16 lineId, UInt key)
{
    UInt modKey;
    UInt16 clusterId = ti_sdo_utils_MultiProc_getClusterId(procId);
    ti_sdo_ipc_Notify_Object *obj;

    Assert_isTrue(procId < ti_sdo_utils_MultiProc_numProcessors &&
                  lineId < ti_sdo_ipc_Notify_numLines, ti_sdo_ipc_Notify_A_invArgument);

    obj = (ti_sdo_ipc_Notify_Object *)
          Notify_module->notifyHandles[clusterId][lineId];

    Assert_isTrue(obj != NULL, ti_sdo_ipc_Notify_A_notRegistered);
    Assert_isTrue(key == obj->nesting, ti_sdo_ipc_Notify_A_outOfOrderNesting);

    /* Nesting value and enable state have to be in sync */
    modKey = Gate_enterModule();

    obj->nesting--;
    if (obj->nesting == 0) {
        /* Enable receiving events */
        if (procId != MultiProc_self()) {
            INotifyDriver_enable(obj->driverHandle);
        }
    }

    Gate_leaveModule(modKey);
}
示例#4
0
/**
 * @name   DomxTunnelMgr_unRegisterHandle
 * @brief  UnResgiter a component handle
 * @param  hComponentHandle           : Handle to component to be unregistered
 * @return none
 */
Void DomxTunnelMgr_unRegisterHandle (OmxTypes_OMX_HANDLETYPE hComponentHandle)
{
  OMX_CONFIG_DOMXPROXYCOMPINFO sDomxProxyInfo;
  OMX_ERRORTYPE eError;
  Int nCompIdx;
  IArg key;

  DOMX_UTL_TRACE_FUNCTION_ENTRY_LEVEL1 ();
  nCompIdx = domxtmgr_get_component_registry_index (hComponentHandle);
  if (-1 == nCompIdx)
  {
    eError = OMX_GetConfig (hComponentHandle, (OMX_INDEXTYPE)
                            OMX_TI_IndexConfigGetDomxCompInfo, &sDomxProxyInfo);
    if (OMX_ErrorNone == eError)
    {
      nCompIdx =
        domxtmgr_get_component_registry_index (sDomxProxyInfo.hCompRealHandle);
      DOMX_UTL_TRACE_FUNCTION_ASSERT ((-1 != nCompIdx),
                                      "Component handle not found");
    }
    else
    {
      DOMX_UTL_TRACE_FUNCTION_ASSERT ((OMX_ErrorNone == eError),
                                      "OMX_GetConfig returned error");
    }
  }
  domxtmgr_delete_proxylite_connections (hComponentHandle);
  key = Gate_enterModule ();
  domxtmgr_unregister_component (nCompIdx);
  Gate_leaveModule (key);

  DOMX_UTL_TRACE_FUNCTION_EXIT_LEVEL1 (eError);

  return;
}
示例#5
0
/*
 *  ======== Notify_unregisterEventSingle ========
 */
Int Notify_unregisterEventSingle(UInt16 procId, UInt16 lineId, UInt32 eventId)
{
    UInt32  strippedEventId = (eventId & 0xFFFF);
    UInt16  clusterId = ti_sdo_utils_MultiProc_getClusterId(procId);
    Int     status;
    ti_sdo_ipc_Notify_Object *obj;
    UInt    modKey;

    Assert_isTrue(procId < ti_sdo_utils_MultiProc_numProcessors &&
                  lineId < ti_sdo_ipc_Notify_numLines, ti_sdo_ipc_Notify_A_invArgument);
    Assert_isTrue(strippedEventId < ti_sdo_ipc_Notify_numEvents,
                  ti_sdo_ipc_Notify_A_invArgument);
    Assert_isTrue(ISRESERVED(eventId), ti_sdo_ipc_Notify_A_reservedEvent);

    modKey = Gate_enterModule();

    obj = (ti_sdo_ipc_Notify_Object *)
          Notify_module->notifyHandles[clusterId][lineId];

    Assert_isTrue(obj != NULL, ti_sdo_ipc_Notify_A_notRegistered);

    if (obj->callbacks[strippedEventId].fnNotifyCbck) {
        if (procId != MultiProc_self()) {
            /*
             *  First, Tell the remote notify driver that the event is now
             *  unregistered
             */
            INotifyDriver_unregisterEvent(obj->driverHandle,
                                          strippedEventId);
        }

        /*
         *  No need to protect these modifications with the system gate because
         *  we shouldn't get preempted by Notify_exec after INotifyDriver_
         *  unregisterEvent.
         */
        obj->callbacks[strippedEventId].fnNotifyCbck = NULL;
        obj->callbacks[strippedEventId].cbckArg = NULL;

        status = Notify_S_SUCCESS;
    }
    else {
        /* No callback is registered. Fail. */
        status = Notify_E_FAIL;
    }

    Gate_leaveModule(modKey);

    return (status);
}
示例#6
0
/*
 *  ======== Notify_registerEventSingle ========
 */
Int Notify_registerEventSingle(UInt16                 procId,
                               UInt16                 lineId,
                               UInt32                 eventId,
                               Notify_FnNotifyCbck    fnNotifyCbck,
                               UArg                   cbckArg)
{
    UInt32        strippedEventId = (eventId & 0xFFFF);
    UInt16 clusterId = ti_sdo_utils_MultiProc_getClusterId(procId);
    UInt          modKey;
    Int           status;
    ti_sdo_ipc_Notify_Object *obj;

    Assert_isTrue(procId < ti_sdo_utils_MultiProc_numProcessors &&
                  lineId < ti_sdo_ipc_Notify_numLines, ti_sdo_ipc_Notify_A_invArgument);
    Assert_isTrue(strippedEventId < ti_sdo_ipc_Notify_numEvents,
                  ti_sdo_ipc_Notify_A_invArgument);
    Assert_isTrue(ISRESERVED(eventId), ti_sdo_ipc_Notify_A_reservedEvent);

    modKey = Gate_enterModule();

    obj = (ti_sdo_ipc_Notify_Object *)
          Notify_module->notifyHandles[clusterId][lineId];

    Assert_isTrue(obj != NULL, ti_sdo_ipc_Notify_A_notRegistered);

    if (obj->callbacks[strippedEventId].fnNotifyCbck) {
        /* A callback is already registered. Fail. */
        status = Notify_E_ALREADYEXISTS;
    }
    else {
        /*
         *  No callback is registered. Register it. There is no need to protect
         *  these modifications because the event isn't registered yet.
         */
        obj->callbacks[strippedEventId].fnNotifyCbck = (Fxn)fnNotifyCbck;
        obj->callbacks[strippedEventId].cbckArg = cbckArg;

        if (procId != MultiProc_self()) {
            /* Tell the remote notify driver that the event is now registered */
            INotifyDriver_registerEvent(obj->driverHandle, strippedEventId);
        }

        status = Notify_S_SUCCESS;
    }

    Gate_leaveModule(modKey);

    return (status);
}
示例#7
0
/**
 * @name domxtmgr_module_init
 * @brief DomxTunnelManager Module level init function
 * @param  component_name  : OMX Component name
 * @param  info            : Info entry to be populated
 * @param  eb              : Used to raise error 
 * @return none
 */
static Void domxtmgr_module_init ()
{
  IArg key;

  Log_print1 (Diags_ENTRY, "Entering %s (void)", (xdc_IArg) __FUNCTION__);

  key = Gate_enterModule ();

  DOMX_UTL_TRACE_FUNCTION_ASSERT
    ((DomxTunnelMgr_module->connectionInfoTbl.length == 
      DomxTunnelMgr_maxNumComponents), 
     "Table length != maxNumComponents");
  DomxTunnelMgr_module->numActiveComponents = 0;
  DomxTunnelMgr_module->initDone = TRUE;
  Gate_leaveModule (key);

  Log_print1 (Diags_EXIT, "Leaving %s retVal: void", (xdc_IArg) __FUNCTION__);
}
示例#8
0
/**
 * @name   DomxTunnelMgr_registerSkelInfo
 * @brief  Register a components skeleton info
 * @param  hComponentHandle           : Handle to component to register
 * @param  szCompName                 : Component name
 * @param  pRpcSkelHandle             : Pointer to RPC skel handle
 * @param  cComponentRcmSvrName       : Name of component rcm server name
 * @return none
 */
Void DomxTunnelMgr_registerSkelInfo (OmxTypes_OMX_HANDLETYPE hComponentHandle,
                                     Char *szCompName,
                                     OmxTypes_OMX_PTR pRpcSkelHandle,
                                     Char *cComponentRcmSvrName)
{
  DomxCore_componentCoreInfoEntry *entry;
  Error_Block ebObj;
  Error_Block *eb = &ebObj;
  Int nCompIdx = DOMX_INT_TUNNELMGR_INVALID;
  IArg key;

  DOMX_UTL_TRACE_FUNCTION_ENTRY_LEVEL1 ();

  Error_init (eb);
  if (FALSE == DomxTunnelMgr_module->initDone)
  {
    domxtmgr_module_init ();
  }
  key = Gate_enterModule ();
  domxtmgr_map_component_name2info (szCompName, &entry, eb);
  if (NULL != entry)
  {
    DOMX_UTL_TRACE_FUNCTION_ASSERT ((entry->coreId == DomxCore_localCoreId),
                                    "Entry coreID != localCoreID");
    nCompIdx = domxtmgr_get_component_registry_index (hComponentHandle);
    DOMX_UTL_TRACE_FUNCTION_ASSERT ((nCompIdx != DOMX_INT_TUNNELMGR_INVALID),
                                    "Invalid Comp index");
    domxtmgr_register_skelinfo (nCompIdx, pRpcSkelHandle, cComponentRcmSvrName);
  }
  Gate_leaveModule (key);
  /* TODO: Component should return error code */
  DOMX_UTL_TRACE_FUNCTION_ASSERT ((FALSE == Error_check (eb)),
                                  "DomxTunnelMgr_registerSkelInfo failed");

  DOMX_UTL_TRACE_FUNCTION_EXIT_LEVEL1 (OMX_ErrorNone);
}
示例#9
0
/** 
********************************************************************************
 *  @func     MEMCFG_ModuleDeInit
 *  @brief  This function performs de-initialization of shared regions and set the
 *          Module instance appropriately.
 *
 *  @param[in ]  None  : None
 * 
 *  @returns MEMCFG_MODSTAT_INITIALIZED 
 *           MEMCFG_MODSTAT_NOTINITIALIZED
********************************************************************************
*/
uint32_t MEMCFG_ModuleDeInit (void)
{
  IArg key;
  int32_t memcfg_retval;

  key = Gate_enterModule ();

  if (MEMCFG_MODSTAT_INITIALIZED == MEMCFG_module->uInitState)
  {
    memcfg_retval = memcfg_module_deinit_shared_region ();

    if (MEMCFG_S_SUCCESS == memcfg_retval)
    {
      MEMCFG_module->uInitState = MEMCFG_MODSTAT_NOTINITIALIZED;
    }

  }                             /* End of IF: if (MEMCFG_MODSTAT_NOTINITIALIZED 
                                   == uInitState) */

  Gate_leaveModule (key);

  return (MEMCFG_module->uInitState);

}                               /* MEMCFG_ModuleInit */
示例#10
0
/*
 *  ======== Notify_registerEvent ========
 */
Int Notify_registerEvent(UInt16                 procId,
                         UInt16                 lineId,
                         UInt32                 eventId,
                         Notify_FnNotifyCbck    fnNotifyCbck,
                         UArg                   cbckArg)
{
    UInt32               strippedEventId = (eventId & 0xFFFF);
    UInt16 clusterId =   ti_sdo_utils_MultiProc_getClusterId(procId);
    Int                  status;
    ti_sdo_ipc_Notify_Object        *obj;
    UInt                 modKey;
    List_Handle          eventList;
    ti_sdo_ipc_Notify_EventListener *listener;
    Bool                 listWasEmpty;
    Error_Block          eb;

    Assert_isTrue(procId < ti_sdo_utils_MultiProc_numProcessors &&
                  lineId < ti_sdo_ipc_Notify_numLines, ti_sdo_ipc_Notify_A_invArgument);
    Assert_isTrue(strippedEventId < ti_sdo_ipc_Notify_numEvents,
                  ti_sdo_ipc_Notify_A_invArgument);
    Assert_isTrue(ISRESERVED(eventId), ti_sdo_ipc_Notify_A_reservedEvent);

    Error_init(&eb);

    modKey = Gate_enterModule();

    obj = (ti_sdo_ipc_Notify_Object *)
          Notify_module->notifyHandles[clusterId][lineId];

    Assert_isTrue(obj != NULL, ti_sdo_ipc_Notify_A_notRegistered);

    /* Allocate a new EventListener */
    listener = Memory_alloc(ti_sdo_ipc_Notify_Object_heap(),
                            sizeof(ti_sdo_ipc_Notify_EventListener), 0, &eb);
    if (listener == NULL) {
        /* Listener memory allocation failed.  Leave module gate & return */
        Gate_leaveModule(modKey);

        return (Notify_E_MEMORY);
    }

    listener->callback.fnNotifyCbck = (Fxn)fnNotifyCbck;
    listener->callback.cbckArg = cbckArg;

    eventList = List_Object_get(obj->eventList, strippedEventId);

    /*
     *  Store whether the list was empty so we know whether to register the
     *  callback
     */
    listWasEmpty = List_empty(eventList);

    /*
     *  Need to atomically add to the list using the system gate because
     *  Notify_exec might preempt List_remove.  List_put is atomic.
     */
    List_put(eventList, (List_Elem *)listener);

    if (listWasEmpty) {
        /*
         *  Registering this event for the first time.  Need to register the
         *  callback function.
         */
        status = Notify_registerEventSingle(procId, lineId, eventId,
                                            Notify_execMany, (UArg)obj);

        /* Notify_registerEventSingle should always succeed */
        Assert_isTrue(status == Notify_S_SUCCESS,
                      ti_sdo_ipc_Notify_A_internal);
    }

    status = Notify_S_SUCCESS;

    Gate_leaveModule(modKey);

    return (status);
}
示例#11
0
/*
 *  ======== HeapMem_enter ========
 *  Enter the HeapMem module's gate.
 */
IArg HeapMem_enter()
{
    return (Gate_enterModule());
}
示例#12
0
/*
 *  ======== write8 =========
 *
 *  Odd serial numbers indicate a new record, even serial numbers indicate
 *  an "extension" to the previous record.  0 is a sentinal for no record,
 *  but only if it doesn't follow a -1 (0xffffffff).  If a serial number
 *  of 0 follows a serial number of 0xffffffff, it's an extension, otherwise
 *  it's a "no record".
 */
Void LoggerBuf_write8(LoggerBuf_Object *obj, Log_Event evt,
                      Types_ModuleId mid, IArg a1, IArg a2, IArg a3, IArg a4,
                      IArg a5, IArg a6, IArg a7, IArg a8)
{
    /* part1 */
    
    IArg key;
    Int adv;
    Int32 ser;
    LoggerBuf_Entry *e;

    /* Do nothing if the instance is disabled. */
    if (!obj->enabled) {
        return;
    }

    /* 
     * If event level filtering is enabled, and the event isn't a high enough
     * level, drop the record and return.
     */
    if (LoggerBuf_filterByLevel && 
        LoggerBuf_filterOutEvent(Log_getMask(evt))) {
        return;
    }
    
    /* 
     *  If all of the following are true:
     *   - A logger has been specified to route status events to
     *   - This is a status event
     *   - This logger is NOT the status logger
     * Pass the event to the status logger and return.
     *
     * Otherwise, continue to log the event.
     */
    if ((LoggerBuf_statusLogger != NULL) && 
        (Log_getMask(evt) & Diags_STATUS) &&
        (LoggerBuf_statusLogger != 
         xdc_runtime_LoggerBuf_Handle_to_xdc_runtime_ILogger(obj))) {
        ILogger_write8(LoggerBuf_statusLogger, evt, mid, a1, a2, a3, a4, a5,
                       a6, a7, a8);
        return;
    }

    key = Gate_enterModule();

    /*
     * Record new serial number even if the buffer is FULL.  We do this
     * because the buffer might become un-FULL at some later time, and
     * a reader (decoder) of the buffer needs to know if events have
     * been missed.
     */
    ser = obj->serial;
    obj->serial += 2;

    adv = obj->advance;
    if (adv == LoggerBuf_FULL) {
        goto leave;
    }

    e = obj->curEntry;
    if (e == obj->endEntry) {
        if (adv == LoggerBuf_WRAP) {
            obj->curEntry = obj->entryArr;
        }
        else {
            obj->advance = LoggerBuf_FULL;
        }
    }
    else {
        obj->curEntry = e + 1;
    }

    LoggerBuf_TimestampProxy_get64(&e->tstamp);

    e->serial = ser;
    e->evt = Types_makeEvent(Log_getEventId(evt), mid);
    e->arg1 = a1;
    e->arg2 = a2;
    e->arg3 = a3;
    e->arg4 = a4;

    /* part 2 */

    /*
     * We intentionally don't check for a "new" FULL condition here
     * since we want to write only the "extension" record, so a decoder
     * can know that this is an incomplete record and therefore throw
     * it away.  By not checking for FULL here, we end up just overwriting
     * the "starter" record (that was written above) of a two-entry record
     * with the "extension" record.
     */

    e = obj->curEntry;
    if (e == obj->endEntry) {
        if (adv == LoggerBuf_WRAP) {
            obj->curEntry = obj->entryArr;
        }
        else {
            obj->advance = LoggerBuf_FULL;
        }
    }
    else {
        obj->curEntry = e + 1;
    }

    e->serial = ser + 1;
    e->evt = ~0;
    e->arg1 = a5;
    e->arg2 = a6;
    e->arg3 = a7;
    e->arg4 = a8;

leave:
    Gate_leaveModule(key);
}
示例#13
0
/*
 * ======== processPipeCommand ========
 */
static Void processPipeCommand(String command)
{
    Int    i, j, n;
    String mask;
    IArg key;

    DBG( "Processing pipe command '%s'\n", command );

    /* first check if this command is an alias */
    for (i = 0; TraceUtil_cmdAliases[i] != NULL; i++) {
        if (!strcmp( TraceUtil_cmdAliases[i][0], command )) {
            for (j = 1; TraceUtil_cmdAliases[i][j] != NULL; j++) {
                processPipeCommand( TraceUtil_cmdAliases[i][j] );
            }
            return; /* we have finished processing the alias */
        }
    }

    if (strstr( command, TRACECMD_ARMTRACEMASK ) == command) {
        mask = command + strlen( TRACECMD_ARMTRACEMASK );

        INFO( "Setting Arm trace mask to '%s'\n", mask );
        GT_set( mask );
    }
    else if (strstr( command, TRACECMD_DSP0TRACEMASK ) == command) {
        mask = command + strlen( TRACECMD_DSP0TRACEMASK );

        INFO( "Setting DSP0 trace mask to '%s'\n", mask );

        key = Gate_enterModule();

        Engine_setTrace(hEngine, mask);

        Gate_leaveModule(key);
    }
    else if (strstr( command, TRACECMD_REFRESHPERIOD ) == command) {
        n = atoi( command + strlen( TRACECMD_REFRESHPERIOD ) );

        INFO( "Setting trace refresh period to %d ms.\n", n );

        refresh = n * 1000;
    }
    else if (strstr( command, TRACECMD_RESETFILES ) == command) {
        INFO( "Resetting trace/log files.\n" );
        if (localTraceFilePtr != NULL   &&
            localTraceFilePtr != stdout &&
            localTraceFilePtr != stderr) {
            DBG( "Resetting Arm trace file.\n" );

            /* rewind file (stdio operation) then truncate it (OS operation) */
            rewind( localTraceFilePtr );
            ftruncate( fileno( localTraceFilePtr ), 0L );
        }
        if (dsp0TraceFilePtr != NULL   &&
            dsp0TraceFilePtr != stdout &&
            dsp0TraceFilePtr != stderr) {
            DBG("Resetting DSP trace file.\n");
            rewind(dsp0TraceFilePtr);
            ftruncate(fileno(dsp0TraceFilePtr), 0L);
        }
        if (dsp0BiosFilePtr != NULL) {
            DBG("Resetting DSP log file.\n");
            rewind(dsp0BiosFilePtr);
            ftruncate(fileno(dsp0BiosFilePtr), 0L);
        }
    }
    else {
        WARN("Unknown trace pipe command '%s'\n", command);
    }

}
示例#14
0
/**
 * @name   DomxTunnelMgr_registerHandle
 * @brief  Resgiter a component handle
 * @param  hComponentHandle           : Handle to component to register
 * @param  szCompName                 : Component name
 * @return none
 */
Void DomxTunnelMgr_registerHandle (OmxTypes_OMX_HANDLETYPE hComponentHandle,
                                   Char *szCompName)
{
  IArg key;
  OMX_CONFIG_DOMXPROXYCOMPINFO sDomxProxyInfo;
  OMX_ERRORTYPE eError;
  DomxCore_componentCoreInfoEntry *entry;
  Error_Block ebObj;
  Error_Block *eb = &ebObj;

  DOMX_UTL_TRACE_FUNCTION_ENTRY_LEVEL1 ();

  Log_print3 (Diags_USER1, "Entered: %s (0x%x, 0x%x)", (xdc_IArg) __FUNCTION__,
              (xdc_IArg) hComponentHandle, (xdc_IArg) szCompName);

  Error_init (eb);
  if (FALSE == DomxTunnelMgr_module->initDone)
  {
    domxtmgr_module_init ();
  }
  key = Gate_enterModule ();
  domxtmgr_map_component_name2info (szCompName, &entry, eb);
  if (NULL != entry)
  {
    if (entry->coreId == DomxCore_localCoreId)
    {
      domxtmgr_register_connection (hComponentHandle,
                                    szCompName,
                                    DomxCore_localCoreId,
                                    NULL,
                                    NULL,
                                    hComponentHandle, DomxCore_localCoreId, eb);
    }
    else
    {
      eError = OMX_GetConfig (hComponentHandle, (OMX_INDEXTYPE)
                              OMX_TI_IndexConfigGetDomxCompInfo,
                              &sDomxProxyInfo);
      if (OMX_ErrorNone == eError)
      {
        domxtmgr_register_connection (sDomxProxyInfo.hCompRealHandle,
                                      szCompName,
                                      entry->coreId,
                                      (OmxTypes_OMX_PTR) sDomxProxyInfo.
                                      nRpcSkelPtr,
                                      (OmxTypes_OMX_S8 *) sDomxProxyInfo.
                                      cComponentRcmSvrName, hComponentHandle,
                                      DomxCore_localCoreId, eb);
        /* Also register connenction on remote core */
        domxtmgr_register_connection (sDomxProxyInfo.hCompRealHandle,
                                      szCompName,
                                      entry->coreId,
                                      NULL,
                                      NULL,
                                      sDomxProxyInfo.hCompRealHandle,
                                      entry->coreId, eb);
      }
      else
      {
        DOMX_UTL_TRACE_FUNCTION_ASSERT ((OMX_ErrorNone == eError),
                                        "OMX_GetConfig returned error");
      }
    }
  }
  Gate_leaveModule (key);
  /* TODO: Component should return error code */
  DOMX_UTL_TRACE_FUNCTION_ASSERT ((FALSE == Error_check (eb)),
                                  "Error in DomxTunnelMgr_registerHandle");

  DOMX_UTL_TRACE_FUNCTION_EXIT_LEVEL1 (OMX_ErrorNone);
}
示例#15
0
/*
 *  ======== LoggerBuf_getNextEntry ========
 *  "atomically" read and clear the next entry in the log
 *
 *  Returns:
 *      0   - no entry in the log
 *      1,2 - read one or two complete entries (write4, write8)
 *      -1  - read one but there may be another
 *
 *  Below are some notes on the implementation.
 *
 *  Pointers:
 *  - cureEntry points to the next entry to write
 *  - endEntry points to the last entry (not past it)
 *  - readEntry points to the entry that will be read on the next call to
 *    getNextEntry. 
 *
 *  Edge cases:
 *  - An extension record can be orphaned (the base can be missing)
 *  - A base record cannot be missing its extension (the records are written in
 *    order, so the base is always overwritten first)
 *  - The serial number can wrap from 0xFFFFFFFF to 0x0.
 *  - If a base record is at the end of the buffer, its extension may be at
 *    the beginning.
 */
Int LoggerBuf_getNextEntry(LoggerBuf_Object *obj, Log_EventRec *evtRec)
{
    LoggerBuf_Entry *ent;
    LoggerBuf_Entry *nextEnt;
    Int nEntries;
    Bits32 serA;
    IArg key;

    nEntries = 0;

    key = Gate_enterModule();

    ent = obj->readEntry;

    serA = ent->serial;
    if ((serA & 1) != 0) {
        /* serial numbers are odd and start at 1 */
        nEntries++;

        /* reduce two-spaced serial numbers to consecutive ints */
        evtRec->serial = (serA + 1) / 2;
        evtRec->evt = ent->evt;
        evtRec->tstamp = ent->tstamp;
        evtRec->arg[0] = ent->arg1;
        evtRec->arg[1] = ent->arg2;
        evtRec->arg[2] = ent->arg3;
        evtRec->arg[3] = ent->arg4;

        memset(ent, 0, sizeof (LoggerBuf_Entry));

        /* get pointer to next entry */
        if (ent == obj->endEntry) {
            nextEnt = obj->entryArr;
        }
        else {
            nextEnt = ent + 1;
        }

        if (nextEnt->serial == (serA + 1)) {

            /* continuation record */
            nEntries++;

            evtRec->arg[4] = nextEnt->arg1;
            evtRec->arg[5] = nextEnt->arg2;
            evtRec->arg[6] = nextEnt->arg3;
            evtRec->arg[7] = nextEnt->arg4;

            memset(nextEnt, 0, sizeof (LoggerBuf_Entry));

            /* get pointer to next entry */
            if (nextEnt == obj->endEntry) {
                nextEnt = obj->entryArr;
            }
            else {
                nextEnt += 1;
            }
        }
        else {
            evtRec->arg[4] = 0;
            evtRec->arg[5] = 0;
            evtRec->arg[6] = 0;
            evtRec->arg[7] = 0;
        }
    }
    else {
        /*
         * readEntry has an even sequence number, so it's either an
         * incomplete record, or it's empty.  If it's incomplete, we
         * need to toss it by advancing readEntry, but if it's empty
         * we want to do nothing.  We need to be able to distinguish
         * between an incomplete "extension" record that has a serial
         * number of 0 (since it's base record was 0xffffffff) and
         * an empty record, and we do this by checking the evt field,
         * which gets set to ~0 for extension records in write8.
         */
        if ((ent->evt == 0) && (ent->serial == 0)) {
            /* empty record, don't advance read pointer */
            nextEnt = obj->readEntry;
        }
        else if (ent->evt == ~0) {
            /* extension record */
            /* return -1 to indicate there may be more to go */
            nEntries = -1;

            if (ent == obj->endEntry) {
                nextEnt = obj->entryArr;
            }
            else {
                nextEnt = ent + 1;
            }
        }
        else {
            /* return -1 to indicate there may be more to go */
            nEntries = -1;

            /* bogus extension record, clear & advance read pointer */
            memset(ent, 0, sizeof (LoggerBuf_Entry));

            if (ent == obj->endEntry) {
                nextEnt = obj->entryArr;
            }
            else {
                nextEnt = ent + 1;
            }
        }
    }

    obj->readEntry = nextEnt;

    Gate_leaveModule(key);

    return (nEntries);
}
示例#16
0
/**
 * @name   DomxTunnelMgr_mapTunnelComponentPeerHandles
 * @brief  Map component handle to peer handles to be used in tunnel request
 * @param  hTunneledOutput            : Handle to output port component 
 * @param  hTunneledInput             : Handle to input port component 
 * @param  hTunneledOutputPeerMap     : Handle to mapped output port component 
 * @param  hTunneledOutputPeerMap     : Handle to mapped input port component 
 * @return none
 */
Void DomxTunnelMgr_mapTunnelComponentPeerHandles (OmxTypes_OMX_HANDLETYPE
                                                    hTunneledOutput,
                                                  OmxTypes_OMX_HANDLETYPE
                                                    hTunneledInput,
                                                  OmxTypes_OMX_HANDLETYPE
                                                    *hTunneledOutputPeerMap,
                                                  OmxTypes_OMX_HANDLETYPE
                                                    *hTunneledInputPeerMap)
{
  OMX_CONFIG_DOMXPROXYCOMPINFO sDomxProxyInfohOut, sDomxProxyInfohIn;
  DomxTypes_coreType eOutCompCoreId, eInCompCoreId;
  Int32 nCompIdxhOut, nCompIdxhIn;
  Error_Block ebObj;
  Error_Block *eb = &ebObj;
  IArg key;
  Bool bDisconnecthOut = FALSE;
  Bool bDisconnecthIn = FALSE;

  DOMX_UTL_TRACE_FUNCTION_ENTRY_LEVEL1 ();

  Log_print5 (Diags_USER1, "Entered: %s (0x%x, 0x%x, 0x%x, 0x%x)",
              (xdc_IArg) __FUNCTION__, (xdc_IArg) hTunneledOutput,
              (xdc_IArg) hTunneledInput, (xdc_IArg) hTunneledOutputPeerMap,
              (xdc_IArg) hTunneledInputPeerMap);

  Error_init (eb);
  if (FALSE == DomxTunnelMgr_module->initDone)
  {
    domxtmgr_module_init ();
  }
  key = Gate_enterModule ();
  *hTunneledOutputPeerMap = NULL;
  *hTunneledInputPeerMap = NULL;
  sDomxProxyInfohOut.pRpcStubHandle = NULL;
  sDomxProxyInfohIn.pRpcStubHandle = NULL;
  if (NULL != hTunneledOutput)
  {
    domxtmgr_get_component_connection_info (hTunneledOutput,
                                            &sDomxProxyInfohOut, &nCompIdxhOut,
                                            &eOutCompCoreId, eb);
  }
  else
  {
    bDisconnecthOut = TRUE;
  }

  if (FALSE == Error_check (eb))
  {
    if (NULL != hTunneledInput)
    {
      Log_print1 (Diags_USER1, "eOutCompCoreId: %d\n", eOutCompCoreId);

      domxtmgr_get_component_connection_info (hTunneledInput,
                                              &sDomxProxyInfohIn, &nCompIdxhIn,
                                              &eInCompCoreId, eb);
    }
    else
    {
      bDisconnecthIn = TRUE;
    }
  }
  
  if (FALSE == Error_check (eb))
  {
    if (NULL != hTunneledOutput)
    {
      if (FALSE == bDisconnecthIn)
      {
        Log_print1 (Diags_USER1, "eInCompCoreId: %d\n", eInCompCoreId);

        domxtmgr_map_connection_handle (nCompIdxhOut, eInCompCoreId,
                                        sDomxProxyInfohIn.pRpcStubHandle,
                                        hTunneledInputPeerMap, eb);
      }
      else
      {
        /* Do nothing for now */
      }
    }
  }

  if (FALSE == Error_check (eb))
  {
    if (NULL != hTunneledInput)
    {
      if (FALSE == bDisconnecthOut)
      {
        domxtmgr_map_connection_handle (nCompIdxhIn, eOutCompCoreId,
                                        sDomxProxyInfohOut.pRpcStubHandle,
                                        hTunneledOutputPeerMap, eb);
      }
      else
      {
        /* Do nothing for now */
      }
    }
  }

  Gate_leaveModule (key);
  /* TODO: Component should return error code */
  DOMX_UTL_TRACE_FUNCTION_ASSERT ((FALSE == Error_check (eb)),
                                  " in mapTunnelComponentPeerHandles");

  DOMX_UTL_TRACE_FUNCTION_EXIT_LEVEL1 (OMX_ErrorNone);
}
示例#17
0
/*
 *  ======== HeapMem_alloc ========
 *  HeapMem is implemented such that all of the memory and blocks it works
 *  with have an alignment that is a multiple of the header size and have a
 *  size which is a multiple of the header size. Maintaining this requirement
 *  throughout the implementation ensures that there are never any odd
 *  alignments or odd block sizes to deal with.
 *
 *  Specifically:
 *  The buffer managed by HeapMem:
 *    1. Is aligned on a multiple of sizeof(HeapMem_Header)
 *    2. Has an adjusted size that is a multiple of sizeof(HeapMem_Header)
 *  All blocks on the freelist:
 *    1. Are aligned on a multiple of sizeof(HeapMem_Header)
 *    2. Have a size that is a multiple of sizeof(HeapMem_Header)
 *  All allocated blocks:
 *    1. Are aligned on a multiple of sizeof(HeapMem_Header)
 *    2. Have a size that is a multiple of sizeof(HeapMem_Header)
 *
 */
Ptr HeapMem_alloc(HeapMem_Object *obj, SizeT reqSize,
                  SizeT reqAlign, Error_Block *eb)
{
    IArg key;
    HeapMem_Header *prevHeader, *newHeader, *curHeader;
    Char *allocAddr;
    Memory_Size curSize, adjSize;
    SizeT remainSize; /* free memory after allocated memory      */
    SizeT adjAlign, offset;

    /* Assert that requested align is a power of 2 */
    Assert_isTrue(((reqAlign & (reqAlign - 1)) == 0), HeapMem_A_align);

    adjSize = (Memory_Size)reqSize;

    /* Make size requested a multiple of Memory_Header */
    if ((offset = (adjSize & (obj->minBlockAlign - 1))) != 0) {
        adjSize = adjSize + (obj->minBlockAlign - offset);
    }

    /* Assert that requested block size is non-zero */
    Assert_isTrue((adjSize != 0), HeapMem_A_zeroBlock);

    /*
     *  Make sure the alignment is at least as large as the sizeof
     *  HeapMem_Header.
     *  Note: adjAlign must be a power of 2 (by function constraint) and
     *  Header size is also a power of 2,
     */
    adjAlign = reqAlign;
    if (adjAlign & (obj->minBlockAlign - 1)) {
        /* adjAlign is less than Header size */
        adjAlign = obj->minBlockAlign;
    }

    key = Gate_enterModule();

    /*
     *  The block will be allocated from curHeader. Maintain a pointer to
     *  prevHeader so prevHeader->next can be updated after the alloc.
     */
    prevHeader  = &obj->head;
    curHeader = prevHeader->next;

    /* Loop over the free list. */
    while (curHeader != NULL) {

        curSize = curHeader->size;

        /*
         *  Determine the offset from the beginning to make sure
         *  the alignment request is honored.
         */
        offset = (Memory_Size)curHeader & (adjAlign - 1);
        if (offset) {
            offset = adjAlign - offset;
        }

        /* Internal Assert that offset is a multiple of minBlockAlign */
        Assert_isTrue(((offset & (obj->minBlockAlign - 1)) == 0), NULL);

        /* big enough? */
        if (curSize >= (adjSize + offset)) {

            /* Set the pointer that will be returned. Alloc from front */
            allocAddr = (Char *)((Memory_Size)curHeader + offset);

            /*
             *  Determine the remaining memory after the allocated block.
             *  Note: this cannot be negative because of above comparison.
             */
            remainSize = curSize - adjSize - offset;

            /* Internal Assert that remainSize is a multiple of header size */
            Assert_isTrue(((remainSize & (obj->minBlockAlign - 1)) == 0), NULL);

            /*
             *  If there is memory at the beginning (due to alignment
             *  requirements), maintain it in the list.
             *
             *  offset and remainSize must be multiples of
             *  sizeof(HeapMem_Header). Therefore the address of the newHeader
             *  below must be a multiple of the sizeof(HeapMem_Header), thus
             *  maintaining the requirement.
             */
            if (offset) {

                /* Adjust the curHeader size accordingly */
                curHeader->size = offset;

                /*
                 *  If there is remaining memory, add into the free list.
                 *  Note: no need to coalesce and we have HeapMem locked so
                 *        it is safe.
                 */
                if (remainSize) {
                    newHeader = (HeapMem_Header *)
                                ((Memory_Size)allocAddr + adjSize);
                    newHeader->next = curHeader->next;
                    newHeader->size = remainSize;
                    curHeader->next = newHeader;
                }
            }
            else {
                /*
                 *  If there is any remaining, link it in,
                 *  else point to the next free block.
                 *  Note: no need to coalesce and we have HeapMem locked so
                 *        it is safe.
                 */
                if (remainSize) {
                    newHeader = (HeapMem_Header *)
                                ((Memory_Size)allocAddr + adjSize);
                    newHeader->next  = curHeader->next;
                    newHeader->size  = remainSize;
                    prevHeader->next = newHeader;
                }
                else {
                    prevHeader->next = curHeader->next;
                }
            }

            Gate_leaveModule(key);

            /* Success, return the allocated memory */
            return ((Ptr)allocAddr);
        }
        else {
            prevHeader = curHeader;
            curHeader = curHeader->next;
        }
    }

    Gate_leaveModule(key);

    Error_raise(eb, HeapMem_E_memory, (IArg)obj, (IArg)reqSize);

    return (NULL);
}
示例#18
0
/*
 *  ======== Notify_unregisterEvent ========
 */
Int Notify_unregisterEvent(UInt16                 procId,
                           UInt16                 lineId,
                           UInt32                 eventId,
                           Notify_FnNotifyCbck    fnNotifyCbck,
                           UArg                   cbckArg)
{
    UInt32  strippedEventId = (eventId & 0xFFFF);
    UInt16  clusterId = ti_sdo_utils_MultiProc_getClusterId(procId);
    Int     status;
    UInt    sysKey, modKey;
    ti_sdo_ipc_Notify_Object *obj;
    List_Handle eventList;
    ti_sdo_ipc_Notify_EventListener *listener;
    UInt    count = 0;

    Assert_isTrue(procId < ti_sdo_utils_MultiProc_numProcessors && lineId <
                  ti_sdo_ipc_Notify_numLines, ti_sdo_ipc_Notify_A_invArgument);
    Assert_isTrue(strippedEventId < ti_sdo_ipc_Notify_numEvents,
                  ti_sdo_ipc_Notify_A_invArgument);
    Assert_isTrue(ISRESERVED(eventId), ti_sdo_ipc_Notify_A_reservedEvent);

    modKey = Gate_enterModule();

    obj = (ti_sdo_ipc_Notify_Object *)
          Notify_module->notifyHandles[clusterId][lineId];

    Assert_isTrue(obj != NULL, ti_sdo_ipc_Notify_A_notRegistered);

    eventList = List_Object_get(obj->eventList, strippedEventId);

    if (List_empty(eventList)) {
        return (Notify_E_NOTFOUND);
    }

    /* Get the first listener on the list */
    listener = (ti_sdo_ipc_Notify_EventListener *)List_next(eventList, NULL);

    while (listener != NULL) {
        count++;
        if (listener->callback.fnNotifyCbck == (Fxn)fnNotifyCbck &&
                listener->callback.cbckArg == cbckArg ) {
            break;      /* found a match! */
        }
        listener = (ti_sdo_ipc_Notify_EventListener *)
                   List_next(eventList, (List_Elem *)listener);
    }

    if (listener == NULL) {
        /* Event listener not found */
        status = Notify_E_NOTFOUND;
    }
    else {
        if (count == 1 && List_next(eventList, (List_Elem *)listener) == NULL) {
            /*
             *  If only one element counted so far and the List_next returns
             *  NULL, the list will be empty after unregistering.  Therefore,
             *  unregister the callback function.
             */
            status = Notify_unregisterEventSingle(procId, lineId, eventId);
            /* unregisterEvent should always suceed */
            Assert_isTrue(status == Notify_S_SUCCESS,
                          ti_sdo_ipc_Notify_A_internal);

            /*  No need to protect the list removal: the event's unregistered */
            List_remove(eventList, (List_Elem *)listener);
        }
        else {
            /*
             *  Need to atomically remove from the list using the system gate
             *  because Notify_exec might preempt List_remove (the event is
             *  still registered)
             */
            sysKey = Hwi_disable();
            List_remove(eventList, (List_Elem *)listener);
            Hwi_restore(sysKey);
        }

        /* Free the memory alloc'ed for the event listener */
        Memory_free(ti_sdo_ipc_Notify_Object_heap(), listener,
                    sizeof(ti_sdo_ipc_Notify_EventListener));

        status = Notify_S_SUCCESS;
    }

    Gate_leaveModule(modKey);

    return (status);
}
示例#19
0
/*
 *  ======== HeapMem_free ========
 */
Void HeapMem_free(HeapMem_Object *obj, Ptr addr, SizeT size)
{
    IArg key;
    HeapMem_Header *curHeader, *newHeader, *nextHeader;
    SizeT offset;

    /* Make sure the addr is aligned properly */
    Assert_isTrue((((UArg)addr & (obj->minBlockAlign - 1)) == 0),
                  HeapMem_A_invalidFree);

    /* obj->head never changes, doesn't need Gate protection. */
    curHeader = &obj->head;

    /* Restore size to actual allocated size */
    if ((offset = size & (obj->minBlockAlign - 1)) != 0) {
        size += obj->minBlockAlign - offset;
    }

    key = Gate_enterModule();

    newHeader = (HeapMem_Header *)addr;
    nextHeader = curHeader->next;

    /*
     *  Make sure the entire buffer is in the range of the heap.
     *  Note the obj->head.size never changes
     */
    Assert_isTrue((((UArg)newHeader >= (UArg)(obj->buf)) &&
                   ((UArg)newHeader + size <=
                    (UArg)(obj->buf) + obj->head.size)),
                  HeapMem_A_invalidFree);

    /* Go down freelist and find right place for buf */
    while (nextHeader != NULL && nextHeader < newHeader) {
        /* Make sure the addr is not in this free block */
        Assert_isTrue(((UArg)newHeader >= (UArg)nextHeader + nextHeader->size),
                      HeapMem_A_invalidFree);
        curHeader = nextHeader;
        nextHeader = nextHeader->next;
    }

    newHeader->next = nextHeader;
    newHeader->size = size;
    curHeader->next = newHeader;

    /* Join contiguous free blocks */
    if (nextHeader != NULL) {
        /*
         *  Verify the free size is not overlapping. Not all cases are
         *  detectable, but it is worth a shot. Note: only do this
         *  assert if nextHeader is non-NULL.
         */
        Assert_isTrue((((UArg)newHeader + size) <= (UArg)nextHeader),
                      HeapMem_A_invalidFree);

        /* Join with upper block */
        if (((Memory_Size)newHeader + size) == (Memory_Size)nextHeader) {
            newHeader->next = nextHeader->next;
            newHeader->size += nextHeader->size;
        }
    }
    /*
     *  Join with lower block. Make sure to check to see if not the
     *  first block.
     */
    if ((curHeader != &obj->head) &&
            (((Memory_Size)curHeader + curHeader->size) == (Memory_Size)newHeader)) {
        curHeader->next = newHeader->next;
        curHeader->size += newHeader->size;
    }

    Gate_leaveModule(key);
}
示例#20
0
/*
 * ======== traceThrFxn ========
 */
static void *traceThrFxn(void *arg)
{
    String engineName = (String) arg;
    Server_Status status;
    FILE *f;
    IArg key;

    /* determine DSP line prefix: "[DSP] " if local and DSP trace end up at the same
     * file, otherwise ""
     */
    char *dspPrefix = (dsp0TraceFilePtr == localTraceFilePtr) ? "[DSP] " : "";

    DBG("Trace thread started\n");

    hEngine = Engine_open(engineName, NULL, NULL);

    if (hEngine == NULL) {
        ERR("Failed to open codec engine \"%s\"\n", engineName);
        threadCreateFailed = TRUE;
        return ((void *) -1);
    }

    /* for multi-process situations, make sure can acquire server trace */
    if (Global_useLinkArbiter) {

        /* get server handle */
        hServer = Engine_getServer(hEngine);

        /* cleanup and abort if can't get server handle */
        if (hServer == NULL) {
            Engine_close(hEngine);
            ERR("Failed to get server handle\n");
            threadCreateFailed = TRUE;
            return ((void *) -1);
        }

        /* request server trace token */
        status = Server_connectTrace(hServer, &traceToken);

        /* cleanup and abort if trace could not acquire trace token */
        if (status != Server_EOK) {
            Engine_close(hEngine);
            ERR("Failed to connect for server trace\n");
            threadCreateFailed = TRUE;
            return ((void *) -1);
        }
    }

    /* else: if single-process, don't need to explictly connect for trace */

    Engine_setTrace(hEngine, dsp0mask);

    /* create the pipe thread now */
    if (cmdPipeFile != NULL && cmdPipeFile[0] != '\0') {
        if (pthread_create(&pipeThread, NULL, pipeThrFxn, NULL)) {
            ERR("Failed to create pipe thread\n");
        } else {
            /* run the thread just created so it can immediately execute
             * pending cmdPipe trace commands -- in case there are any
             */
            while (pipeThreadCreated == FALSE) {
                sched_yield();
            }
        }
    }

    /* TODO: remove? will LogClient_connect be inside CE? */
    /*
     * Note, call LogClient_connect() before releasing the main thread to
     * avoid context switching away _during_ the connect() call - which could
     * result in a skewed timesynch log.
     */
    if (dsp0BiosFilePtr != NULL) {
//        LogClient_connect();
    }

    /* Release the spinning main thread to run */
    traceThreadCreated = TRUE;

    while (!quit) {

        if (refresh > 0) {

            DBG("Writing DSP logs\n");

            key = Gate_enterModule();

            Engine_fwriteTrace(hEngine, dspPrefix, dsp0TraceFilePtr);

            if (dsp0BiosFilePtr != NULL) {
//                LogClient_fwriteLogs(dsp0BiosFilePtr);
            }

            Gate_leaveModule(key);

            DBG("Sleeping for %d us\n", refresh);
            usleep(refresh);
        } else {
            DBG("Sleeping for %d us\n", SLEEPWHENNOREFRESH);
            usleep( SLEEPWHENNOREFRESH );
        }
    }

    if (refresh > 0) {

        DBG("Trace thread exiting, writing final DSP logs\n");

        /* try to collect anything that remained one more time */
        key = Gate_enterModule();

        Engine_fwriteTrace(hEngine, dspPrefix, dsp0TraceFilePtr);

        if (dsp0BiosFilePtr != NULL) {
//            LogClient_fwriteLogs(dsp0BiosFilePtr);
        }

        Gate_leaveModule(key);
    }

    if (dsp0BiosFilePtr != NULL) {
//        LogClient_disconnect();
    }

    /* for multi-process situations, release trace token back to RMS */
    if (Global_useLinkArbiter) {
        Server_disconnectTrace(hServer, traceToken);
    }

    Engine_close(hEngine);

    DBG("Quitting trace thread\n");

    /* and killing our offspring. */
    if (pipeThread != NULL) {
        DBG("Telling pipe thread to quit\n");
        f = fopen(cmdPipeFile, "w");
        if (f != NULL) {
            fputs(TRACECMD_QUIT, f);
            fclose(f);
            DBG("Wrote quit command, waiting for the pipe thread to join\n");
            if (pthread_join(pipeThread, NULL)) {
                ERR("Failed to join pipe thread\n");
            }
            DBG("Pipe thread joined.\n");
        }
    }

    return ((void *) 1);
}
示例#21
0
/*
 *  ======== write4 =========
 */
Void LoggerBuf_write4(LoggerBuf_Object *obj, Log_Event evt,
                      Types_ModuleId mid, IArg a1, IArg a2, IArg a3, IArg a4)
{
    IArg key;
    Int adv;
    Int32 ser;
    LoggerBuf_Entry *e;

    /* Do nothing if the instance is disabled. */
    if (!obj->enabled) {
        return;
    }

    /* 
     * If event level filtering is enabled, and the event isn't a high enough
     * level, drop the record and return.
     */
    if (LoggerBuf_filterByLevel && 
        LoggerBuf_filterOutEvent(Log_getMask(evt))) {
        return;
    }
    
    /* 
     *  If all of the following are true:
     *   - A logger has been specified to route status events to
     *   - This is a status event
     *   - This logger is NOT the status logger
     * Pass the event to the status logger and return.
     *
     * Otherwise, continue to log the event.
     */
    if ((LoggerBuf_statusLogger != NULL) && 
        (Log_getMask(evt) & Diags_STATUS) &&
        (LoggerBuf_statusLogger != 
         xdc_runtime_LoggerBuf_Handle_to_xdc_runtime_ILogger(obj))) {
        ILogger_write4(LoggerBuf_statusLogger, evt, mid, a1, a2, a3, a4);
        return;
    }
    
    key = Gate_enterModule();

    /*
     * Record new serial number even if the buffer is FULL.  We do this
     * because a reader (decoder) of the buffer needs to know if events
     * have been missed, and the buffer might become un-FULL at some
     * later time.
     */
    ser = obj->serial;
    obj->serial += 2;

    adv = obj->advance;
    if (adv == LoggerBuf_FULL) {
        goto leave;
    }

    e = obj->curEntry;

    if (e == obj->endEntry) {
        if (adv == LoggerBuf_WRAP) {
            obj->curEntry = obj->entryArr;
        }
        else {
            obj->advance = LoggerBuf_FULL;
        }
    }
    else {
        obj->curEntry = e + 1;
    }

    LoggerBuf_TimestampProxy_get64(&e->tstamp);

    e->serial = ser;
    e->evt = Types_makeEvent(Log_getEventId(evt), mid);
    e->arg1 = a1;
    e->arg2 = a2;
    e->arg3 = a3;
    e->arg4 = a4;

leave:
    Gate_leaveModule(key);
}