1 /* 2 SDL - Simple DirectMedia Layer 3 Copyright (C) 1997-2012 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 (at) 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 } 143