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_CreateSemaphore()

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 SDL_sem::sem.

47 {
48  SDL_sem *sem = (SDL_sem *) SDL_malloc(sizeof(SDL_sem));
49  if (sem) {
50  if (sem_init(&sem->sem, 0, initial_value) < 0) {
51  SDL_SetError("sem_init() failed");
52  SDL_free(sem);
53  sem = NULL;
54  }
55  } else {
57  }
58  return sem;
59 }
static SDL_sem * sem
Definition: testsem.c:23
void SDL_free(void *mem)
#define NULL
Definition: begin_code.h:164
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
#define SDL_SetError
#define SDL_malloc

◆ SDL_DestroySemaphore()

void SDL_DestroySemaphore ( SDL_sem *  sem)

Destroy a semaphore.

Definition at line 62 of file SDL_syssem.c.

References SDL_free().

63 {
64  if (sem) {
65  sem_destroy(&sem->sem);
66  SDL_free(sem);
67  }
68 }
static SDL_sem * sem
Definition: testsem.c:23
void SDL_free(void *mem)

◆ SDL_SemPost()

int SDL_SemPost ( SDL_sem *  sem)

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

Returns
0, or -1 on error.

Definition at line 190 of file SDL_syssem.c.

References retval, and SDL_SetError.

191 {
192  int retval;
193 
194  if (!sem) {
195  return SDL_SetError("Passed a NULL semaphore");
196  }
197 
198  retval = sem_post(&sem->sem);
199  if (retval < 0) {
200  SDL_SetError("sem_post() failed");
201  }
202  return retval;
203 }
static SDL_sem * sem
Definition: testsem.c:23
SDL_bool retval
#define SDL_SetError

◆ SDL_SemTryWait()

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.

72 {
73  int retval;
74 
75  if (!sem) {
76  return SDL_SetError("Passed a NULL semaphore");
77  }
78  retval = SDL_MUTEX_TIMEDOUT;
79  if (sem_trywait(&sem->sem) == 0) {
80  retval = 0;
81  }
82  return retval;
83 }
static SDL_sem * sem
Definition: testsem.c:23
#define SDL_MUTEX_TIMEDOUT
Definition: SDL_mutex.h:44
SDL_bool retval
#define SDL_SetError

◆ SDL_SemValue()

Uint32 SDL_SemValue ( SDL_sem *  sem)

Returns the current count of the semaphore.

Definition at line 177 of file SDL_syssem.c.

178 {
179  int ret = 0;
180  if (sem) {
181  sem_getvalue(&sem->sem, &ret);
182  if (ret < 0) {
183  ret = 0;
184  }
185  }
186  return (Uint32) ret;
187 }
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:169
static SDL_sem * sem
Definition: testsem.c:23

◆ SDL_SemWait()

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.

87 {
88  int retval;
89 
90  if (!sem) {
91  return SDL_SetError("Passed a NULL semaphore");
92  }
93 
94  retval = sem_wait(&sem->sem);
95  if (retval < 0) {
96  retval = SDL_SetError("sem_wait() failed");
97  }
98  return retval;
99 }
static SDL_sem * sem
Definition: testsem.c:23
SDL_bool retval
#define SDL_SetError

◆ SDL_SemWaitTimeout()

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 102 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.

103 {
104  int retval;
105 #ifdef HAVE_SEM_TIMEDWAIT
106 #ifndef HAVE_CLOCK_GETTIME
107  struct timeval now;
108 #endif
109  struct timespec ts_timeout;
110 #else
111  Uint32 end;
112 #endif
113 
114  if (!sem) {
115  return SDL_SetError("Passed a NULL semaphore");
116  }
117 
118  /* Try the easy cases first */
119  if (timeout == 0) {
120  return SDL_SemTryWait(sem);
121  }
122  if (timeout == SDL_MUTEX_MAXWAIT) {
123  return SDL_SemWait(sem);
124  }
125 
126 #ifdef HAVE_SEM_TIMEDWAIT
127  /* Setup the timeout. sem_timedwait doesn't wait for
128  * a lapse of time, but until we reach a certain time.
129  * This time is now plus the timeout.
130  */
131 #ifdef HAVE_CLOCK_GETTIME
132  clock_gettime(CLOCK_REALTIME, &ts_timeout);
133 
134  /* Add our timeout to current time */
135  ts_timeout.tv_nsec += (timeout % 1000) * 1000000;
136  ts_timeout.tv_sec += timeout / 1000;
137 #else
138  gettimeofday(&now, NULL);
139 
140  /* Add our timeout to current time */
141  ts_timeout.tv_sec = now.tv_sec + (timeout / 1000);
142  ts_timeout.tv_nsec = (now.tv_usec + (timeout % 1000) * 1000) * 1000;
143 #endif
144 
145  /* Wrap the second if needed */
146  if (ts_timeout.tv_nsec > 1000000000) {
147  ts_timeout.tv_sec += 1;
148  ts_timeout.tv_nsec -= 1000000000;
149  }
150 
151  /* Wait. */
152  do {
153  retval = sem_timedwait(&sem->sem, &ts_timeout);
154  } while (retval < 0 && errno == EINTR);
155 
156  if (retval < 0) {
157  if (errno == ETIMEDOUT) {
158  retval = SDL_MUTEX_TIMEDOUT;
159  } else {
160  SDL_SetError("sem_timedwait returned an error: %s", strerror(errno));
161  }
162  }
163 #else
164  end = SDL_GetTicks() + timeout;
165  while ((retval = SDL_SemTryWait(sem)) == SDL_MUTEX_TIMEDOUT) {
166  if (SDL_TICKS_PASSED(SDL_GetTicks(), end)) {
167  break;
168  }
169  SDL_Delay(1);
170  }
171 #endif /* HAVE_SEM_TIMEDWAIT */
172 
173  return retval;
174 }
GLuint GLuint end
Definition: SDL_opengl.h:1571
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:169
static SDL_sem * sem
Definition: testsem.c:23
#define SDL_MUTEX_TIMEDOUT
Definition: SDL_mutex.h:44
SDL_bool retval
#define SDL_MUTEX_MAXWAIT
Definition: SDL_mutex.h:49
Uint32 SDL_GetTicks(void)
Get the number of milliseconds since the SDL library initialization.
int SDL_SemTryWait(SDL_sem *sem)
Definition: SDL_syssem.c:130
int SDL_SemWait(SDL_sem *sem)
Definition: SDL_syssem.c:180
#define SDL_Delay
#define NULL
Definition: begin_code.h:164
#define SDL_SetError
GLbitfield GLuint64 timeout
#define SDL_TICKS_PASSED(A, B)
Compare SDL ticks values, and return true if A has passed B.
Definition: SDL_timer.h:56