comparison src/thread/pthread/SDL_syssem.c @ 1361:19418e4422cb

New configure-based build system. Still work in progress, but much improved
author Sam Lantinga <slouken@libsdl.org>
date Thu, 16 Feb 2006 10:11:48 +0000
parents
children d910939febfa
comparison
equal deleted inserted replaced
1360:70a9cfb4cf1b 1361:19418e4422cb
1 /*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2006 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 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 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19 Sam Lantinga
20 slouken@libsdl.org
21 */
22
23 #include <pthread.h>
24 #include <semaphore.h>
25
26 #include "SDL_thread.h"
27 #include "SDL_timer.h"
28
29 /* Wrapper around POSIX 1003.1b semaphores */
30
31 #if MACOSX
32 #define USE_NAMED_SEMAPHORES 1
33 #endif /* MACOSX */
34
35 struct SDL_semaphore {
36 sem_t *sem;
37 #if !USE_NAMED_SEMAPHORES
38 sem_t sem_data;
39 #endif
40 };
41
42 /* Create a semaphore, initialized with value */
43 SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
44 {
45 SDL_sem *sem = (SDL_sem *) SDL_malloc(sizeof(SDL_sem));
46 if ( sem ) {
47 #if USE_NAMED_SEMAPHORES
48 static int semnum = 0;
49 char name[32];
50
51 SDL_snprintf(name, SDL_arraysize(name), "/SDL_sem-%d-%4.4d", getpid(), semnum++);
52 sem->sem = sem_open(name, O_CREAT, 0600, initial_value);
53 if ( sem->sem == (sem_t *)SEM_FAILED ) {
54 SDL_SetError("sem_open(%s) failed", name);
55 SDL_free(sem);
56 sem = NULL;
57 } else {
58 sem_unlink(name);
59 }
60 #else
61 if ( sem_init(&sem->sem_data, 0, initial_value) < 0 ) {
62 SDL_SetError("sem_init() failed");
63 SDL_free(sem);
64 sem = NULL;
65 } else {
66 sem->sem = &sem->sem_data;
67 }
68 #endif /* USE_NAMED_SEMAPHORES */
69 } else {
70 SDL_OutOfMemory();
71 }
72 return sem;
73 }
74
75 void SDL_DestroySemaphore(SDL_sem *sem)
76 {
77 if ( sem ) {
78 #if USE_NAMED_SEMAPHORES
79 sem_close(sem->sem);
80 #else
81 sem_destroy(sem->sem);
82 #endif
83 SDL_free(sem);
84 }
85 }
86
87 int SDL_SemTryWait(SDL_sem *sem)
88 {
89 int retval;
90
91 if ( ! sem ) {
92 SDL_SetError("Passed a NULL semaphore");
93 return -1;
94 }
95 retval = SDL_MUTEX_TIMEDOUT;
96 if ( sem_trywait(sem->sem) == 0 ) {
97 retval = 0;
98 }
99 return retval;
100 }
101
102 int SDL_SemWait(SDL_sem *sem)
103 {
104 int retval;
105
106 if ( ! sem ) {
107 SDL_SetError("Passed a NULL semaphore");
108 return -1;
109 }
110
111 retval = sem_wait(sem->sem);
112 if ( retval < 0 ) {
113 SDL_SetError("sem_wait() failed");
114 }
115 return retval;
116 }
117
118 int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
119 {
120 int retval;
121
122 if ( ! sem ) {
123 SDL_SetError("Passed a NULL semaphore");
124 return -1;
125 }
126
127 /* Try the easy cases first */
128 if ( timeout == 0 ) {
129 return SDL_SemTryWait(sem);
130 }
131 if ( timeout == SDL_MUTEX_MAXWAIT ) {
132 return SDL_SemWait(sem);
133 }
134
135 /* Ack! We have to busy wait... */
136 timeout += SDL_GetTicks();
137 do {
138 retval = SDL_SemTryWait(sem);
139 if ( retval == 0 ) {
140 break;
141 }
142 SDL_Delay(1);
143 } while ( SDL_GetTicks() < timeout );
144
145 return retval;
146 }
147
148 Uint32 SDL_SemValue(SDL_sem *sem)
149 {
150 int ret = 0;
151 if ( sem ) {
152 sem_getvalue(sem->sem, &ret);
153 if ( ret < 0 ) {
154 ret = 0;
155 }
156 }
157 return (Uint32)ret;
158 }
159
160 int SDL_SemPost(SDL_sem *sem)
161 {
162 int retval;
163
164 if ( ! sem ) {
165 SDL_SetError("Passed a NULL semaphore");
166 return -1;
167 }
168
169 retval = sem_post(sem->sem);
170 if ( retval < 0 ) {
171 SDL_SetError("sem_post() failed");
172 }
173 return retval;
174 }