/* 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; }
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()); }
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; }