• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #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 */
SDL_CreateSemaphore(Uint32 initial_value)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 */
SDL_DestroySemaphore(SDL_sem * sem)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 
SDL_SemWaitTimeout(SDL_sem * sem,Uint32 timeout)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 
SDL_SemTryWait(SDL_sem * sem)103 int SDL_SemTryWait(SDL_sem *sem)
104 {
105 	return SDL_SemWaitTimeout(sem, 0);
106 }
107 
SDL_SemWait(SDL_sem * sem)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 */
SDL_SemValue(SDL_sem * sem)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) */
SDL_SemPost(SDL_sem * sem)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 }
143