Пример #1
0
int
timerLoop (void)
{
    IxOsalTimeval now;
    IxOsalVoidFnVoidPtr callback = NULL;
    void *callbackParam = NULL;
    IxOsalTimerRec *nextTimer;
    IX_STATUS status;

    while (1)
    {
        /*
         *  This loop catches all cases in a simple way.  If multiple
         *  timers expire together, then lowest will be <=0 until all
         *  have been processed and the queue get won't get invoked.
         */

        status =
            ixOsalSemaphoreWait (&ixOsalCriticalSectSem,
            IX_OSAL_WAIT_FOREVER);
        if (status != IX_SUCCESS)
        {
            ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT,
                "timerLoop  fail to get semaphore \n", 0, 0, 0, 0, 0, 0);
            return IX_FAIL;
        }

        ixOsalTimeGet (&now);
        nextTimer = findNextTimeout (now);

        if ((nextTimer == NULL)
            || IX_OSAL_TIME_GT ((nextTimer->expires), (now)))
        {
            callback = NULL;
        }
        else
        {
            rescheduleTimer (nextTimer);
            callback = nextTimer->callback;
            callbackParam = nextTimer->callbackParam;
        }

        status = ixOsalSemaphorePost (&ixOsalCriticalSectSem);
        if (status != IX_SUCCESS)
        {
            ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT,
                "timerLoop  fail to release semaphore \n", 0, 0, 0, 0, 0, 0);
            return IX_FAIL;
        }

        if (callback != NULL)
        {
            callTimerCallback (callback, callbackParam);
        }
        else
        {
            timerSleep (nextTimer, now);
        }
    }
}
Пример #2
0
/**
 * @brief default NPE event processing callback
 *
 * @param npeID ID of the NPE that generated the event
 * @param msg NPE message (encapsulated event)
 *
 * Creates an event object on the Ethernet event processor queue
 * and signals the new event by incrementing the event queue semaphore.
 * Events are processed by @ref ixEthDBEventProcessorLoop() which runs
 * at user level.
 *
 * @see ixEthDBEventProcessorLoop()
 *
 * @warning do not call directly
 *
 * @internal
 */
