mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-10-16 06:45:59 +00:00
Convert ticks to 64-bit, added nanosecond precision to the API
Fixes https://github.com/libsdl-org/SDL/issues/5512 Fixes https://github.com/libsdl-org/SDL/issues/6731
This commit is contained in:
@@ -481,4 +481,43 @@ void SDL_DetachThread(SDL_Thread *thread)
|
||||
}
|
||||
}
|
||||
|
||||
int SDL_SemWait(SDL_sem *sem)
|
||||
{
|
||||
return SDL_SemWaitTimeoutNS(sem, SDL_MUTEX_MAXWAIT);
|
||||
}
|
||||
|
||||
int SDL_SemTryWait(SDL_sem *sem)
|
||||
{
|
||||
return SDL_SemWaitTimeoutNS(sem, 0);
|
||||
}
|
||||
|
||||
int SDL_SemWaitTimeout(SDL_sem *sem, Sint32 timeoutMS)
|
||||
{
|
||||
Sint64 timeoutNS;
|
||||
|
||||
if (timeoutMS >= 0) {
|
||||
timeoutNS = SDL_MS_TO_NS(timeoutMS);
|
||||
} else {
|
||||
timeoutNS = -1;
|
||||
}
|
||||
return SDL_SemWaitTimeoutNS(sem, timeoutNS);
|
||||
}
|
||||
|
||||
int SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex)
|
||||
{
|
||||
return SDL_CondWaitTimeoutNS(cond, mutex, SDL_MUTEX_MAXWAIT);
|
||||
}
|
||||
|
||||
int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Sint32 timeoutMS)
|
||||
{
|
||||
Sint64 timeoutNS;
|
||||
|
||||
if (timeoutMS >= 0) {
|
||||
timeoutNS = SDL_MS_TO_NS(timeoutMS);
|
||||
} else {
|
||||
timeoutNS = -1;
|
||||
}
|
||||
return SDL_CondWaitTimeoutNS(cond, mutex, timeoutNS);
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
@@ -37,8 +37,7 @@
|
||||
#define SDL_DestroyCond_generic SDL_DestroyCond
|
||||
#define SDL_CondSignal_generic SDL_CondSignal
|
||||
#define SDL_CondBroadcast_generic SDL_CondBroadcast
|
||||
#define SDL_CondWait_generic SDL_CondWait
|
||||
#define SDL_CondWaitTimeout_generic SDL_CondWaitTimeout
|
||||
#define SDL_CondWaitTimeoutNS_generic SDL_CondWaitTimeoutNS
|
||||
#endif
|
||||
|
||||
typedef struct SDL_cond_generic
|
||||
@@ -148,7 +147,7 @@ int SDL_CondBroadcast_generic(SDL_cond *_cond)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Wait on the condition variable for at most 'ms' milliseconds.
|
||||
/* Wait on the condition variable for at most 'timeoutNS' nanoseconds.
|
||||
The mutex must be locked before entering this function!
|
||||
The mutex is unlocked during the wait, and locked again after the wait.
|
||||
|
||||
@@ -169,7 +168,7 @@ Thread B:
|
||||
SDL_CondSignal(cond);
|
||||
SDL_UnlockMutex(lock);
|
||||
*/
|
||||
int SDL_CondWaitTimeout_generic(SDL_cond *_cond, SDL_mutex *mutex, Uint32 ms)
|
||||
int SDL_CondWaitTimeoutNS_generic(SDL_cond *_cond, SDL_mutex *mutex, Sint64 timeoutNS)
|
||||
{
|
||||
SDL_cond_generic *cond = (SDL_cond_generic *)_cond;
|
||||
int retval;
|
||||
@@ -190,11 +189,7 @@ int SDL_CondWaitTimeout_generic(SDL_cond *_cond, SDL_mutex *mutex, Uint32 ms)
|
||||
SDL_UnlockMutex(mutex);
|
||||
|
||||
/* Wait for a signal */
|
||||
if (ms == SDL_MUTEX_MAXWAIT) {
|
||||
retval = SDL_SemWait(cond->wait_sem);
|
||||
} else {
|
||||
retval = SDL_SemWaitTimeout(cond->wait_sem, ms);
|
||||
}
|
||||
retval = SDL_SemWaitTimeoutNS(cond->wait_sem, timeoutNS);
|
||||
|
||||
/* Let the signaler know we have completed the wait, otherwise
|
||||
the signaler can race ahead and get the condition semaphore
|
||||
@@ -223,10 +218,4 @@ int SDL_CondWaitTimeout_generic(SDL_cond *_cond, SDL_mutex *mutex, Uint32 ms)
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Wait on the condition variable forever */
|
||||
int SDL_CondWait_generic(SDL_cond *cond, SDL_mutex *mutex)
|
||||
{
|
||||
return SDL_CondWaitTimeout_generic(cond, mutex, SDL_MUTEX_MAXWAIT);
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
@@ -29,9 +29,7 @@ SDL_cond *SDL_CreateCond_generic(void);
|
||||
void SDL_DestroyCond_generic(SDL_cond *cond);
|
||||
int SDL_CondSignal_generic(SDL_cond *cond);
|
||||
int SDL_CondBroadcast_generic(SDL_cond *cond);
|
||||
int SDL_CondWait_generic(SDL_cond *cond, SDL_mutex *mutex);
|
||||
int SDL_CondWaitTimeout_generic(SDL_cond *cond,
|
||||
SDL_mutex *mutex, Uint32 ms);
|
||||
int SDL_CondWaitTimeoutNS_generic(SDL_cond *cond, SDL_mutex *mutex, Sint64 timeoutNS);
|
||||
|
||||
#endif /* SDL_THREAD_GENERIC_COND_SUFFIX */
|
||||
|
||||
|
@@ -37,17 +37,7 @@ void SDL_DestroySemaphore(SDL_sem *sem)
|
||||
{
|
||||
}
|
||||
|
||||
int SDL_SemTryWait(SDL_sem *sem)
|
||||
{
|
||||
return SDL_SetError("SDL not built with thread support");
|
||||
}
|
||||
|
||||
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
|
||||
{
|
||||
return SDL_SetError("SDL not built with thread support");
|
||||
}
|
||||
|
||||
int SDL_SemWait(SDL_sem *sem)
|
||||
int SDL_SemWaitTimeoutNS(SDL_sem *sem, Sint64 timeoutNS)
|
||||
{
|
||||
return SDL_SetError("SDL not built with thread support");
|
||||
}
|
||||
@@ -117,26 +107,7 @@ void SDL_DestroySemaphore(SDL_sem *sem)
|
||||
}
|
||||
}
|
||||
|
||||
int SDL_SemTryWait(SDL_sem *sem)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if (sem == NULL) {
|
||||
return SDL_InvalidParamError("sem");
|
||||
}
|
||||
|
||||
retval = SDL_MUTEX_TIMEDOUT;
|
||||
SDL_LockMutex(sem->count_lock);
|
||||
if (sem->count > 0) {
|
||||
--sem->count;
|
||||
retval = 0;
|
||||
}
|
||||
SDL_UnlockMutex(sem->count_lock);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
|
||||
int SDL_SemWaitTimeoutNS(SDL_sem *sem, Sint64 timeoutNS)
|
||||
{
|
||||
int retval;
|
||||
|
||||
@@ -145,16 +116,24 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
|
||||
}
|
||||
|
||||
/* A timeout of 0 is an easy case */
|
||||
if (timeout == 0) {
|
||||
return SDL_SemTryWait(sem);
|
||||
if (timeoutNS == 0) {
|
||||
retval = SDL_MUTEX_TIMEDOUT;
|
||||
SDL_LockMutex(sem->count_lock);
|
||||
if (sem->count > 0) {
|
||||
--sem->count;
|
||||
retval = 0;
|
||||
}
|
||||
SDL_UnlockMutex(sem->count_lock);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
SDL_LockMutex(sem->count_lock);
|
||||
++sem->waiters_count;
|
||||
retval = 0;
|
||||
while ((sem->count == 0) && (retval != SDL_MUTEX_TIMEDOUT)) {
|
||||
retval = SDL_CondWaitTimeout(sem->count_nonzero,
|
||||
sem->count_lock, timeout);
|
||||
retval = SDL_CondWaitTimeoutNS(sem->count_nonzero,
|
||||
sem->count_lock, timeoutNS);
|
||||
}
|
||||
--sem->waiters_count;
|
||||
if (retval == 0) {
|
||||
@@ -165,11 +144,6 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
|
||||
return retval;
|
||||
}
|
||||
|
||||
int SDL_SemWait(SDL_sem *sem)
|
||||
{
|
||||
return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
|
||||
}
|
||||
|
||||
Uint32
|
||||
SDL_SemValue(SDL_sem *sem)
|
||||
{
|
||||
@@ -201,4 +175,5 @@ int SDL_SemPost(SDL_sem *sem)
|
||||
}
|
||||
|
||||
#endif /* SDL_THREADS_DISABLED */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
@@ -74,7 +74,7 @@ int SDL_CondBroadcast(SDL_cond *cond)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Wait on the condition variable for at most 'ms' milliseconds.
|
||||
/* Wait on the condition variable for at most 'timeoutNS' nanoseconds.
|
||||
The mutex must be locked before entering this function!
|
||||
The mutex is unlocked during the wait, and locked again after the wait.
|
||||
|
||||
@@ -95,7 +95,7 @@ Thread B:
|
||||
SDL_CondSignal(cond);
|
||||
SDL_UnlockMutex(lock);
|
||||
*/
|
||||
int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
|
||||
int SDL_CondWaitTimeoutNS(SDL_cond *cond, SDL_mutex *mutex, Sint64 timeoutNS)
|
||||
{
|
||||
Result res;
|
||||
|
||||
@@ -107,22 +107,15 @@ int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
|
||||
}
|
||||
|
||||
res = 0;
|
||||
if (ms == SDL_MUTEX_MAXWAIT) {
|
||||
if (timeoutNS < 0) {
|
||||
CondVar_Wait(&cond->cond_variable, &mutex->lock.lock);
|
||||
} else {
|
||||
res = CondVar_WaitTimeout(&cond->cond_variable, &mutex->lock.lock,
|
||||
(s64)ms * 1000000LL);
|
||||
res = CondVar_WaitTimeout(&cond->cond_variable, &mutex->lock.lock, timeoutNS);
|
||||
}
|
||||
|
||||
return R_SUCCEEDED(res) ? 0 : SDL_MUTEX_TIMEDOUT;
|
||||
}
|
||||
|
||||
/* Wait on the condition variable forever */
|
||||
int SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex)
|
||||
{
|
||||
return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT);
|
||||
}
|
||||
|
||||
#endif /* SDL_THREAD_N3DS */
|
||||
|
||||
/* vi: set sts=4 ts=4 sw=4 expandtab: */
|
||||
|
@@ -62,16 +62,7 @@ void SDL_DestroySemaphore(SDL_sem *sem)
|
||||
}
|
||||
}
|
||||
|
||||
int SDL_SemTryWait(SDL_sem *sem)
|
||||
{
|
||||
if (sem == NULL) {
|
||||
return SDL_InvalidParamError("sem");
|
||||
}
|
||||
|
||||
return SDL_SemWaitTimeout(sem, 0);
|
||||
}
|
||||
|
||||
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
|
||||
int SDL_SemWaitTimeoutNS(SDL_sem *sem, Sint64 timeoutNS)
|
||||
{
|
||||
int retval;
|
||||
|
||||
@@ -79,12 +70,15 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
|
||||
return SDL_InvalidParamError("sem");
|
||||
}
|
||||
|
||||
if (timeout == SDL_MUTEX_MAXWAIT) {
|
||||
if (timeoutNS == SDL_MUTEX_MAXWAIT) {
|
||||
LightSemaphore_Acquire(&sem->semaphore, 1);
|
||||
retval = 0;
|
||||
} else {
|
||||
int return_code = LightSemaphore_TryAcquire(&sem->semaphore, 1);
|
||||
if (return_code != 0) {
|
||||
/* FIXME: Does this code guarantee a wall clock timeout here?
|
||||
* Can we handle sub-millisecond delays? */
|
||||
u32 timeout = (u32)SDL_NS_TO_MS(timeoutNS);
|
||||
for (u32 i = 0; i < timeout; i++) {
|
||||
svcSleepThread(1000000LL);
|
||||
return_code = LightSemaphore_TryAcquire(&sem->semaphore, 1);
|
||||
@@ -99,11 +93,6 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
|
||||
return retval;
|
||||
}
|
||||
|
||||
int SDL_SemWait(SDL_sem *sem)
|
||||
{
|
||||
return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
|
||||
}
|
||||
|
||||
Uint32
|
||||
SDL_SemValue(SDL_sem *sem)
|
||||
{
|
||||
|
@@ -100,19 +100,27 @@ void SDL_DestroySemaphore(SDL_sem *sem)
|
||||
}
|
||||
}
|
||||
|
||||
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
|
||||
int SDL_SemWaitTimeoutNS(SDL_sem *sem, Sint64 timeoutNS)
|
||||
{
|
||||
if (sem == NULL) {
|
||||
return SDL_InvalidParamError("sem");
|
||||
}
|
||||
|
||||
if (timeout == SDL_MUTEX_MAXWAIT) {
|
||||
if (timeoutNS == 0) {
|
||||
if (sem->count > 0) {
|
||||
--sem->count;
|
||||
return 0;
|
||||
}
|
||||
return SDL_MUTEX_TIMEOUT;
|
||||
}
|
||||
|
||||
if (timeoutNS == SDL_MUTEX_MAXWAIT) {
|
||||
WaitAll(sem);
|
||||
return SDL_MUTEX_MAXWAIT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
RThread thread;
|
||||
TInfo *info = new (ELeave) TInfo(timeout, sem->handle);
|
||||
TInfo *info = new (ELeave) TInfo((TInt)SDL_NS_TO_MS(timeoutNS), sem->handle);
|
||||
TInt status = CreateUnique(NewThread, &thread, info);
|
||||
|
||||
if (status != KErrNone) {
|
||||
@@ -130,23 +138,6 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
|
||||
return info->iVal;
|
||||
}
|
||||
|
||||
int SDL_SemTryWait(SDL_sem *sem)
|
||||
{
|
||||
if (sem == NULL) {
|
||||
return SDL_InvalidParamError("sem");
|
||||
}
|
||||
|
||||
if (sem->count > 0) {
|
||||
sem->count--;
|
||||
}
|
||||
return SDL_MUTEX_TIMEOUT;
|
||||
}
|
||||
|
||||
int SDL_SemWait(SDL_sem *sem)
|
||||
{
|
||||
return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
|
||||
}
|
||||
|
||||
Uint32
|
||||
SDL_SemValue(SDL_sem *sem)
|
||||
{
|
||||
|
@@ -79,7 +79,7 @@ void SDL_DestroySemaphore(SDL_sem *sem)
|
||||
}
|
||||
}
|
||||
|
||||
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
|
||||
int SDL_SemWaitTimeoutNS(SDL_sem *sem, Sint64 timeoutNS)
|
||||
{
|
||||
int ret;
|
||||
struct timer_alarm_t alarm;
|
||||
@@ -89,15 +89,15 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
|
||||
return SDL_InvalidParamError("sem");
|
||||
}
|
||||
|
||||
if (timeout == 0) {
|
||||
if (timeoutNS == 0) {
|
||||
if (PollSema(sem->semid) < 0) {
|
||||
return SDL_MUTEX_TIMEDOUT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (timeout != SDL_MUTEX_MAXWAIT) {
|
||||
SetTimerAlarm(&alarm, MSec2TimerBusClock(timeout), &usercb, (void *)GetThreadId());
|
||||
if (timeoutNS != SDL_MUTEX_MAXWAIT) {
|
||||
SetTimerAlarm(&alarm, MSec2TimerBusClock(SDL_NS_TO_MS(timeoutNS)), &usercb, (void *)GetThreadId());
|
||||
}
|
||||
|
||||
ret = WaitSema(sem->semid);
|
||||
@@ -109,16 +109,6 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
|
||||
return 0; // Wait condition satisfied.
|
||||
}
|
||||
|
||||
int SDL_SemTryWait(SDL_sem *sem)
|
||||
{
|
||||
return SDL_SemWaitTimeout(sem, 0);
|
||||
}
|
||||
|
||||
int SDL_SemWait(SDL_sem *sem)
|
||||
{
|
||||
return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
|
||||
}
|
||||
|
||||
/* Returns the current count of the semaphore */
|
||||
Uint32 SDL_SemValue(SDL_sem *sem)
|
||||
{
|
||||
|
@@ -132,7 +132,7 @@ int SDL_CondBroadcast(SDL_cond *cond)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Wait on the condition variable for at most 'ms' milliseconds.
|
||||
/* Wait on the condition variable for at most 'timeoutNS' nanoseconds.
|
||||
The mutex must be locked before entering this function!
|
||||
The mutex is unlocked during the wait, and locked again after the wait.
|
||||
|
||||
@@ -153,7 +153,7 @@ Thread B:
|
||||
SDL_CondSignal(cond);
|
||||
SDL_UnlockMutex(lock);
|
||||
*/
|
||||
int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
|
||||
int SDL_CondWaitTimeoutNS(SDL_cond *cond, SDL_mutex *mutex, Sint64 timeoutNS)
|
||||
{
|
||||
int retval;
|
||||
|
||||
@@ -173,11 +173,7 @@ int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
|
||||
SDL_UnlockMutex(mutex);
|
||||
|
||||
/* Wait for a signal */
|
||||
if (ms == SDL_MUTEX_MAXWAIT) {
|
||||
retval = SDL_SemWait(cond->wait_sem);
|
||||
} else {
|
||||
retval = SDL_SemWaitTimeout(cond->wait_sem, ms);
|
||||
}
|
||||
retval = SDL_SemWaitTimeout(cond->wait_sem, timeoutNS);
|
||||
|
||||
/* Let the signaler know we have completed the wait, otherwise
|
||||
the signaler can race ahead and get the condition semaphore
|
||||
@@ -206,12 +202,6 @@ int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Wait on the condition variable forever */
|
||||
int SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex)
|
||||
{
|
||||
return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT);
|
||||
}
|
||||
|
||||
#endif /* SDL_THREAD_PSP */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
@@ -73,16 +73,17 @@ void SDL_DestroySemaphore(SDL_sem *sem)
|
||||
* If the timeout is 0 then just poll the semaphore; if it's SDL_MUTEX_MAXWAIT, pass
|
||||
* NULL to sceKernelWaitSema() so that it waits indefinitely; and if the timeout
|
||||
* is specified, convert it to microseconds. */
|
||||
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
|
||||
int SDL_SemWaitTimeoutNS(SDL_sem *sem, Sint64 timeoutNS)
|
||||
{
|
||||
Uint32 *pTimeout;
|
||||
SceUInt timeoutUS;
|
||||
SceUInt *pTimeout;
|
||||
int res;
|
||||
|
||||
if (sem == NULL) {
|
||||
return SDL_InvalidParamError("sem");
|
||||
}
|
||||
|
||||
if (timeout == 0) {
|
||||
if (timeoutNS == 0) {
|
||||
res = sceKernelPollSema(sem->semid, 1);
|
||||
if (res < 0) {
|
||||
return SDL_MUTEX_TIMEDOUT;
|
||||
@@ -90,14 +91,14 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (timeout == SDL_MUTEX_MAXWAIT) {
|
||||
if (timeoutNS < 0) {
|
||||
pTimeout = NULL;
|
||||
} else {
|
||||
timeout *= 1000; /* Convert to microseconds. */
|
||||
pTimeout = &timeout;
|
||||
timeoutUS = (SceUInt)SDL_NS_TO_US(timeoutNS); /* Convert to microseconds. */
|
||||
pTimeout = &timeoutUS;
|
||||
}
|
||||
|
||||
res = sceKernelWaitSema(sem->semid, 1, (SceUInt *)pTimeout);
|
||||
res = sceKernelWaitSema(sem->semid, 1, pTimeout);
|
||||
switch (res) {
|
||||
case SCE_KERNEL_ERROR_OK:
|
||||
return 0;
|
||||
@@ -108,16 +109,6 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
|
||||
}
|
||||
}
|
||||
|
||||
int SDL_SemTryWait(SDL_sem *sem)
|
||||
{
|
||||
return SDL_SemWaitTimeout(sem, 0);
|
||||
}
|
||||
|
||||
int SDL_SemWait(SDL_sem *sem)
|
||||
{
|
||||
return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
|
||||
}
|
||||
|
||||
/* Returns the current count of the semaphore */
|
||||
Uint32 SDL_SemValue(SDL_sem *sem)
|
||||
{
|
||||
|
@@ -91,7 +91,7 @@ int SDL_CondBroadcast(SDL_cond *cond)
|
||||
return retval;
|
||||
}
|
||||
|
||||
int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
|
||||
int SDL_CondWaitTimeoutNS(SDL_cond *cond, SDL_mutex *mutex, Sint64 timeoutNS)
|
||||
{
|
||||
int retval;
|
||||
#ifndef HAVE_CLOCK_GETTIME
|
||||
@@ -103,18 +103,25 @@ int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
|
||||
return SDL_InvalidParamError("cond");
|
||||
}
|
||||
|
||||
if (timeoutNS < 0) {
|
||||
if (pthread_cond_wait(&cond->cond, &mutex->id) != 0) {
|
||||
return SDL_SetError("pthread_cond_wait() failed");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_CLOCK_GETTIME
|
||||
clock_gettime(CLOCK_REALTIME, &abstime);
|
||||
|
||||
abstime.tv_nsec += (ms % 1000) * 1000000;
|
||||
abstime.tv_sec += ms / 1000;
|
||||
abstime.tv_sec += (timeoutNS / SDL_NS_PER_SECOND);
|
||||
abstime.tv_nsec += (timeoutNS % SDL_NS_PER_SECOND);
|
||||
#else
|
||||
gettimeofday(&delta, NULL);
|
||||
|
||||
abstime.tv_sec = delta.tv_sec + (ms / 1000);
|
||||
abstime.tv_nsec = (long)(delta.tv_usec + (ms % 1000) * 1000) * 1000;
|
||||
abstime.tv_sec = delta.tv_sec + (timeoutNS / SDL_NS_PER_SECOND);
|
||||
abstime.tv_nsec = SDL_US_TO_NS(delta.tv_usec) + (timeoutNS % SDL_NS_PER_SECOND);
|
||||
#endif
|
||||
if (abstime.tv_nsec > 1000000000) {
|
||||
while (abstime.tv_nsec > 1000000000) {
|
||||
abstime.tv_sec += 1;
|
||||
abstime.tv_nsec -= 1000000000;
|
||||
}
|
||||
@@ -136,17 +143,4 @@ tryagain:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Wait on the condition variable, unlocking the provided mutex.
|
||||
The mutex must be locked before entering this function!
|
||||
*/
|
||||
int SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex)
|
||||
{
|
||||
if (cond == NULL) {
|
||||
return SDL_InvalidParamError("cond");
|
||||
} else if (pthread_cond_wait(&cond->cond, &mutex->id) != 0) {
|
||||
return SDL_SetError("pthread_cond_wait() failed");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
@@ -63,39 +63,7 @@ void SDL_DestroySemaphore(SDL_sem *sem)
|
||||
}
|
||||
}
|
||||
|
||||
int SDL_SemTryWait(SDL_sem *sem)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if (sem == NULL) {
|
||||
return SDL_InvalidParamError("sem");
|
||||
}
|
||||
retval = SDL_MUTEX_TIMEDOUT;
|
||||
if (sem_trywait(&sem->sem) == 0) {
|
||||
retval = 0;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
int SDL_SemWait(SDL_sem *sem)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if (sem == NULL) {
|
||||
return SDL_InvalidParamError("sem");
|
||||
}
|
||||
|
||||
do {
|
||||
retval = sem_wait(&sem->sem);
|
||||
} while (retval < 0 && errno == EINTR);
|
||||
|
||||
if (retval < 0) {
|
||||
retval = SDL_SetError("sem_wait() failed");
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
|
||||
int SDL_SemWaitTimeoutNS(SDL_sem *sem, Sint64 timeoutNS)
|
||||
{
|
||||
int retval;
|
||||
#ifdef HAVE_SEM_TIMEDWAIT
|
||||
@@ -104,7 +72,7 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
|
||||
#endif
|
||||
struct timespec ts_timeout;
|
||||
#else
|
||||
Uint32 end;
|
||||
Uint64 end;
|
||||
#endif
|
||||
|
||||
if (sem == NULL) {
|
||||
@@ -112,11 +80,22 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
|
||||
}
|
||||
|
||||
/* Try the easy cases first */
|
||||
if (timeout == 0) {
|
||||
return SDL_SemTryWait(sem);
|
||||
if (timeoutNS == 0) {
|
||||
retval = SDL_MUTEX_TIMEDOUT;
|
||||
if (sem_trywait(&sem->sem) == 0) {
|
||||
retval = 0;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
if (timeout == SDL_MUTEX_MAXWAIT) {
|
||||
return SDL_SemWait(sem);
|
||||
if (timeoutNS < 0) {
|
||||
do {
|
||||
retval = sem_wait(&sem->sem);
|
||||
} while (retval < 0 && errno == EINTR);
|
||||
|
||||
if (retval < 0) {
|
||||
retval = SDL_SetError("sem_wait() failed");
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
#ifdef HAVE_SEM_TIMEDWAIT
|
||||
@@ -128,18 +107,18 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
|
||||
clock_gettime(CLOCK_REALTIME, &ts_timeout);
|
||||
|
||||
/* Add our timeout to current time */
|
||||
ts_timeout.tv_nsec += (timeout % 1000) * 1000000;
|
||||
ts_timeout.tv_sec += timeout / 1000;
|
||||
ts_timeout.tv_sec += (timeoutNS / SDL_NS_PER_SECOND);
|
||||
ts_timeout.tv_nsec += (timeoutNS % SDL_NS_PER_SECOND);
|
||||
#else
|
||||
gettimeofday(&now, NULL);
|
||||
|
||||
/* Add our timeout to current time */
|
||||
ts_timeout.tv_sec = now.tv_sec + (timeout / 1000);
|
||||
ts_timeout.tv_nsec = (now.tv_usec + (timeout % 1000) * 1000) * 1000;
|
||||
ts_timeout.tv_sec = now.tv_sec + (timeoutNS / SDL_NS_PER_SECOND);
|
||||
ts_timeout.tv_nsec = SDL_US_TO_NS(now.tv_usec) + (timeoutNS % SDL_NS_PER_SECOND);
|
||||
#endif
|
||||
|
||||
/* Wrap the second if needed */
|
||||
if (ts_timeout.tv_nsec > 1000000000) {
|
||||
while (ts_timeout.tv_nsec > 1000000000) {
|
||||
ts_timeout.tv_sec += 1;
|
||||
ts_timeout.tv_nsec -= 1000000000;
|
||||
}
|
||||
@@ -157,12 +136,13 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
|
||||
}
|
||||
}
|
||||
#else
|
||||
end = SDL_GetTicks() + timeout;
|
||||
while ((retval = SDL_SemTryWait(sem)) == SDL_MUTEX_TIMEDOUT) {
|
||||
if (SDL_TICKS_PASSED(SDL_GetTicks(), end)) {
|
||||
end = SDL_GetTicksNS() + timeoutNS;
|
||||
while (sem_trywait(&sem->sem) != 0) {
|
||||
if (SDL_GetTicksNS() >= end) {
|
||||
retval = SDL_MUTEX_TIMEDOUT;
|
||||
break;
|
||||
}
|
||||
SDL_Delay(1);
|
||||
SDL_DelayNS(100);
|
||||
}
|
||||
#endif /* HAVE_SEM_TIMEDWAIT */
|
||||
|
||||
|
@@ -85,7 +85,7 @@ SDL_CondBroadcast(SDL_cond *cond)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Wait on the condition variable for at most 'ms' milliseconds.
|
||||
/* Wait on the condition variable for at most 'timeoutNS' nanoseconds.
|
||||
The mutex must be locked before entering this function!
|
||||
The mutex is unlocked during the wait, and locked again after the wait.
|
||||
|
||||
@@ -107,7 +107,7 @@ Thread B:
|
||||
SDL_UnlockMutex(lock);
|
||||
*/
|
||||
extern "C" int
|
||||
SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
|
||||
SDL_CondWaitTimeoutNS(SDL_cond *cond, SDL_mutex *mutex, Sint64 timeoutNS)
|
||||
{
|
||||
if (cond == NULL) {
|
||||
return SDL_InvalidParamError("cond");
|
||||
@@ -119,7 +119,7 @@ SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
|
||||
|
||||
try {
|
||||
std::unique_lock<std::recursive_mutex> cpp_lock(mutex->cpp_mutex, std::adopt_lock_t());
|
||||
if (ms == SDL_MUTEX_MAXWAIT) {
|
||||
if (timeoutNS < 0) {
|
||||
cond->cpp_cond.wait(
|
||||
cpp_lock);
|
||||
cpp_lock.release();
|
||||
@@ -127,7 +127,7 @@ SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
|
||||
} else {
|
||||
auto wait_result = cond->cpp_cond.wait_for(
|
||||
cpp_lock,
|
||||
std::chrono::duration<Uint32, std::milli>(ms));
|
||||
std::chrono::duration<Sint64, std::nano>(timeoutNS));
|
||||
cpp_lock.release();
|
||||
if (wait_result == std::cv_status::timeout) {
|
||||
return SDL_MUTEX_TIMEDOUT;
|
||||
@@ -136,15 +136,8 @@ SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
|
||||
}
|
||||
}
|
||||
} catch (std::system_error &ex) {
|
||||
return SDL_SetError("unable to wait on a C++ condition variable: code=%d; %s", ex.code(), ex.what());
|
||||
return SDL_SetError("Unable to wait on a C++ condition variable: code=%d; %s", ex.code(), ex.what());
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait on the condition variable forever */
|
||||
extern "C" int
|
||||
SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex)
|
||||
{
|
||||
return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT);
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
@@ -132,7 +132,7 @@ int SDL_CondBroadcast(SDL_cond *cond)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Wait on the condition variable for at most 'ms' milliseconds.
|
||||
/* Wait on the condition variable for at most 'timeoutNS' nanoseconds.
|
||||
The mutex must be locked before entering this function!
|
||||
The mutex is unlocked during the wait, and locked again after the wait.
|
||||
|
||||
@@ -153,7 +153,7 @@ Thread B:
|
||||
SDL_CondSignal(cond);
|
||||
SDL_UnlockMutex(lock);
|
||||
*/
|
||||
int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
|
||||
int SDL_CondWaitTimeoutNS(SDL_cond *cond, SDL_mutex *mutex, Sint64 timeoutNS)
|
||||
{
|
||||
int retval;
|
||||
|
||||
@@ -173,11 +173,7 @@ int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
|
||||
SDL_UnlockMutex(mutex);
|
||||
|
||||
/* Wait for a signal */
|
||||
if (ms == SDL_MUTEX_MAXWAIT) {
|
||||
retval = SDL_SemWait(cond->wait_sem);
|
||||
} else {
|
||||
retval = SDL_SemWaitTimeout(cond->wait_sem, ms);
|
||||
}
|
||||
retval = SDL_SemWaitTimeoutNS(cond->wait_sem, timeoutNS);
|
||||
|
||||
/* Let the signaler know we have completed the wait, otherwise
|
||||
the signaler can race ahead and get the condition semaphore
|
||||
@@ -206,12 +202,6 @@ int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Wait on the condition variable forever */
|
||||
int SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex)
|
||||
{
|
||||
return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT);
|
||||
}
|
||||
|
||||
#endif /* SDL_THREAD_VITA */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
@@ -74,16 +74,17 @@ void SDL_DestroySemaphore(SDL_sem *sem)
|
||||
* If the timeout is 0 then just poll the semaphore; if it's SDL_MUTEX_MAXWAIT, pass
|
||||
* NULL to sceKernelWaitSema() so that it waits indefinitely; and if the timeout
|
||||
* is specified, convert it to microseconds. */
|
||||
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
|
||||
int SDL_SemWaitTimeoutNS(SDL_sem *sem, Sint64 timeoutNS)
|
||||
{
|
||||
Uint32 *pTimeout;
|
||||
SceUInt timeoutUS;
|
||||
SceUInt *pTimeout;
|
||||
int res;
|
||||
|
||||
if (sem == NULL) {
|
||||
return SDL_InvalidParamError("sem");
|
||||
}
|
||||
|
||||
if (timeout == 0) {
|
||||
if (timeoutNS == 0) {
|
||||
res = sceKernelPollSema(sem->semid, 1);
|
||||
if (res < 0) {
|
||||
return SDL_MUTEX_TIMEDOUT;
|
||||
@@ -91,11 +92,11 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (timeout == SDL_MUTEX_MAXWAIT) {
|
||||
if (timeoutNS < 0) {
|
||||
pTimeout = NULL;
|
||||
} else {
|
||||
timeout *= 1000; /* Convert to microseconds. */
|
||||
pTimeout = &timeout;
|
||||
timeoutUS = (SceUInt)SDL_NS_TO_US(timeoutNS); /* Convert to microseconds. */
|
||||
pTimeout = &timeoutUS;
|
||||
}
|
||||
|
||||
res = sceKernelWaitSema(sem->semid, 1, pTimeout);
|
||||
@@ -105,20 +106,10 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
|
||||
case SCE_KERNEL_ERROR_WAIT_TIMEOUT:
|
||||
return SDL_MUTEX_TIMEDOUT;
|
||||
default:
|
||||
return SDL_SetError("WaitForSingleObject() failed");
|
||||
return SDL_SetError("sceKernelWaitSema() failed");
|
||||
}
|
||||
}
|
||||
|
||||
int SDL_SemTryWait(SDL_sem *sem)
|
||||
{
|
||||
return SDL_SemWaitTimeout(sem, 0);
|
||||
}
|
||||
|
||||
int SDL_SemWait(SDL_sem *sem)
|
||||
{
|
||||
return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
|
||||
}
|
||||
|
||||
/* Returns the current count of the semaphore */
|
||||
Uint32 SDL_SemValue(SDL_sem *sem)
|
||||
{
|
||||
|
@@ -27,8 +27,7 @@ typedef SDL_cond *(*pfnSDL_CreateCond)(void);
|
||||
typedef void (*pfnSDL_DestroyCond)(SDL_cond *);
|
||||
typedef int (*pfnSDL_CondSignal)(SDL_cond *);
|
||||
typedef int (*pfnSDL_CondBroadcast)(SDL_cond *);
|
||||
typedef int (*pfnSDL_CondWait)(SDL_cond *, SDL_mutex *);
|
||||
typedef int (*pfnSDL_CondWaitTimeout)(SDL_cond *, SDL_mutex *, Uint32);
|
||||
typedef int (*pfnSDL_CondWaitTimeoutNS)(SDL_cond *, SDL_mutex *, Sint64);
|
||||
|
||||
typedef struct SDL_cond_impl_t
|
||||
{
|
||||
@@ -36,8 +35,7 @@ typedef struct SDL_cond_impl_t
|
||||
pfnSDL_DestroyCond Destroy;
|
||||
pfnSDL_CondSignal Signal;
|
||||
pfnSDL_CondBroadcast Broadcast;
|
||||
pfnSDL_CondWait Wait;
|
||||
pfnSDL_CondWaitTimeout WaitTimeout;
|
||||
pfnSDL_CondWaitTimeoutNS WaitTimeoutNS;
|
||||
} SDL_cond_impl_t;
|
||||
|
||||
/* Implementation will be chosen at runtime based on available Kernel features */
|
||||
@@ -125,7 +123,7 @@ static int SDL_CondBroadcast_cv(SDL_cond *_cond)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int SDL_CondWaitTimeout_cv(SDL_cond *_cond, SDL_mutex *_mutex, Uint32 ms)
|
||||
static int SDL_CondWaitTimeoutNS_cv(SDL_cond *_cond, SDL_mutex *_mutex, Sint64 timeoutNS)
|
||||
{
|
||||
SDL_cond_cv *cond = (SDL_cond_cv *)_cond;
|
||||
DWORD timeout;
|
||||
@@ -138,10 +136,10 @@ static int SDL_CondWaitTimeout_cv(SDL_cond *_cond, SDL_mutex *_mutex, Uint32 ms)
|
||||
return SDL_InvalidParamError("mutex");
|
||||
}
|
||||
|
||||
if (ms == SDL_MUTEX_MAXWAIT) {
|
||||
if (timeoutNS < 0) {
|
||||
timeout = INFINITE;
|
||||
} else {
|
||||
timeout = (DWORD)ms;
|
||||
timeout = (DWORD)SDL_NS_TO_MS(timeoutNS);
|
||||
}
|
||||
|
||||
if (SDL_mutex_impl_active.Type == SDL_MUTEX_SRW) {
|
||||
@@ -188,18 +186,12 @@ static int SDL_CondWaitTimeout_cv(SDL_cond *_cond, SDL_mutex *_mutex, Uint32 ms)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int SDL_CondWait_cv(SDL_cond *cond, SDL_mutex *mutex)
|
||||
{
|
||||
return SDL_CondWaitTimeout_cv(cond, mutex, SDL_MUTEX_MAXWAIT);
|
||||
}
|
||||
|
||||
static const SDL_cond_impl_t SDL_cond_impl_cv = {
|
||||
&SDL_CreateCond_cv,
|
||||
&SDL_DestroyCond_cv,
|
||||
&SDL_CondSignal_cv,
|
||||
&SDL_CondBroadcast_cv,
|
||||
&SDL_CondWait_cv,
|
||||
&SDL_CondWaitTimeout_cv,
|
||||
&SDL_CondWaitTimeoutNS_cv,
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -211,8 +203,7 @@ static const SDL_cond_impl_t SDL_cond_impl_generic = {
|
||||
&SDL_DestroyCond_generic,
|
||||
&SDL_CondSignal_generic,
|
||||
&SDL_CondBroadcast_generic,
|
||||
&SDL_CondWait_generic,
|
||||
&SDL_CondWaitTimeout_generic,
|
||||
&SDL_CondWaitTimeoutNS_generic,
|
||||
};
|
||||
|
||||
SDL_cond *
|
||||
@@ -272,14 +263,9 @@ int SDL_CondBroadcast(SDL_cond *cond)
|
||||
return SDL_cond_impl_active.Broadcast(cond);
|
||||
}
|
||||
|
||||
int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
|
||||
int SDL_CondWaitTimeoutNS(SDL_cond *cond, SDL_mutex *mutex, Sint64 timeoutNS)
|
||||
{
|
||||
return SDL_cond_impl_active.WaitTimeout(cond, mutex, ms);
|
||||
}
|
||||
|
||||
int SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex)
|
||||
{
|
||||
return SDL_cond_impl_active.Wait(cond, mutex);
|
||||
return SDL_cond_impl_active.WaitTimeoutNS(cond, mutex, timeoutNS);
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
@@ -37,9 +37,7 @@
|
||||
|
||||
typedef SDL_sem *(*pfnSDL_CreateSemaphore)(Uint32);
|
||||
typedef void (*pfnSDL_DestroySemaphore)(SDL_sem *);
|
||||
typedef int (*pfnSDL_SemWaitTimeout)(SDL_sem *, Uint32);
|
||||
typedef int (*pfnSDL_SemTryWait)(SDL_sem *);
|
||||
typedef int (*pfnSDL_SemWait)(SDL_sem *);
|
||||
typedef int (*pfnSDL_SemWaitTimeoutNS)(SDL_sem *, Sint64);
|
||||
typedef Uint32 (*pfnSDL_SemValue)(SDL_sem *);
|
||||
typedef int (*pfnSDL_SemPost)(SDL_sem *);
|
||||
|
||||
@@ -47,9 +45,7 @@ typedef struct SDL_semaphore_impl_t
|
||||
{
|
||||
pfnSDL_CreateSemaphore Create;
|
||||
pfnSDL_DestroySemaphore Destroy;
|
||||
pfnSDL_SemWaitTimeout WaitTimeout;
|
||||
pfnSDL_SemTryWait TryWait;
|
||||
pfnSDL_SemWait Wait;
|
||||
pfnSDL_SemWaitTimeoutNS WaitTimeoutNS;
|
||||
pfnSDL_SemValue Value;
|
||||
pfnSDL_SemPost Post;
|
||||
} SDL_sem_impl_t;
|
||||
@@ -108,81 +104,60 @@ static void SDL_DestroySemaphore_atom(SDL_sem *sem)
|
||||
}
|
||||
}
|
||||
|
||||
static int SDL_SemTryWait_atom(SDL_sem *_sem)
|
||||
static int SDL_SemWaitTimeoutNS_atom(SDL_sem *_sem, Sint64 timeoutNS)
|
||||
{
|
||||
SDL_sem_atom *sem = (SDL_sem_atom *)_sem;
|
||||
LONG count;
|
||||
Uint64 now;
|
||||
Uint64 deadline;
|
||||
DWORD timeout_eff;
|
||||
|
||||
if (sem == NULL) {
|
||||
return SDL_InvalidParamError("sem");
|
||||
}
|
||||
|
||||
count = sem->count;
|
||||
if (count == 0) {
|
||||
return SDL_MUTEX_TIMEDOUT;
|
||||
}
|
||||
|
||||
if (InterlockedCompareExchange(&sem->count, count - 1, count) == count) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return SDL_MUTEX_TIMEDOUT;
|
||||
}
|
||||
|
||||
static int SDL_SemWait_atom(SDL_sem *_sem)
|
||||
{
|
||||
SDL_sem_atom *sem = (SDL_sem_atom *)_sem;
|
||||
LONG count;
|
||||
|
||||
if (sem == NULL) {
|
||||
return SDL_InvalidParamError("sem");
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
if (timeoutNS == 0) {
|
||||
count = sem->count;
|
||||
while (count == 0) {
|
||||
if (pWaitOnAddress(&sem->count, &count, sizeof(sem->count), INFINITE) == FALSE) {
|
||||
return SDL_SetError("WaitOnAddress() failed");
|
||||
}
|
||||
count = sem->count;
|
||||
if (count == 0) {
|
||||
return SDL_MUTEX_TIMEDOUT;
|
||||
}
|
||||
|
||||
if (InterlockedCompareExchange(&sem->count, count - 1, count) == count) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return SDL_MUTEX_TIMEDOUT;
|
||||
}
|
||||
}
|
||||
if (timeoutNS < 0) {
|
||||
for (;;) {
|
||||
count = sem->count;
|
||||
while (count == 0) {
|
||||
if (pWaitOnAddress(&sem->count, &count, sizeof(sem->count), INFINITE) == FALSE) {
|
||||
return SDL_SetError("WaitOnAddress() failed");
|
||||
}
|
||||
count = sem->count;
|
||||
}
|
||||
|
||||
static int SDL_SemWaitTimeout_atom(SDL_sem *_sem, Uint32 timeout)
|
||||
{
|
||||
SDL_sem_atom *sem = (SDL_sem_atom *)_sem;
|
||||
LONG count;
|
||||
Uint32 now;
|
||||
Uint32 deadline;
|
||||
DWORD timeout_eff;
|
||||
|
||||
if (timeout == SDL_MUTEX_MAXWAIT) {
|
||||
return SDL_SemWait_atom(_sem);
|
||||
}
|
||||
|
||||
if (sem == NULL) {
|
||||
return SDL_InvalidParamError("sem");
|
||||
if (InterlockedCompareExchange(&sem->count, count - 1, count) == count) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* WaitOnAddress is subject to spurious and stolen wakeups so we
|
||||
* need to recalculate the effective timeout before every wait
|
||||
*/
|
||||
now = SDL_GetTicks();
|
||||
deadline = now + (DWORD)timeout;
|
||||
now = SDL_GetTicksNS();
|
||||
deadline = now + timeoutNS;
|
||||
|
||||
for (;;) {
|
||||
count = sem->count;
|
||||
/* If no semaphore is available we need to wait */
|
||||
while (count == 0) {
|
||||
now = SDL_GetTicks();
|
||||
now = SDL_GetTicksNS();
|
||||
if (deadline > now) {
|
||||
timeout_eff = deadline - now;
|
||||
timeout_eff = (DWORD)SDL_NS_TO_MS(deadline - now);
|
||||
} else {
|
||||
return SDL_MUTEX_TIMEDOUT;
|
||||
}
|
||||
@@ -232,9 +207,7 @@ static int SDL_SemPost_atom(SDL_sem *_sem)
|
||||
static const SDL_sem_impl_t SDL_sem_impl_atom = {
|
||||
&SDL_CreateSemaphore_atom,
|
||||
&SDL_DestroySemaphore_atom,
|
||||
&SDL_SemWaitTimeout_atom,
|
||||
&SDL_SemTryWait_atom,
|
||||
&SDL_SemWait_atom,
|
||||
&SDL_SemWaitTimeoutNS_atom,
|
||||
&SDL_SemValue_atom,
|
||||
&SDL_SemPost_atom,
|
||||
};
|
||||
@@ -289,7 +262,7 @@ static void SDL_DestroySemaphore_kern(SDL_sem *_sem)
|
||||
}
|
||||
}
|
||||
|
||||
static int SDL_SemWaitTimeout_kern(SDL_sem *_sem, Uint32 timeout)
|
||||
static int SDL_SemWaitTimeoutNS_kern(SDL_sem *_sem, Sint64 timeoutNS)
|
||||
{
|
||||
SDL_sem_kern *sem = (SDL_sem_kern *)_sem;
|
||||
int retval;
|
||||
@@ -299,10 +272,10 @@ static int SDL_SemWaitTimeout_kern(SDL_sem *_sem, Uint32 timeout)
|
||||
return SDL_InvalidParamError("sem");
|
||||
}
|
||||
|
||||
if (timeout == SDL_MUTEX_MAXWAIT) {
|
||||
if (timeoutNS < 0) {
|
||||
dwMilliseconds = INFINITE;
|
||||
} else {
|
||||
dwMilliseconds = (DWORD)timeout;
|
||||
dwMilliseconds = (DWORD)SDL_NS_TO_MS(timeoutNS);
|
||||
}
|
||||
switch (WaitForSingleObjectEx(sem->id, dwMilliseconds, FALSE)) {
|
||||
case WAIT_OBJECT_0:
|
||||
@@ -319,16 +292,6 @@ static int SDL_SemWaitTimeout_kern(SDL_sem *_sem, Uint32 timeout)
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int SDL_SemTryWait_kern(SDL_sem *sem)
|
||||
{
|
||||
return SDL_SemWaitTimeout_kern(sem, 0);
|
||||
}
|
||||
|
||||
static int SDL_SemWait_kern(SDL_sem *sem)
|
||||
{
|
||||
return SDL_SemWaitTimeout_kern(sem, SDL_MUTEX_MAXWAIT);
|
||||
}
|
||||
|
||||
/* Returns the current count of the semaphore */
|
||||
static Uint32 SDL_SemValue_kern(SDL_sem *_sem)
|
||||
{
|
||||
@@ -362,9 +325,7 @@ static int SDL_SemPost_kern(SDL_sem *_sem)
|
||||
static const SDL_sem_impl_t SDL_sem_impl_kern = {
|
||||
&SDL_CreateSemaphore_kern,
|
||||
&SDL_DestroySemaphore_kern,
|
||||
&SDL_SemWaitTimeout_kern,
|
||||
&SDL_SemTryWait_kern,
|
||||
&SDL_SemWait_kern,
|
||||
&SDL_SemWaitTimeoutNS_kern,
|
||||
&SDL_SemValue_kern,
|
||||
&SDL_SemPost_kern,
|
||||
};
|
||||
@@ -417,19 +378,9 @@ void SDL_DestroySemaphore(SDL_sem *sem)
|
||||
SDL_sem_impl_active.Destroy(sem);
|
||||
}
|
||||
|
||||
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
|
||||
int SDL_SemWaitTimeoutNS(SDL_sem *sem, Sint64 timeoutNS)
|
||||
{
|
||||
return SDL_sem_impl_active.WaitTimeout(sem, timeout);
|
||||
}
|
||||
|
||||
int SDL_SemTryWait(SDL_sem *sem)
|
||||
{
|
||||
return SDL_sem_impl_active.TryWait(sem);
|
||||
}
|
||||
|
||||
int SDL_SemWait(SDL_sem *sem)
|
||||
{
|
||||
return SDL_sem_impl_active.Wait(sem);
|
||||
return SDL_sem_impl_active.WaitTimeoutNS(sem, timeoutNS);
|
||||
}
|
||||
|
||||
Uint32
|
||||
|
Reference in New Issue
Block a user