comparison src/thread/os2/SDL_syssem.c @ 1190:173c063d4f55

OS/2 port! This was mostly, if not entirely, written by "Doodle" and "Caetano": doodle@scenergy.dfmk.hu daniel@caetano.eng.br --ryan.
author Ryan C. Gordon <icculus@icculus.org>
date Wed, 23 Nov 2005 07:29:56 +0000
parents
children c9b51268668f
comparison
equal deleted inserted replaced
1189:c96b326b90ba 1190:173c063d4f55
1 /*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with this library; if not, write to the Free
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 Sam Lantinga
20 slouken@libsdl.org
21 */
22
23 #ifdef SAVE_RCSID
24 static char rcsid =
25 "@(#) $Id$";
26 #endif
27
28 /* Semaphore functions using the OS/2 API */
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #define INCL_DOS
33 #define INCL_DOSERRORS
34 #define INCL_DOSSEMAPHORES
35 #include <os2.h>
36
37 #include "SDL_error.h"
38 #include "SDL_thread.h"
39 #include "SDL_timer.h"
40
41
42 struct SDL_semaphore {
43 HMTX id;
44 HEV changed;
45 Uint32 value;
46 };
47
48
49 /* Create a semaphore */
50 DECLSPEC SDL_sem * SDLCALL SDL_CreateSemaphore(Uint32 initial_value)
51 {
52 SDL_sem *sem;
53 ULONG ulrc;
54
55 /* Allocate sem memory */
56 sem = (SDL_sem *)malloc(sizeof(*sem));
57 if ( sem ) {
58 /* Create the mutex semaphore */
59 ulrc = DosCreateMutexSem(NULL,&(sem->id),0,TRUE);
60 if ( ulrc ) {
61 SDL_SetError("Couldn't create semaphore");
62 free(sem);
63 sem = NULL;
64 } else
65 {
66 DosCreateEventSem(NULL, &(sem->changed), 0, FALSE);
67 sem->value = initial_value;
68 DosReleaseMutexSem(sem->id);
69 }
70 } else {
71 SDL_OutOfMemory();
72 }
73 return(sem);
74 }
75
76 /* Free the semaphore */
77 DECLSPEC void SDLCALL SDL_DestroySemaphore(SDL_sem *sem)
78 {
79 if ( sem ) {
80 if ( sem->id ) {
81 DosCloseEventSem(sem->changed);
82 DosCloseMutexSem(sem->id);
83 sem->id = 0;
84 }
85 free(sem);
86 }
87 }
88
89 DECLSPEC int SDLCALL SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
90 {
91 ULONG ulrc;
92
93 if ( ! sem ) {
94 SDL_SetError("Passed a NULL sem");
95 return -1;
96 }
97
98 if ( timeout == SDL_MUTEX_MAXWAIT ) {
99 while (1) {
100 ulrc = DosRequestMutexSem(sem->id, SEM_INDEFINITE_WAIT);
101 if (ulrc) {
102 /* if error waiting mutex */
103 SDL_SetError("DosRequestMutexSem() failed");
104 return -1;
105 } else if (sem->value) {
106 sem->value--;
107 DosReleaseMutexSem(sem->id);
108 return 0;
109 } else {
110 ULONG ulPostCount;
111 DosResetEventSem(sem->changed, &ulPostCount);
112 DosReleaseMutexSem(sem->id);
113 /* continue waiting until somebody posts the semaphore */
114 DosWaitEventSem(sem->changed, SEM_INDEFINITE_WAIT);
115 }
116 }
117 } else
118 if ( timeout == 0 )
119 {
120 ulrc = DosRequestMutexSem(sem->id, SEM_INDEFINITE_WAIT);
121 if (ulrc==NO_ERROR)
122 {
123 if (sem->value)
124 {
125 sem->value--;
126 DosReleaseMutexSem(sem->id);
127 return 0;
128 } else
129 {
130 DosReleaseMutexSem(sem->id);
131 return SDL_MUTEX_TIMEDOUT;
132 }
133 } else
134 {
135 SDL_SetError("DosRequestMutexSem() failed");
136 return -1;
137 }
138 } else {
139 ulrc = DosRequestMutexSem(sem->id, SEM_INDEFINITE_WAIT);
140 if (ulrc) {
141 /* if error waiting mutex */
142 SDL_SetError("DosRequestMutexSem() failed");
143 return -1;
144 } else
145 if (sem->value) {
146 sem->value--;
147 DosReleaseMutexSem(sem->id);
148 return 0;
149 } else {
150 ULONG ulPostCount;
151 DosResetEventSem(sem->changed, &ulPostCount);
152 DosReleaseMutexSem(sem->id);
153 /* continue waiting until somebody posts the semaphore */
154 ulrc = DosWaitEventSem(sem->changed, timeout);
155 if (ulrc==NO_ERROR)
156 return 0;
157 else
158 return SDL_MUTEX_TIMEDOUT;
159 }
160 }
161 /* never reached */
162 return -1;
163 }
164
165 DECLSPEC int SDLCALL SDL_SemTryWait(SDL_sem *sem)
166 {
167 return SDL_SemWaitTimeout(sem, 0);
168 }
169
170 DECLSPEC int SDLCALL SDL_SemWait(SDL_sem *sem)
171 {
172 return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
173 }
174
175 /* Returns the current count of the semaphore */
176 DECLSPEC Uint32 SDLCALL SDL_SemValue(SDL_sem *sem)
177 {
178 if ( ! sem ) {
179 SDL_SetError("Passed a NULL sem");
180 return 0;
181 }
182 return sem->value;
183 }
184
185 DECLSPEC int SDLCALL SDL_SemPost(SDL_sem *sem)
186 {
187 if ( ! sem ) {
188 SDL_SetError("Passed a NULL sem");
189 return -1;
190 }
191 if ( DosRequestMutexSem(sem->id,SEM_INDEFINITE_WAIT) ) {
192 SDL_SetError("DosRequestMutexSem() failed");
193 return -1;
194 }
195 sem->value++;
196 DosPostEventSem(sem->changed);
197 DosReleaseMutexSem(sem->id);
198 return 0;
199 }