This repository has been archived by the owner on Feb 11, 2021. It is now read-only.
/
SDL_syssem.c
194 lines (173 loc) · 5.03 KB
1
2
/*
SDL - Simple DirectMedia Layer
3
Copyright (C) 1997-2009 Sam Lantinga
4
5
This library is free software; you can redistribute it and/or
6
modify it under the terms of the GNU Lesser General Public
7
License as published by the Free Software Foundation; either
8
version 2.1 of the License, or (at your option) any later version.
9
10
11
12
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
Lesser General Public License for more details.
14
15
16
17
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19
20
21
Sam Lantinga
slouken@libsdl.org
*/
22
#include "SDL_config.h"
23
24
25
26
27
28
29
30
31
32
33
34
/* Semaphore functions using the OS/2 API */
#define INCL_DOS
#define INCL_DOSERRORS
#define INCL_DOSSEMAPHORES
#include <os2.h>
#include "SDL_thread.h"
#include "SDL_timer.h"
35
36
37
38
39
struct SDL_semaphore
{
HMTX id;
HEV changed;
Uint32 value;
40
41
42
43
};
/* Create a semaphore */
44
45
DECLSPEC SDL_sem *SDLCALL
SDL_CreateSemaphore(Uint32 initial_value)
46
{
47
48
49
50
51
52
53
54
55
56
57
58
SDL_sem *sem;
ULONG ulrc;
/* Allocate sem memory */
sem = (SDL_sem *) SDL_malloc(sizeof(*sem));
if (sem) {
/* Create the mutex semaphore */
ulrc = DosCreateMutexSem(NULL, &(sem->id), 0, TRUE);
if (ulrc) {
SDL_SetError("Couldn't create semaphore");
SDL_free(sem);
sem = NULL;
59
} else {
60
61
62
DosCreateEventSem(NULL, &(sem->changed), 0, FALSE);
sem->value = initial_value;
DosReleaseMutexSem(sem->id);
63
}
64
65
66
67
} else {
SDL_OutOfMemory();
}
return (sem);
68
69
70
}
/* Free the semaphore */
71
72
DECLSPEC void SDLCALL
SDL_DestroySemaphore(SDL_sem * sem)
73
{
74
75
76
77
78
if (sem) {
if (sem->id) {
DosCloseEventSem(sem->changed);
DosCloseMutexSem(sem->id);
sem->id = 0;
79
}
80
81
SDL_free(sem);
}
82
83
}
84
85
DECLSPEC int SDLCALL
SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout)
86
{
87
ULONG ulrc;
88
89
90
91
92
if (!sem) {
SDL_SetError("Passed a NULL sem");
return -1;
}
93
94
95
if (timeout == SDL_MUTEX_MAXWAIT) {
while (1) {
96
ulrc = DosRequestMutexSem(sem->id, SEM_INDEFINITE_WAIT);
97
98
if (ulrc) {
/* if error waiting mutex */
99
100
SDL_SetError("DosRequestMutexSem() failed");
return -1;
101
} else if (sem->value) {
102
103
104
sem->value--;
DosReleaseMutexSem(sem->id);
return 0;
105
} else {
106
107
108
109
ULONG ulPostCount;
DosResetEventSem(sem->changed, &ulPostCount);
DosReleaseMutexSem(sem->id);
/* continue waiting until somebody posts the semaphore */
110
111
DosWaitEventSem(sem->changed, SEM_INDEFINITE_WAIT);
}
112
}
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
} else if (timeout == 0) {
ulrc = DosRequestMutexSem(sem->id, SEM_INDEFINITE_WAIT);
if (ulrc == NO_ERROR) {
if (sem->value) {
sem->value--;
DosReleaseMutexSem(sem->id);
return 0;
} else {
DosReleaseMutexSem(sem->id);
return SDL_MUTEX_TIMEDOUT;
}
} else {
SDL_SetError("DosRequestMutexSem() failed");
return -1;
}
} else {
ulrc = DosRequestMutexSem(sem->id, SEM_INDEFINITE_WAIT);
if (ulrc) {
/* if error waiting mutex */
SDL_SetError("DosRequestMutexSem() failed");
return -1;
} else if (sem->value) {
sem->value--;
DosReleaseMutexSem(sem->id);
return 0;
} else {
ULONG ulPostCount;
DosResetEventSem(sem->changed, &ulPostCount);
DosReleaseMutexSem(sem->id);
/* continue waiting until somebody posts the semaphore */
ulrc = DosWaitEventSem(sem->changed, timeout);
if (ulrc == NO_ERROR)
return 0;
else
return SDL_MUTEX_TIMEDOUT;
}
}
/* never reached */
return -1;
152
153
}
154
155
DECLSPEC int SDLCALL
SDL_SemTryWait(SDL_sem * sem)
156
{
157
return SDL_SemWaitTimeout(sem, 0);
158
159
}
160
161
DECLSPEC int SDLCALL
SDL_SemWait(SDL_sem * sem)
162
{
163
return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
164
165
166
}
/* Returns the current count of the semaphore */
167
168
DECLSPEC Uint32 SDLCALL
SDL_SemValue(SDL_sem * sem)
169
{
170
171
172
173
174
if (!sem) {
SDL_SetError("Passed a NULL sem");
return 0;
}
return sem->value;
175
176
}
177
178
DECLSPEC int SDLCALL
SDL_SemPost(SDL_sem * sem)
179
{
180
181
182
183
184
185
186
187
188
189
190
191
if (!sem) {
SDL_SetError("Passed a NULL sem");
return -1;
}
if (DosRequestMutexSem(sem->id, SEM_INDEFINITE_WAIT)) {
SDL_SetError("DosRequestMutexSem() failed");
return -1;
}
sem->value++;
DosPostEventSem(sem->changed);
DosReleaseMutexSem(sem->id);
return 0;
192
}
193
194
/* vi: set ts=4 sw=4 expandtab: */