IX_ETH_DB_PUBLIC
void ixEthDBNPEEventCallback(IxNpeMhNpeId npeID, IxNpeMhMessage msg)
{
    PortEvent *local_event;

    IX_ETH_DB_IRQ_EVENTS_TRACE("DB: (Events) new event received by processor callback from port %d, id 0x%X\n", IX_ETHNPE_NODE_AND_PORT_TO_PHYSICAL_ID(npeID,0), NPE_MSG_ID(msg), 0, 0, 0, 0);

    if (CAN_ENQUEUE(&eventQueue))
    {
        TEST_FIXTURE_LOCK_EVENT_QUEUE;

        local_event = QUEUE_HEAD(&eventQueue);

        /* create event structure on queue */
        local_event->eventType = NPE_MSG_ID(msg);
        local_event->portID    = IX_ETHNPE_NODE_AND_PORT_TO_PHYSICAL_ID(npeID,0);
        
        /* update queue */
        PUSH_UPDATE_QUEUE(&eventQueue);

        TEST_FIXTURE_UNLOCK_EVENT_QUEUE;

        IX_ETH_DB_IRQ_EVENTS_TRACE("DB: (Events) Waking up main processor loop...\n", 0, 0, 0, 0, 0, 0);

        /* increment event queue semaphore */
        ixOsalSemaphorePost(&eventQueueSemaphore);
    }
    else
    {
        IX_ETH_DB_IRQ_EVENTS_TRACE("DB: (Events) Warning: could not enqueue event (overflow)\n", 0, 0, 0, 0, 0, 0);
    }
}
Пример #3
0
PUBLIC IX_STATUS
ixOsalTimerCancel (IxOsalTimer * timer)
{
    UINT32 id;
    UINT32 i;
    IX_STATUS status = IX_FAIL;

    if (ixOsalTimerInited == FALSE)
    {
        ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT,
            "ixOsalTimerCancel: call schedule APIs first to start timer \n",
            0, 0, 0, 0, 0, 0);
        return IX_FAIL;
    }

    id = *timer;

    status =
        ixOsalSemaphoreWait (&ixOsalCriticalSectSem, IX_OSAL_WAIT_FOREVER);

    if (status != IX_SUCCESS)
    {
        ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT,
            "ixOsalTimerCancel: fail to get semaphore \n", 0, 0, 0, 0, 0, 0);
        return IX_FAIL;
    }
    /*
     *  NOTE : there is no need to get the timer callback thread to wake
     *  up and recalculate.  If this timer is the next to expire, then
     *  the timer callback thread will wake up but not find any timers to
     *  callback and will just go back to sleep again anyway.
     */

    /*
     *  NOTE2 : We cancel a timer by doing a linear search for the timer id.
     *  This is not terribly efficient but is the safest way to ensure that
     *  cancellations do not cancel the wrong timer by mistake.  Also we
     *  assume timer cancellation does not occur often.  If the timer to
     *  be cancelled is not found, an error is logged.
     */

    for (i = 0; i < ixOsalHigestTimeSlotUsed; i++)
    {
        if (ixOsalTimers[i].inUse && ixOsalTimers[i].id == id)
        {
            ixOsalTimers[i].inUse = FALSE;
            break;
        }
    }

    status = ixOsalSemaphorePost (&ixOsalCriticalSectSem);
    if (status != IX_SUCCESS)
    {
        ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT,
            "ixOsalTimerCancel: fail to free semaphore \n", 0, 0, 0, 0, 0, 0);
        return IX_FAIL;
    }

    return IX_SUCCESS;
}
Пример #4
0
/**
 * @ingroup IxTimeSyncAccCodelet
 *
 * @fn ixTimeSyncAccCodeletTxDoneCB (
	UINT32 cbTag, 
	IX_OSAL_MBUF* mBufPtr, 
 *
 * @brief Tx callback. This function gives semaphore to allow 
 *	  ixTimeSyncAccCodeletPTPMsgTransmit function to transmit
 * 	  next PTP message. 
 *
 * @param 
 * cbTag UINT32 [in] - argument passed to callback 
 *
 * @param 
 * mBufPtr IX_OSAL_MBUF* [in] - pointer to mBuf
 *
 * @return void
 */
PRIVATE void 
ixTimeSyncAccCodeletTxDoneCB (
	UINT32 cbTag, 
	IX_OSAL_MBUF* mBufPtr)
{

	if (IX_SUCCESS != ixOsalSemaphorePost (&ixTimeSyncAccCodeletSemId))
	{
		ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "ixTimeSyncAccCodeletTxDoneCB: Failed to give semaphore, port Id %d\n",
				cbTag, 0, 0, 0, 0, 0);
	}
} /* end of ixTimeSyncAccCodeletTxDoneCB function */
Пример #5
0
/**
 * @brief stops the event processor
 *
 * Stops the event processor and frees the event queue semaphore
 * Called by the component de-initialization function, ixEthDBUnload()
 *
 * @warning do not call directly
 *
 * @return IX_ETH_DB_SUCCESS if the operation completed 
 * successfully or IX_ETH_DB_FAIL otherwise;
 *
 * @internal
 */
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBStopLearningFunction(void)
{
    ixEthDBLearningShutdown = true;

    /* wake up event processing loop to actually process the shutdown event */
    ixOsalSemaphorePost(&eventQueueSemaphore);

    if (ixOsalSemaphoreDestroy(&eventQueueSemaphore) != IX_SUCCESS)
    {
        return IX_ETH_DB_FAIL;
    }

    return IX_ETH_DB_SUCCESS;
}
Пример #6
0
/**
 * @brief stops the event processor
 *
 * Stops the event processor and frees the event queue semaphore
 * Called by the component de-initialization function, ixEthDBUnload()
 *
 * @warning do not call directly
 *
 * @return IX_ETH_DB_SUCCESS if the operation completed 
 * successfully or IX_ETH_DB_FAIL otherwise;
 *
 * @internal
 */
