Пример #1
0
static int ALCnullBackend_mixerProc(void *ptr)
{
    ALCnullBackend *self = (ALCnullBackend*)ptr;
    ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
    struct timespec now, start;
    ALuint64 avail, done;
    const long restTime = (long)((ALuint64)device->UpdateSize * 1000000000 /
                                 device->Frequency / 2);

    SetRTPriority();
    althrd_setname(althrd_current(), MIXER_THREAD_NAME);

    done = 0;
    if(altimespec_get(&start, AL_TIME_UTC) != AL_TIME_UTC)
    {
        ERR("Failed to get starting time\n");
        return 1;
    }
    while(!ATOMIC_LOAD(&self->killNow, almemory_order_acquire) &&
          ATOMIC_LOAD(&device->Connected, almemory_order_acquire))
    {
        if(altimespec_get(&now, AL_TIME_UTC) != AL_TIME_UTC)
        {
            ERR("Failed to get current time\n");
            return 1;
        }

        avail  = (now.tv_sec - start.tv_sec) * device->Frequency;
        avail += (ALint64)(now.tv_nsec - start.tv_nsec) * device->Frequency / 1000000000;
        if(avail < done)
        {
            /* Oops, time skipped backwards. Reset the number of samples done
             * with one update available since we (likely) just came back from
             * sleeping. */
            done = avail - device->UpdateSize;
        }

        if(avail-done < device->UpdateSize)
            al_nssleep(restTime);
        else while(avail-done >= device->UpdateSize)
        {
            ALCnullBackend_lock(self);
            aluMixData(device, NULL, device->UpdateSize);
            ALCnullBackend_unlock(self);
            done += device->UpdateSize;
        }
    }

    return 0;
}
Пример #2
0
int almtx_timedlock(almtx_t *mtx, const struct timespec *ts)
{
    int ret;

#ifdef HAVE_PTHREAD_MUTEX_TIMEDLOCK
    ret = pthread_mutex_timedlock(mtx, ts);
    switch(ret)
    {
        case 0: return althrd_success;
        case ETIMEDOUT: return althrd_timedout;
        case EBUSY: return althrd_busy;
    }
    return althrd_error;
#else
    if(!mtx || !ts)
        return althrd_error;

    while((ret=almtx_trylock(mtx)) == althrd_busy)
    {
        struct timespec now;

        if(ts->tv_sec < 0 || ts->tv_nsec < 0 || ts->tv_nsec >= 1000000000 ||
           altimespec_get(&now, AL_TIME_UTC) != AL_TIME_UTC)
            return althrd_error;
        if(now.tv_sec > ts->tv_sec || (now.tv_sec == ts->tv_sec && now.tv_nsec >= ts->tv_nsec))
            return althrd_timedout;

        althrd_yield();
    }

    return ret;
#endif
}
Пример #3
0
int alcnd_timedwait(alcnd_t *cond, almtx_t *mtx, const struct timespec *time_point)
{
    struct timespec curtime;
    DWORD sleeptime;

    if(altimespec_get(&curtime, AL_TIME_UTC) != AL_TIME_UTC)
        return althrd_error;

    sleeptime  = (time_point->tv_nsec - curtime.tv_nsec + 999999)/1000000;
    sleeptime += (time_point->tv_sec - curtime.tv_sec)*1000;
    if(SleepConditionVariableCS(cond, mtx, sleeptime) != 0)
        return althrd_success;
    return (GetLastError()==ERROR_TIMEOUT) ? althrd_timedout : althrd_error;
}
Пример #4
0
int almtx_timedlock(almtx_t *mtx, const struct timespec *ts)
{
    int ret;

    if(!mtx || !ts)
        return althrd_error;

    while((ret=almtx_trylock(mtx)) == althrd_busy)
    {
        struct timespec now;

        if(ts->tv_sec < 0 || ts->tv_nsec < 0 || ts->tv_nsec >= 1000000000 ||
           altimespec_get(&now, AL_TIME_UTC) != AL_TIME_UTC)
            return althrd_error;
        if(now.tv_sec > ts->tv_sec || (now.tv_sec == ts->tv_sec && now.tv_nsec >= ts->tv_nsec))
            return althrd_timedout;

        althrd_yield();
    }

    return ret;
}
Пример #5
0
int alcnd_timedwait(alcnd_t *cond, almtx_t *mtx, const struct timespec *time_point)
{
    _int_alcnd_t *icond = cond->Ptr;
    struct timespec curtime;
    DWORD sleeptime;
    int res;

    if(altimespec_get(&curtime, AL_TIME_UTC) != AL_TIME_UTC)
        return althrd_error;
    sleeptime  = (time_point->tv_nsec - curtime.tv_nsec + 999999)/1000000;
    sleeptime += (time_point->tv_sec - curtime.tv_sec)*1000;

    IncrementRef(&icond->wait_count);
    LeaveCriticalSection(mtx);

    res = WaitForMultipleObjects(2, icond->events, FALSE, sleeptime);

    if(DecrementRef(&icond->wait_count) == 0 && res == WAIT_OBJECT_0+BROADCAST)
        ResetEvent(icond->events[BROADCAST]);
    EnterCriticalSection(mtx);

    return (res == WAIT_TIMEOUT) ? althrd_timedout : althrd_success;
}