SDL 2.0
SDL_syssem.c
Go to the documentation of this file.
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2019 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21#include "../../SDL_internal.h"
22
23/* An implementation of semaphores using mutexes and condition variables */
24
25#include "SDL_timer.h"
26#include "SDL_thread.h"
27#include "SDL_systhread_c.h"
28
29
30#if SDL_THREADS_DISABLED
31
32SDL_sem *
33SDL_CreateSemaphore(Uint32 initial_value)
34{
35 SDL_SetError("SDL not built with thread support");
36 return (SDL_sem *) 0;
37}
38
39void
41{
42}
43
44int
45SDL_SemTryWait(SDL_sem * sem)
46{
47 return SDL_SetError("SDL not built with thread support");
48}
49
50int
52{
53 return SDL_SetError("SDL not built with thread support");
54}
55
56int
57SDL_SemWait(SDL_sem * sem)
58{
59 return SDL_SetError("SDL not built with thread support");
60}
61
63SDL_SemValue(SDL_sem * sem)
64{
65 return 0;
66}
67
68int
69SDL_SemPost(SDL_sem * sem)
70{
71 return SDL_SetError("SDL not built with thread support");
72}
73
74#else
75
77{
82};
83
84SDL_sem *
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}
106
107/* WARNING:
108 You cannot call this function when another thread is using the semaphore.
109*/
110void
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}
128
129int
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}
148
149int
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}
178
179int
180SDL_SemWait(SDL_sem * sem)
181{
183}
184
185Uint32
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}
198
199int
200SDL_SemPost(SDL_sem * sem)
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}
215
216#endif /* SDL_THREADS_DISABLED */
217/* vi: set ts=4 sw=4 expandtab: */
#define SDL_SetError
#define SDL_CreateCond
#define SDL_LockMutex
#define SDL_malloc
#define SDL_CondSignal
#define SDL_CreateMutex
#define SDL_free
#define SDL_CondWaitTimeout
#define SDL_Delay
#define SDL_DestroyCond
#define SDL_DestroyMutex
#define SDL_UnlockMutex
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
#define SDL_MUTEX_TIMEDOUT
Definition: SDL_mutex.h:44
#define SDL_MUTEX_MAXWAIT
Definition: SDL_mutex.h:49
GLbitfield GLuint64 timeout
GLsizei const GLfloat * value
uint32_t Uint32
Definition: SDL_stdinc.h:203
#define NULL
Definition: begin_code.h:167
int SDL_SemWait(SDL_sem *sem)
Definition: SDL_syssem.c:180
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
Definition: SDL_syssem.c:150
SDL_sem * SDL_CreateSemaphore(Uint32 initial_value)
Definition: SDL_syssem.c:85
void SDL_DestroySemaphore(SDL_sem *sem)
Definition: SDL_syssem.c:111
int SDL_SemPost(SDL_sem *sem)
Definition: SDL_syssem.c:200
Uint32 SDL_SemValue(SDL_sem *sem)
Definition: SDL_syssem.c:186
int SDL_SemTryWait(SDL_sem *sem)
Definition: SDL_syssem.c:130
SDL_cond * count_nonzero
Definition: SDL_syssem.c:81
Uint32 waiters_count
Definition: SDL_syssem.c:79
SDL_mutex * count_lock
Definition: SDL_syssem.c:80
Uint32 count
Definition: SDL_syssem.c:78
SDL_bool retval
static SDL_sem * sem
Definition: testsem.c:23