SDL-1.2.14
[sdl_omap.git] / src / thread / beos / SDL_syssem.c
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     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 #include "SDL_config.h"
23
24 /* Semaphores in the BeOS environment */
25
26 #include <be/kernel/OS.h>
27
28 #include "SDL_thread.h"
29
30
31 struct SDL_semaphore {
32         sem_id id;
33 };
34
35 /* Create a counting semaphore */
36 SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
37 {
38         SDL_sem *sem;
39
40         sem = (SDL_sem *)SDL_malloc(sizeof(*sem));
41         if ( sem ) {
42                 sem->id = create_sem(initial_value, "SDL semaphore");
43                 if ( sem->id < B_NO_ERROR ) {
44                         SDL_SetError("create_sem() failed");
45                         SDL_free(sem);
46                         sem = NULL;
47                 }
48         } else {
49                 SDL_OutOfMemory();
50         }
51         return(sem);
52 }
53
54 /* Free the semaphore */
55 void SDL_DestroySemaphore(SDL_sem *sem)
56 {
57         if ( sem ) {
58                 if ( sem->id >= B_NO_ERROR ) {
59                         delete_sem(sem->id);
60                 }
61                 SDL_free(sem);
62         }
63 }
64
65 int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
66 {
67         int32 val;
68         int retval;
69
70         if ( ! sem ) {
71                 SDL_SetError("Passed a NULL semaphore");
72                 return -1;
73         }
74
75   tryagain:
76         if ( timeout == SDL_MUTEX_MAXWAIT ) {
77                 val = acquire_sem(sem->id);
78         } else {
79                 timeout *= 1000; /* BeOS uses a timeout in microseconds */
80                 val = acquire_sem_etc(sem->id, 1, B_RELATIVE_TIMEOUT, timeout);
81         }
82         switch (val) {
83             case B_INTERRUPTED:
84                 goto tryagain;
85             case B_NO_ERROR:
86                 retval = 0;
87                 break;
88             case B_TIMED_OUT:
89                 retval = SDL_MUTEX_TIMEDOUT;
90                 break;
91             case B_WOULD_BLOCK:
92                 retval = SDL_MUTEX_TIMEDOUT;
93                 break;
94             default:
95                 SDL_SetError("acquire_sem() failed");
96                 retval = -1;
97                 break;
98         }
99
100         return retval;
101 }
102
103 int SDL_SemTryWait(SDL_sem *sem)
104 {
105         return SDL_SemWaitTimeout(sem, 0);
106 }
107
108 int SDL_SemWait(SDL_sem *sem)
109 {
110         return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
111 }
112
113 /* Returns the current count of the semaphore */
114 Uint32 SDL_SemValue(SDL_sem *sem)
115 {
116         int32 count;
117         Uint32 value;
118
119         value = 0;
120         if ( sem ) {
121                 get_sem_count(sem->id, &count);
122                 if ( count > 0 ) {
123                         value = (Uint32)count;
124                 }
125         }
126         return value;
127 }
128
129 /* Atomically increases the semaphore's count (not blocking) */
130 int SDL_SemPost(SDL_sem *sem)
131 {
132         if ( ! sem ) {
133                 SDL_SetError("Passed a NULL semaphore");
134                 return -1;
135         }
136
137         if ( release_sem(sem->id) != B_NO_ERROR ) {
138                 SDL_SetError("release_sem() failed");
139                 return -1;
140         }
141         return 0;
142 }