Beispiel #1
0
/* Blocks the thread while waiting for the semaphore to be
 * signaled. If the "timeout" argument is non-zero, the thread should
 * only be blocked for the specified time (measured in
 * milliseconds).
 *
 * If the timeout argument is non-zero, the return value is the number of
 * milliseconds spent waiting for the semaphore to be signaled. If the
 * semaphore wasn't signaled within the specified time, the return value is
 * SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore
 * (i.e., it was already signaled), the function may return zero. */
u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
{
    /* Slightly more complicated than the normal minios semaphore:
     * need to wake on timeout *or* signal */
    int flags;
    int64_t then = NOW();
    int64_t deadline;

    if (timeout == 0)
	deadline = 0;
    else
	deadline = then + MILLISECS(timeout);

    while(1) {
        wait_event_deadline(sem->sem.wait, (sem->sem.count > 0), deadline);

        local_irq_save(flags);
	/* Atomically check that we can proceed */
	if (sem->sem.count > 0 || (deadline && NOW() >= deadline))
	    break;
        local_irq_restore(flags);
    }

    if (sem->sem.count > 0) {
        sem->sem.count--;
        local_irq_restore(flags);
        return NSEC_TO_MSEC(NOW() - then);
    }

    local_irq_restore(flags);
    return SYS_ARCH_TIMEOUT;
}
Beispiel #2
0
void poll_networking(void)
{
    uint64_t now;

    if (!netif)
        return;

    /* poll interface */
    netfrontif_poll(netif, LWIP_NETIF_MAX_RXBURST_LEN);

    /* process lwIP timers */
    now = NSEC_TO_MSEC(NOW());
    TIMED(now, ts_etharp,  ARP_TMR_INTERVAL, etharp_tmr());
    TIMED(now, ts_ipreass, IP_TMR_INTERVAL,  ip_reass_tmr());
    TIMED(now, ts_tcp,     TCP_TMR_INTERVAL, tcp_tmr());
    TIMED(now, ts_dns,     DNS_TMR_INTERVAL, dns_tmr());
}
Beispiel #3
0
int ARSAL_Sem_Timedwait(ARSAL_Sem_t *sem, const struct timespec *timeout)
{
    int result = -1;

    if (NULL == sem || NULL == *sem)
    {
        errno = EINVAL;
        return result;
    } /* MUST BE INIT TO -1 */
    /* No else. */

#if __SAL_USE_POSIX_SEM

    struct timespec finalTime = {0};
    ARSAL_Time_GetLocalTime(&finalTime, NULL);
    finalTime.tv_nsec += timeout->tv_nsec;
    finalTime.tv_sec += timeout->tv_sec + NSEC_TO_SEC(finalTime.tv_nsec);
    finalTime.tv_nsec %= SEC_TO_NSEC(1);
    result = sem_timedwait((sem_t *)*sem, &finalTime);

#else

    /*
     * Custom timedwait algo:
     * Lock mutex
     * Check if counter is > 0
     *  NO         YES
     *  |          | - Decrement counter
     *  |          \ - Unlock mutex
     *  | - Timedwait on condition
     *  | - If timeout -> set result to -1 and errno to ETIMEDOUT
     *  | - Else       -> Decrement counter
     *  \ - Unlock mutex
     */

    ARSAL_Sem_CustomImpl_t *psem = (ARSAL_Sem_CustomImpl_t *)*sem;
    int unlockRes = 0;
    result = ARSAL_Mutex_Lock (&(psem->lock));
    ARSAL_SEM_ERRNO_TRANSFORM (result);

    if (0 == result && 0 >= psem->count)
    {
        int msToWait = SEC_TO_MSEC(timeout->tv_sec) + NSEC_TO_MSEC(timeout->tv_nsec);
        result = ARSAL_Cond_Timedwait (&(psem->cond), &(psem->lock), msToWait);
        ARSAL_SEM_ERRNO_TRANSFORM (result);
    }
    /* No else. */

    if (0 == result)
    {
        if (0 < psem->count)
        {
            (psem->count)--;
        }
        /* No else: don't decrement count below 0. */
    }
    /* No else. */

    unlockRes = ARSAL_Mutex_Unlock (&(psem->lock));
    if (0 != unlockRes)
    {
        result = -1;
        errno = unlockRes;
    }
    /* No else. */

#endif

    return result;
}