Ejemplo n.º 1
0
int ARSAL_Cond_Timedwait(ARSAL_Cond_t *cond, ARSAL_Mutex_t *mutex, int timeout)
{
    int result = 0;
    struct timespec ts;
    ARSAL_Time_GetLocalTime(&ts, NULL);
    ts.tv_nsec += MSEC_TO_NSEC(timeout % SEC_TO_MSEC(1));
    ts.tv_sec  += MSEC_TO_SEC(timeout);
    ts.tv_sec  += NSEC_TO_SEC(ts.tv_nsec);
    ts.tv_nsec %= SEC_TO_NSEC(1);

#if defined(HAVE_PTHREAD_H)
    result = pthread_cond_timedwait((pthread_cond_t *)*cond, (pthread_mutex_t *)*mutex, &ts);
    if ( (result != 0) && (result != ETIMEDOUT) )
    {
        ARSAL_PRINT(ARSAL_PRINT_FATAL, ARSAL_MUTEX_TAG, "Mutex/Cond operation failed! errno = %d , %s ; thread_id = %d",
                    result,
                    strerror(result),
#if HAVE_DECL_SYS_GETTID
                    syscall(SYS_gettid)
#else
                    0
#endif
            );
    }
#endif

    return result;
}
Ejemplo n.º 2
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;
}