SDL 2.0
SDL_mutex.h File Reference
#include "SDL_stdinc.h"
#include "SDL_error.h"
#include "begin_code.h"
#include "close_code.h"
+ Include dependency graph for SDL_mutex.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define SDL_MUTEX_TIMEDOUT   1
 
#define SDL_MUTEX_MAXWAIT   (~(Uint32)0)
 

Functions

Semaphore functions
SDL_sem * SDL_CreateSemaphore (Uint32 initial_value)
 
void SDL_DestroySemaphore (SDL_sem *sem)
 
int SDL_SemWait (SDL_sem *sem)
 
int SDL_SemTryWait (SDL_sem *sem)
 
int SDL_SemWaitTimeout (SDL_sem *sem, Uint32 ms)
 
int SDL_SemPost (SDL_sem *sem)
 
Uint32 SDL_SemValue (SDL_sem *sem)
 
Condition variable functions
SDL_condSDL_CreateCond (void)
 
void SDL_DestroyCond (SDL_cond *cond)
 
int SDL_CondSignal (SDL_cond *cond)
 
int SDL_CondBroadcast (SDL_cond *cond)
 
int SDL_CondWait (SDL_cond *cond, SDL_mutex *mutex)
 
int SDL_CondWaitTimeout (SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
 

Mutex functions

#define SDL_mutexP(m)   SDL_LockMutex(m)
 
#define SDL_mutexV(m)   SDL_UnlockMutex(m)
 
SDL_mutexSDL_CreateMutex (void)
 
int SDL_LockMutex (SDL_mutex *mutex)
 
int SDL_TryLockMutex (SDL_mutex *mutex)
 
int SDL_UnlockMutex (SDL_mutex *mutex)
 
void SDL_DestroyMutex (SDL_mutex *mutex)
 

Detailed Description

Functions to provide thread synchronization primitives.

Definition in file SDL_mutex.h.

Macro Definition Documentation

◆ SDL_MUTEX_MAXWAIT

#define SDL_MUTEX_MAXWAIT   (~(Uint32)0)

This is the timeout value which corresponds to never time out.

Definition at line 49 of file SDL_mutex.h.

◆ SDL_MUTEX_TIMEDOUT

#define SDL_MUTEX_TIMEDOUT   1

Synchronization functions which can time out return this value if they time out.

Definition at line 44 of file SDL_mutex.h.

◆ SDL_mutexP

#define SDL_mutexP (   m)    SDL_LockMutex(m)

Lock the mutex.

Returns
0, or -1 on error.

Definition at line 71 of file SDL_mutex.h.

◆ SDL_mutexV

#define SDL_mutexV (   m)    SDL_UnlockMutex(m)

Unlock the mutex.

Returns
0, or -1 on error.
Warning
It is an error to unlock a mutex that has not been locked by the current thread, and doing so results in undefined behavior.

Definition at line 89 of file SDL_mutex.h.

Function Documentation

◆ SDL_CondBroadcast()

int SDL_CondBroadcast ( SDL_cond cond)

Restart all threads that are waiting on the condition variable.

Returns
0 or -1 on error.

Definition at line 106 of file SDL_syscond.c.

107{
108 if (!cond) {
109 return SDL_SetError("Passed a NULL condition variable");
110 }
111
112 /* If there are waiting threads not already signalled, then
113 signal the condition and wait for the thread to respond.
114 */
115 SDL_LockMutex(cond->lock);
116 if (cond->waiting > cond->signals) {
117 int i, num_waiting;
118
119 num_waiting = (cond->waiting - cond->signals);
120 cond->signals = cond->waiting;
121 for (i = 0; i < num_waiting; ++i) {
122 SDL_SemPost(cond->wait_sem);
123 }
124 /* Now all released threads are blocked here, waiting for us.
125 Collect them all (and win fabulous prizes!) :-)
126 */
127 SDL_UnlockMutex(cond->lock);
128 for (i = 0; i < num_waiting; ++i) {
129 SDL_SemWait(cond->wait_done);
130 }
131 } else {
132 SDL_UnlockMutex(cond->lock);
133 }
134
135 return 0;
136}
#define SDL_SetError
#define SDL_SemPost
#define SDL_SemWait
#define SDL_LockMutex
#define SDL_UnlockMutex
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
SDL_sem * wait_done
Definition: SDL_syscond.c:37
SDL_mutex * lock
Definition: SDL_syscond.c:33
int waiting
Definition: SDL_syscond.c:34
int signals
Definition: SDL_syscond.c:35
SDL_sem * wait_sem
Definition: SDL_syscond.c:36

References SDL_cond::cond, SDL_cond::cpp_cond, i, SDL_cond::lock, retval, SDL_LockMutex, SDL_SemPost, SDL_SemWait, SDL_SetError, SDL_UnlockMutex, SDL_cond::signals, SDL_cond::wait_done, SDL_cond::wait_sem, and SDL_cond::waiting.

◆ SDL_CondSignal()

int SDL_CondSignal ( SDL_cond cond)

Restart one of the threads that are waiting on the condition variable.

Returns
0 or -1 on error.

Definition at line 82 of file SDL_syscond.c.

83{
84 if (!cond) {
85 return SDL_SetError("Passed a NULL condition variable");
86 }
87
88 /* If there are waiting threads not already signalled, then
89 signal the condition and wait for the thread to respond.
90 */
91 SDL_LockMutex(cond->lock);
92 if (cond->waiting > cond->signals) {
93 ++cond->signals;
94 SDL_SemPost(cond->wait_sem);
95 SDL_UnlockMutex(cond->lock);
97 } else {
98 SDL_UnlockMutex(cond->lock);
99 }
100
101 return 0;
102}

References SDL_cond::cond, SDL_cond::cpp_cond, SDL_cond::lock, retval, SDL_LockMutex, SDL_SemPost, SDL_SemWait, SDL_SetError, SDL_UnlockMutex, SDL_cond::signals, SDL_cond::wait_done, SDL_cond::wait_sem, and SDL_cond::waiting.

◆ SDL_CondWait()

int SDL_CondWait ( SDL_cond cond,
SDL_mutex mutex 
)

Wait on the condition variable, unlocking the provided mutex.

Warning
The mutex must be locked before entering this function!

The mutex is re-locked once the condition variable is signaled.

Returns
0 when it is signaled, or -1 on error.

Definition at line 215 of file SDL_syscond.c.

216{
218}
#define SDL_MUTEX_MAXWAIT
Definition: SDL_mutex.h:49
int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
Definition: SDL_syscond.c:160
static SDL_mutex * mutex
Definition: testlock.c:23

References SDL_cond::cond, SDL_mutex::id, mutex, SDL_CondWaitTimeout(), SDL_MUTEX_MAXWAIT, and SDL_SetError.

◆ SDL_CondWaitTimeout()

int SDL_CondWaitTimeout ( SDL_cond cond,
SDL_mutex mutex,
Uint32  ms 
)

Waits for at most ms milliseconds, and returns 0 if the condition variable is signaled, SDL_MUTEX_TIMEDOUT if the condition is not signaled 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 160 of file SDL_syscond.c.

161{
162 int retval;
163
164 if (!cond) {
165 return SDL_SetError("Passed a NULL condition variable");
166 }
167
168 /* Obtain the protection mutex, and increment the number of waiters.
169 This allows the signal mechanism to only perform a signal if there
170 are waiting threads.
171 */
172 SDL_LockMutex(cond->lock);
173 ++cond->waiting;
174 SDL_UnlockMutex(cond->lock);
175
176 /* Unlock the mutex, as is required by condition variable semantics */
178
179 /* Wait for a signal */
180 if (ms == SDL_MUTEX_MAXWAIT) {
181 retval = SDL_SemWait(cond->wait_sem);
182 } else {
184 }
185
186 /* Let the signaler know we have completed the wait, otherwise
187 the signaler can race ahead and get the condition semaphore
188 if we are stopped between the mutex unlock and semaphore wait,
189 giving a deadlock. See the following URL for details:
190 http://web.archive.org/web/20010914175514/http://www-classic.be.com/aboutbe/benewsletter/volume_III/Issue40.html#Workshop
191 */
192 SDL_LockMutex(cond->lock);
193 if (cond->signals > 0) {
194 /* If we timed out, we need to eat a condition signal */
195 if (retval > 0) {
196 SDL_SemWait(cond->wait_sem);
197 }
198 /* We always notify the signal thread that we are done */
199 SDL_SemPost(cond->wait_done);
200
201 /* Signal handshake complete */
202 --cond->signals;
203 }
204 --cond->waiting;
205 SDL_UnlockMutex(cond->lock);
206
207 /* Lock the mutex, as is required by condition variable semantics */
209
210 return retval;
211}
#define SDL_SemWaitTimeout
SDL_bool retval

References SDL_cond::cond, SDL_cond::cpp_cond, SDL_mutex::cpp_mutex, SDL_mutex::id, SDL_cond::lock, mutex, NULL, retval, SDL_LockMutex, SDL_MUTEX_MAXWAIT, SDL_MUTEX_TIMEDOUT, SDL_SemPost, SDL_SemWait, SDL_SemWaitTimeout, SDL_SetError, SDL_UnlockMutex, SDL_cond::signals, SDL_cond::wait_done, SDL_cond::wait_sem, and SDL_cond::waiting.

Referenced by SDL_CondWait().

◆ SDL_CreateCond()

SDL_cond * SDL_CreateCond ( void  )

Create a condition variable.

Typical use of condition variables:

Thread A: SDL_LockMutex(lock); while ( ! condition ) { SDL_CondWait(cond, lock); } SDL_UnlockMutex(lock);

Thread B: SDL_LockMutex(lock); ... condition = true; ... SDL_CondSignal(cond); SDL_UnlockMutex(lock);

There is some discussion whether to signal the condition variable with the mutex locked or not. There is some potential performance benefit to unlocking first on some platforms, but there are some potential race conditions depending on how your code is structured.

In general it's safer to signal the condition variable while the mutex is locked.

Definition at line 42 of file SDL_syscond.c.

43{
44 SDL_cond *cond;
45
46 cond = (SDL_cond *) SDL_malloc(sizeof(SDL_cond));
47 if (cond) {
48 cond->lock = SDL_CreateMutex();
51 cond->waiting = cond->signals = 0;
52 if (!cond->lock || !cond->wait_sem || !cond->wait_done) {
53 SDL_DestroyCond(cond);
54 cond = NULL;
55 }
56 } else {
58 }
59 return (cond);
60}
#define SDL_malloc
#define SDL_CreateMutex
#define SDL_CreateSemaphore
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
#define NULL
Definition: begin_code.h:167
void SDL_DestroyCond(SDL_cond *cond)
Definition: SDL_syscond.c:64

References SDL_cond::cond, SDL_cond::lock, NULL, SDL_CreateMutex, SDL_CreateSemaphore, SDL_DestroyCond(), SDL_free, SDL_malloc, SDL_OutOfMemory, SDL_SetError, SDL_cond::signals, SDL_cond::wait_done, SDL_cond::wait_sem, and SDL_cond::waiting.

◆ SDL_CreateMutex()

SDL_mutex * SDL_CreateMutex ( void  )

Create a mutex, initialized unlocked.

Definition at line 38 of file SDL_sysmutex.c.

39{
41
42 /* Allocate mutex memory */
43 mutex = (SDL_mutex *) SDL_malloc(sizeof(*mutex));
44 if (mutex) {
45 /* Create the mutex semaphore, with initial value 1 */
47 mutex->recursive = 0;
48 mutex->owner = 0;
49 if (!mutex->sem) {
51 mutex = NULL;
52 }
53 } else {
55 }
56 return mutex;
57}
#define SDL_free
SDL_threadID owner
Definition: SDL_sysmutex.c:32
int recursive
Definition: SDL_sysmutex.c:31
SDL_sem * sem
Definition: SDL_sysmutex.c:33

References SDL_mutex::id, mutex, NULL, SDL_mutex::owner, SDL_mutex::recursive, SDL_calloc, SDL_CreateSemaphore, SDL_free, SDL_malloc, SDL_OutOfMemory, SDL_SetError, and SDL_mutex::sem.

◆ SDL_CreateSemaphore()

SDL_sem * SDL_CreateSemaphore ( Uint32  initial_value)

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

Definition at line 85 of file SDL_syssem.c.

86{
87 SDL_sem *sem;
88
89 sem = (SDL_sem *) SDL_malloc(sizeof(*sem));
90 if (!sem) {
92 return NULL;
93 }
94 sem->count = initial_value;
95 sem->waiters_count = 0;
96
97 sem->count_lock = SDL_CreateMutex();
98 sem->count_nonzero = SDL_CreateCond();
99 if (!sem->count_lock || !sem->count_nonzero) {
101 return NULL;
102 }
103
104 return sem;
105}
#define SDL_CreateCond
void SDL_DestroySemaphore(SDL_sem *sem)
Definition: SDL_syssem.c:111
static SDL_sem * sem
Definition: testsem.c:23

References NULL, SDL_CreateCond, SDL_CreateMutex, SDL_DestroySemaphore(), SDL_free, SDL_malloc, SDL_OutOfMemory, SDL_SetError, and sem.

◆ SDL_DestroyCond()

void SDL_DestroyCond ( SDL_cond cond)

Destroy a condition variable.

Definition at line 64 of file SDL_syscond.c.

65{
66 if (cond) {
67 if (cond->wait_sem) {
69 }
70 if (cond->wait_done) {
72 }
73 if (cond->lock) {
75 }
76 SDL_free(cond);
77 }
78}
#define SDL_DestroySemaphore
#define SDL_DestroyMutex

References SDL_cond::cond, SDL_cond::lock, SDL_DestroyMutex, SDL_DestroySemaphore, SDL_free, SDL_cond::wait_done, and SDL_cond::wait_sem.

Referenced by SDL_CreateCond().

◆ SDL_DestroyMutex()

void SDL_DestroyMutex ( SDL_mutex mutex)

Destroy a mutex.

Definition at line 61 of file SDL_sysmutex.c.

62{
63 if (mutex) {
64 if (mutex->sem) {
66 }
68 }
69}

References SDL_mutex::id, mutex, SDL_DestroySemaphore, SDL_free, and SDL_mutex::sem.

◆ SDL_DestroySemaphore()

void SDL_DestroySemaphore ( SDL_sem *  sem)

Destroy a semaphore.

Definition at line 111 of file SDL_syssem.c.

112{
113 if (sem) {
114 sem->count = 0xFFFFFFFF;
115 while (sem->waiters_count > 0) {
116 SDL_CondSignal(sem->count_nonzero);
117 SDL_Delay(10);
118 }
119 SDL_DestroyCond(sem->count_nonzero);
120 if (sem->count_lock) {
121 SDL_LockMutex(sem->count_lock);
122 SDL_UnlockMutex(sem->count_lock);
123 SDL_DestroyMutex(sem->count_lock);
124 }
125 SDL_free(sem);
126 }
127}
#define SDL_CondSignal
#define SDL_Delay
#define SDL_DestroyCond

References SDL_CondSignal, SDL_Delay, SDL_DestroyCond, SDL_DestroyMutex, SDL_free, SDL_LockMutex, SDL_UnlockMutex, and sem.

Referenced by SDL_CreateSemaphore().

◆ SDL_LockMutex()

int SDL_LockMutex ( SDL_mutex mutex)

Definition at line 73 of file SDL_sysmutex.c.

74{
75#if SDL_THREADS_DISABLED
76 return 0;
77#else
78 SDL_threadID this_thread;
79
80 if (mutex == NULL) {
81 return SDL_SetError("Passed a NULL mutex");
82 }
83
84 this_thread = SDL_ThreadID();
85 if (mutex->owner == this_thread) {
87 } else {
88 /* The order of operations is important.
89 We set the locking thread id after we obtain the lock
90 so unlocks from other threads will fail.
91 */
93 mutex->owner = this_thread;
94 mutex->recursive = 0;
95 }
96
97 return 0;
98#endif /* SDL_THREADS_DISABLED */
99}
#define SDL_ThreadID
unsigned long SDL_threadID
Definition: SDL_thread.h:49

References SDL_mutex::id, mutex, NULL, SDL_mutex::owner, SDL_mutex::recursive, SDL_SemWait, SDL_SetError, SDL_ThreadID, and SDL_mutex::sem.

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

201{
202 if (!sem) {
203 return SDL_SetError("Passed a NULL semaphore");
204 }
205
206 SDL_LockMutex(sem->count_lock);
207 if (sem->waiters_count > 0) {
208 SDL_CondSignal(sem->count_nonzero);
209 }
210 ++sem->count;
211 SDL_UnlockMutex(sem->count_lock);
212
213 return 0;
214}

References retval, SDL_CondSignal, SDL_LockMutex, SDL_SetError, SDL_UnlockMutex, and sem.

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

131{
132 int retval;
133
134 if (!sem) {
135 return SDL_SetError("Passed a NULL semaphore");
136 }
137
139 SDL_LockMutex(sem->count_lock);
140 if (sem->count > 0) {
141 --sem->count;
142 retval = 0;
143 }
144 SDL_UnlockMutex(sem->count_lock);
145
146 return retval;
147}
#define SDL_MUTEX_TIMEDOUT
Definition: SDL_mutex.h:44

References retval, SDL_LockMutex, SDL_MUTEX_TIMEDOUT, SDL_SetError, SDL_UnlockMutex, and sem.

Referenced by SDL_SemWaitTimeout().

◆ SDL_SemValue()

Uint32 SDL_SemValue ( SDL_sem *  sem)

Returns the current count of the semaphore.

Definition at line 186 of file SDL_syssem.c.

187{
189
190 value = 0;
191 if (sem) {
192 SDL_LockMutex(sem->count_lock);
193 value = sem->count;
194 SDL_UnlockMutex(sem->count_lock);
195 }
196 return value;
197}
GLsizei const GLfloat * value
uint32_t Uint32
Definition: SDL_stdinc.h:203

References SDL_LockMutex, SDL_UnlockMutex, and sem.

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

181{
183}
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
Definition: SDL_syssem.c:150

References retval, SDL_MUTEX_MAXWAIT, SDL_SemWaitTimeout(), SDL_SetError, and sem.

Referenced by SDL_SemWaitTimeout().

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

151{
152 int retval;
153
154 if (!sem) {
155 return SDL_SetError("Passed a NULL semaphore");
156 }
157
158 /* A timeout of 0 is an easy case */
159 if (timeout == 0) {
160 return SDL_SemTryWait(sem);
161 }
162
163 SDL_LockMutex(sem->count_lock);
164 ++sem->waiters_count;
165 retval = 0;
166 while ((sem->count == 0) && (retval != SDL_MUTEX_TIMEDOUT)) {
167 retval = SDL_CondWaitTimeout(sem->count_nonzero,
168 sem->count_lock, timeout);
169 }
170 --sem->waiters_count;
171 if (retval == 0) {
172 --sem->count;
173 }
174 SDL_UnlockMutex(sem->count_lock);
175
176 return retval;
177}
#define SDL_CondWaitTimeout
GLbitfield GLuint64 timeout
int SDL_SemTryWait(SDL_sem *sem)
Definition: SDL_syssem.c:130

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

Referenced by SDL_SemWait().

◆ SDL_TryLockMutex()

int SDL_TryLockMutex ( SDL_mutex mutex)

Try to lock the mutex

Returns
0, SDL_MUTEX_TIMEDOUT, or -1 on error

Definition at line 103 of file SDL_sysmutex.c.

104{
105#if SDL_THREADS_DISABLED
106 return 0;
107#else
108 int retval = 0;
109 SDL_threadID this_thread;
110
111 if (mutex == NULL) {
112 return SDL_SetError("Passed a NULL mutex");
113 }
114
115 this_thread = SDL_ThreadID();
116 if (mutex->owner == this_thread) {
117 ++mutex->recursive;
118 } else {
119 /* The order of operations is important.
120 We set the locking thread id after we obtain the lock
121 so unlocks from other threads will fail.
122 */
124 if (retval == 0) {
125 mutex->owner = this_thread;
126 mutex->recursive = 0;
127 }
128 }
129
130 return retval;
131#endif /* SDL_THREADS_DISABLED */
132}

References SDL_mutex::cpp_mutex, SDL_mutex::id, mutex, NULL, SDL_mutex::owner, SDL_mutex::recursive, retval, SDL_MUTEX_TIMEDOUT, SDL_SemWait, SDL_SetError, SDL_ThreadID, and SDL_mutex::sem.

◆ SDL_UnlockMutex()

int SDL_UnlockMutex ( SDL_mutex mutex)

Definition at line 162 of file SDL_sysmutex.c.

163{
164 if (mutex == NULL) {
165 return SDL_SetError("Passed a NULL mutex");
166 }
167
168#if FAKE_RECURSIVE_MUTEX
169 /* We can only unlock the mutex if we own it */
170 if (pthread_self() == mutex->owner) {
171 if (mutex->recursive) {
172 --mutex->recursive;
173 } else {
174 /* The order of operations is important.
175 First reset the owner so another thread doesn't lock
176 the mutex and set the ownership before we reset it,
177 then release the lock semaphore.
178 */
179 mutex->owner = 0;
180 pthread_mutex_unlock(&mutex->id);
181 }
182 } else {
183 return SDL_SetError("mutex not owned by this thread");
184 }
185
186#else
187 if (pthread_mutex_unlock(&mutex->id) != 0) {
188 return SDL_SetError("pthread_mutex_unlock() failed");
189 }
190#endif /* FAKE_RECURSIVE_MUTEX */
191
192 return 0;
193}
pthread_mutex_t id
Definition: SDL_sysmutex.c:35

References SDL_mutex::id, mutex, NULL, SDL_mutex::owner, SDL_mutex::recursive, and SDL_SetError.