IX_ETH_DB_PUBLIC
IxEthDBStatus ixEthDBStopLearningFunction(void)
{
    if (IX_FEATURE_CTRL_SWCONFIG_ENABLED ==
        ixFeatureCtrlSwConfigurationCheck (IX_FEATURECTRL_ETH_LEARNING))
    {

    	ixEthDBLearningShutdown = TRUE;

    	/* wake up event processing loop to actually process the shutdown event */
    	ixOsalSemaphorePost(&eventQueueSemaphore);

    	if (ixOsalSemaphoreDestroy(&eventQueueSemaphore) != IX_SUCCESS)
    	{
            return IX_ETH_DB_FAIL;
    	}

        return IX_ETH_DB_SUCCESS;
    }

    return IX_ETH_DB_FEATURE_UNAVAILABLE;
}
Пример #7
0
/**
 * @brief adds an ADD or REMOVE event to the main event queue
 *
 * @param eventType event type - IX_ETH_DB_ADD_FILTERING_RECORD 
 * to add and IX_ETH_DB_REMOVE_FILTERING_RECORD to remove a
 * record.
 *
 * @return IX_ETH_DB_SUCCESS if the event was successfully
 * sent or IX_ETH_DB_BUSY if the event queue is full
 *
 * @internal
 */
IX_ETH_DB_PRIVATE
IxEthDBStatus ixEthDBTriggerPortUpdate(UINT32 eventType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, BOOL staticEntry)
{
    UINT32 intLockKey;

    /* lock interrupts to protect queue */
    intLockKey = ixOsalIrqLock();

    if (CAN_ENQUEUE(&eventQueue))
    {
        PortEvent *queueEvent = QUEUE_HEAD(&eventQueue);

        /* update fields on the queue */
        ixOsalMemCopy(queueEvent->macAddr.macAddress, macAddr->macAddress, IX_IEEE803_MAC_ADDRESS_SIZE);
        
        queueEvent->eventType     = eventType;
        queueEvent->portID        = portID;
        queueEvent->staticEntry   = staticEntry;

        PUSH_UPDATE_QUEUE(&eventQueue);

        /* imcrement event queue semaphore */
        ixOsalSemaphorePost(&eventQueueSemaphore);
        
        /* unlock interrupts */
        ixOsalIrqUnlock(intLockKey);

        return IX_ETH_DB_SUCCESS;
    }
    else /* event queue full */
    {
        /* unlock interrupts */
        ixOsalIrqUnlock(intLockKey);

        return IX_ETH_DB_BUSY;
    }
}
Пример #8
0
PRIVATE
void
ixHssAccCodeletChanRxCallback (
    IxHssAccHssPort hssPortId,
    unsigned rxOffset,
    unsigned txOffset,
    unsigned numHssErrs)
{
    ClientInfo *pClientInfo = &clientInfo[hssPortId];
    Message *pMessage;

    /* add message to the head of the message queue */
    pMessage = &pClientInfo->messageQ[pClientInfo->qHead++];
    pClientInfo->qHead %= NUMELEMS(pClientInfo->messageQ);

    /* fill in the message */
    pMessage->type = RxCallback;
    pMessage->params.rxOffset = rxOffset;
    pMessage->params.txOffset = txOffset;
    pMessage->params.numHssErrs = numHssErrs;

    /* wake up the message processing thread */
    (void) ixOsalSemaphorePost (&pClientInfo->messageSem);
}
Пример #9
0
PUBLIC IX_STATUS
ixOsalMutexUnlock (IxOsalMutex * mutex)
{
    return ixOsalSemaphorePost((IxOsalSemaphore *) mutex);
}
Пример #10
0
PRIVATE IX_STATUS
createNewTimer (IxOsalVoidFnVoidPtr func, void *param, UINT32 priority,
    UINT32 interval, BOOL isRepeating, UINT32 * timerId)
{
    UINT32 i;
    IX_STATUS status = IX_SUCCESS;
    int osTicks;
    IxOsalTimeval timeVal;

    /*
     * Check if callback is NULL 
     */
    if (func == NULL)
    {
        ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT,
            "client registered a NULL callback function\n", 0, 0, 0, 0, 0, 0);
        return IX_FAIL;
    }

    osTicks = ixOsalSysClockRateGet ();
    /*
     * Figure out how many milisecond per tick and compare against interval 
     */
    if (interval < (UINT32) (1000 / osTicks))
    {
        ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT,
            "client requested time interval (%d) finer than clock ticks\n",
            interval, 0, 0, 0, 0, 0);
        return IX_FAIL;
    }

    /*
     * Increment timerId 
     */
    *timerId = ++lastTimerId;

    status =
        ixOsalSemaphoreWait (&ixOsalCriticalSectSem, IX_OSAL_WAIT_FOREVER);
    if (status != IX_SUCCESS)
    {
        ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT,
            "createNewTimer  fail to get semaphore \n", 0, 0, 0, 0, 0, 0);
        return IX_FAIL;
    }

    for (i = 0; i < IX_OSAL_MAX_TIMERS; i++)
    {
        if (!ixOsalTimers[i].inUse)
        {
            break;
        }
    }

    if ((i >= IX_OSAL_TIMER_WARNING_THRESHOLD)
        && (ixOsalThresholdErr == FALSE))
    {
        /*
         * This error serves as an early indication that the number of
         * available timer slots will need to be increased. This is done
         * by increasing IX_OSAL_MAX_TIMERS
         */
        ixOsalLog (IX_OSAL_LOG_LVL_WARNING, IX_OSAL_LOG_DEV_STDOUT,
            "Timer threshold reached. Only %d timer slots now available\n",
            IX_OSAL_MAX_TIMERS - i, 0, 0, 0, 0, 0);
        ixOsalThresholdErr = TRUE;
    }

    if (i == IX_OSAL_MAX_TIMERS)
    {
        /*
         *  If you get this error, increase MAX_TIMERS above 
         */
        ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT,
            "Out of timer slots %d used - request ignored\n",
            i, 0, 0, 0, 0, 0);
        status = IX_FAIL;
    }
    else
    {
        ixOsalTimers[i].inUse = TRUE;

        IX_OSAL_MS_TO_TIMEVAL (interval, &timeVal);

        ixOsalTimers[i].period = timeVal;
        ixOsalTimers[i].isRepeating = isRepeating;
        ixOsalTimeGet (&(ixOsalTimers[i].expires));
        IX_OSAL_TIME_ADD ((ixOsalTimers[i].expires), (ixOsalTimers[i].period))
            ixOsalTimers[i].priority = priority;
        ixOsalTimers[i].callback = func;
        ixOsalTimers[i].callbackParam = param;
        ixOsalTimers[i].id = *timerId;

        if ((i) >= ixOsalHigestTimeSlotUsed)
        {
            ixOsalHigestTimeSlotUsed = i + 1;
        }

        status = ixOsalSemaphorePost (&ixOsalTimerRecalcSem);
        if (status != IX_SUCCESS)
        {
            ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT,
                "createNewTimer:  fail to release semaphore \n",
                0, 0, 0, 0, 0, 0);
            return IX_FAIL;
        }

    }

    status = ixOsalSemaphorePost (&ixOsalCriticalSectSem);
    if (status != IX_SUCCESS)
    {
        ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT,
            "createNewTimer:  fail to release semaphore: ixOsalCriticalSectSem \n",
            0, 0, 0, 0, 0, 0);
        return IX_FAIL;
    }

    return status;
}