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
#define SDL_free
#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
#define SDL_free

◆ 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 193 of file SDL_syssem.c.

References retval, and SDL_SetError.

194 {
195  int retval;
196 
197  if (!sem) {
198  return SDL_SetError("Passed a NULL semaphore");
199  }
200 
201  retval = sem_post(&sem->sem);
202  if (retval < 0) {
203  SDL_SetError("sem_post() failed");
204  }
205  return retval;
206 }
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 180 of file SDL_syssem.c.

181 {
182  int ret = 0;
183  if (sem) {
184  sem_getvalue(&sem->sem, &ret);
185  if (ret < 0) {
186  ret = 0;
187  }
188  }
189  return (Uint32) ret;
190 }
uint32_t Uint32
Definition: SDL_stdinc.h:181
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  do {
95  retval = sem_wait(&sem->sem);
96  } while (retval < 0 && errno == EINTR);
97 
98  if (retval < 0) {
99  retval = SDL_SetError("sem_wait() failed");
100  }
101  return retval;
102 }
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 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.

106 {
107  int retval;
108 #ifdef HAVE_SEM_TIMEDWAIT
109 #ifndef HAVE_CLOCK_GETTIME
110  struct timeval now;
111 #endif
112  struct timespec ts_timeout;
113 #else
114  Uint32 end;
115 #endif
116 
117  if (!sem) {
118  return SDL_SetError("Passed a NULL semaphore");
119  }
120 
121  /* Try the easy cases first */
122  if (timeout == 0) {
123  return SDL_SemTryWait(sem);
124  }
125  if (timeout == SDL_MUTEX_MAXWAIT) {
126  return SDL_SemWait(sem);
127  }
128 
129 #ifdef HAVE_SEM_TIMEDWAIT
130  /* Setup the timeout. sem_timedwait doesn't wait for
131  * a lapse of time, but until we reach a certain time.
132  * This time is now plus the timeout.
133  */
134 #ifdef HAVE_CLOCK_GETTIME
135  clock_gettime(CLOCK_REALTIME, &ts_timeout);
136 
137  /* Add our timeout to current time */
138  ts_timeout.tv_nsec += (timeout % 1000) * 1000000;
139  ts_timeout.tv_sec += timeout / 1000;
140 #else
141  gettimeofday(&now, NULL);
142 
143  /* Add our timeout to current time */
144  ts_timeout.tv_sec = now.tv_sec + (timeout / 1000);
145  ts_timeout.tv_nsec = (now.tv_usec + (timeout % 1000) * 1000) * 1000;
146 #endif
147 
148  /* Wrap the second if needed */
149  if (ts_timeout.tv_nsec > 1000000000) {
150  ts_timeout.tv_sec += 1;
151  ts_timeout.tv_nsec -= 1000000000;
152  }
153 
154  /* Wait. */
155  do {
156  retval = sem_timedwait(&sem->sem, &ts_timeout);
157  } while (retval < 0 && errno == EINTR);
158 
159  if (retval < 0) {
160  if (errno == ETIMEDOUT) {
161  retval = SDL_MUTEX_TIMEDOUT;
162  } else {
163  SDL_SetError("sem_timedwait returned an error: %s", strerror(errno));
164  }
165  }
166 #else
167  end = SDL_GetTicks() + timeout;
168  while ((retval = SDL_SemTryWait(sem)) == SDL_MUTEX_TIMEDOUT) {
169  if (SDL_TICKS_PASSED(SDL_GetTicks(), end)) {
170  break;
171  }
172  SDL_Delay(1);
173  }
174 #endif /* HAVE_SEM_TIMEDWAIT */
175 
176  return retval;
177 }
GLuint GLuint end
Definition: SDL_opengl.h:1571
uint32_t Uint32
Definition: SDL_stdinc.h:181
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