SDL  2.0
SDL_syssem.c File Reference
#include "../../SDL_internal.h"
#include <errno.h>
#include <pthread.h>
#include <semaphore.h>
#include <sys/time.h>
#include <time.h>
#include "SDL_thread.h"
#include "SDL_timer.h"
+ Include dependency graph for SDL_syssem.c:

Go to the source code of this file.

Data Structures

struct  SDL_sem

Functions

SDL_sem * SDL_CreateSemaphore (Uint32 initial_value)
void SDL_DestroySemaphore (SDL_sem *sem)
int SDL_SemTryWait (SDL_sem *sem)
int SDL_SemWait (SDL_sem *sem)
int SDL_SemWaitTimeout (SDL_sem *sem, Uint32 timeout)
Uint32 SDL_SemValue (SDL_sem *sem)
int SDL_SemPost (SDL_sem *sem)

Function Documentation

SDL_sem* SDL_CreateSemaphore ( Uint32  initial_value)

Create a semaphore, initialized with value, returns NULL on failure.

Definition at line 46 of file SDL_syssem.c.

References NULL, SDL_free, SDL_malloc, SDL_OutOfMemory, SDL_SetError, and sem.

{
SDL_sem *sem = (SDL_sem *) SDL_malloc(sizeof(SDL_sem));
if (sem) {
if (sem_init(&sem->sem, 0, initial_value) < 0) {
SDL_SetError("sem_init() failed");
SDL_free(sem);
sem = NULL;
}
} else {
}
return sem;
}
void SDL_DestroySemaphore ( SDL_sem *  sem)

Destroy a semaphore.

Definition at line 62 of file SDL_syssem.c.

References SDL_free.

{
if (sem) {
sem_destroy(&sem->sem);
}
}
int SDL_SemPost ( SDL_sem *  sem)

Atomically increases the semaphore's count (not blocking).

Returns
0, or -1 on error.

Definition at line 193 of file SDL_syssem.c.

References retval, and SDL_SetError.

{
int retval;
if (!sem) {
return SDL_SetError("Passed a NULL semaphore");
}
retval = sem_post(&sem->sem);
if (retval < 0) {
SDL_SetError("sem_post() failed");
}
return retval;
}
int SDL_SemTryWait ( SDL_sem *  sem)

Non-blocking variant of SDL_SemWait().

Returns
0 if the wait succeeds, SDL_MUTEX_TIMEDOUT if the wait would block, and -1 on error.

Definition at line 71 of file SDL_syssem.c.

References retval, SDL_MUTEX_TIMEDOUT, and SDL_SetError.

{
int retval;
if (!sem) {
return SDL_SetError("Passed a NULL semaphore");
}
if (sem_trywait(&sem->sem) == 0) {
retval = 0;
}
return retval;
}
Uint32 SDL_SemValue ( SDL_sem *  sem)

Returns the current count of the semaphore.

Definition at line 180 of file SDL_syssem.c.

{
int ret = 0;
if (sem) {
sem_getvalue(&sem->sem, &ret);
if (ret < 0) {
ret = 0;
}
}
return (Uint32) ret;
}
int SDL_SemWait ( SDL_sem *  sem)

This function suspends the calling thread until the semaphore pointed to by sem has a positive count. It then atomically decreases the semaphore count.

Definition at line 86 of file SDL_syssem.c.

References retval, and SDL_SetError.

{
int retval;
if (!sem) {
return SDL_SetError("Passed a NULL semaphore");
}
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  ms 
)

Variant of SDL_SemWait() with a timeout in milliseconds.

Returns
0 if the wait succeeds, SDL_MUTEX_TIMEDOUT if the wait does not succeed in the allotted time, and -1 on error.
Warning
On some platforms this function is implemented by looping with a delay of 1 ms, and so should be avoided if possible.

Definition at line 105 of file SDL_syssem.c.

References NULL, retval, SDL_Delay, SDL_GetTicks(), SDL_MUTEX_MAXWAIT, SDL_MUTEX_TIMEDOUT, SDL_SemTryWait, SDL_SemWait, SDL_SetError, and SDL_TICKS_PASSED.

{
int retval;
#ifdef HAVE_SEM_TIMEDWAIT
#ifndef HAVE_CLOCK_GETTIME
struct timeval now;
#endif
struct timespec ts_timeout;
#else
#endif
if (!sem) {
return SDL_SetError("Passed a NULL semaphore");
}
/* Try the easy cases first */
if (timeout == 0) {
}
return SDL_SemWait(sem);
}
#ifdef HAVE_SEM_TIMEDWAIT
/* Setup the timeout. sem_timedwait doesn't wait for
* a lapse of time, but until we reach a certain time.
* This time is now plus the timeout.
*/
#ifdef HAVE_CLOCK_GETTIME
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;
#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;
#endif
/* Wrap the second if needed */
if (ts_timeout.tv_nsec > 1000000000) {
ts_timeout.tv_sec += 1;
ts_timeout.tv_nsec -= 1000000000;
}
/* Wait. */
do {
retval = sem_timedwait(&sem->sem, &ts_timeout);
} while (retval < 0 && errno == EINTR);
if (retval < 0) {
if (errno == ETIMEDOUT) {
} else {
SDL_SetError("sem_timedwait returned an error: %s", strerror(errno));
}
}
#else
end = SDL_GetTicks() + timeout;
while ((retval = SDL_SemTryWait(sem)) == SDL_MUTEX_TIMEDOUT) {
break;
}
}
#endif /* HAVE_SEM_TIMEDWAIT */
return retval;
}