146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* 246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL - Simple DirectMedia Layer 346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Copyright (C) 1997-2006 Sam Lantinga 446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner This library is free software; you can redistribute it and/or 646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner modify it under the terms of the GNU Lesser General Public 746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner License as published by the Free Software Foundation; either 846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner version 2.1 of the License, or (at your option) any later version. 946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 1046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner This library is distributed in the hope that it will be useful, 1146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner but WITHOUT ANY WARRANTY; without even the implied warranty of 1246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Lesser General Public License for more details. 1446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 1546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner You should have received a copy of the GNU Lesser General Public 1646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner License along with this library; if not, write to the Free Software 1746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 1846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 1946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Sam Lantinga 2046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner slouken@libsdl.org 2146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner*/ 2246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 2346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include <errno.h> 2446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 2546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "SDL_config.h" 2646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 2746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* An implementation of semaphores using mutexes and condition variables */ 2846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 2946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "SDL_timer.h" 3046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "SDL_thread.h" 3146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "SDL_systhread_c.h" 3246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 3346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 3446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#if SDL_THREADS_DISABLED 3546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 3646be48730333120a7b939116cef075e61c12c703David 'Digit' TurnerSDL_sem *SDL_CreateSemaphore(Uint32 initial_value) 3746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 3846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_SetError("SDL not configured with thread support"); 3946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return (SDL_sem *)0; 4046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 4146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 4246be48730333120a7b939116cef075e61c12c703David 'Digit' Turnervoid SDL_DestroySemaphore(SDL_sem *sem) 4346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 4446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return; 4546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 4646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 4746be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerint SDL_SemTryWait(SDL_sem *sem) 4846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 4946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_SetError("SDL not configured with thread support"); 5046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return -1; 5146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 5246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 5346be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerint SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) 5446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 5546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_SetError("SDL not configured with thread support"); 5646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return -1; 5746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 5846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 5946be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerint SDL_SemWait(SDL_sem *sem) 6046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 6146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_SetError("SDL not configured with thread support"); 6246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return -1; 6346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 6446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 6546be48730333120a7b939116cef075e61c12c703David 'Digit' TurnerUint32 SDL_SemValue(SDL_sem *sem) 6646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 6746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return 0; 6846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 6946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 7046be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerint SDL_SemPost(SDL_sem *sem) 7146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 7246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_SetError("SDL not configured with thread support"); 7346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return -1; 7446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 7546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 7646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#else 7746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 7846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include <kos/sem.h> 7946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 8046be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstruct SDL_semaphore 8146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 8246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner semaphore_t sem; 8346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner}; 8446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 8546be48730333120a7b939116cef075e61c12c703David 'Digit' TurnerSDL_sem *SDL_CreateSemaphore(Uint32 initial_value) 8646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 8746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return (SDL_sem *)sem_create(initial_value); 8846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 8946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 9046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* WARNING: 9146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner You cannot call this function when another thread is using the semaphore. 9246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner*/ 9346be48730333120a7b939116cef075e61c12c703David 'Digit' Turnervoid SDL_DestroySemaphore(SDL_sem *sem) 9446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 9546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( ! sem ) { 9646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_SetError("Passed a NULL semaphore"); 9746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return; 9846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 9946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 10046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner sem_destroy(&sem->sem); 10146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 10246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 10346be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerint SDL_SemTryWait(SDL_sem *sem) 10446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 10546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int retval; 10646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 10746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( ! sem ) { 10846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_SetError("Passed a NULL semaphore"); 10946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return -1; 11046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 11146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 11246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner retval = sem_trywait(&sem->sem); 11346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (retval==0) return 0; 11446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner else return SDL_MUTEX_TIMEDOUT; 11546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 11646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return retval; 11746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 11846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 11946be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerint SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) 12046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 12146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int retval; 12246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 12346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( ! sem ) { 12446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_SetError("Passed a NULL semaphore"); 12546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return -1; 12646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 12746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 12846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* A timeout of 0 is an easy case */ 12946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( timeout == 0 ) { 13046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return SDL_SemTryWait(sem); 13146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 13246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 13346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner retval = sem_wait_timed(&sem->sem,timeout); 13446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (retval==-1) retval= SDL_MUTEX_TIMEDOUT; 13546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 13646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return retval; 13746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 13846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 13946be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerint SDL_SemWait(SDL_sem *sem) 14046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 14146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int retval; 14246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 14346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( ! sem ) { 14446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_SetError("Passed a NULL semaphore"); 14546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return -1; 14646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 14746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 14846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner while ( ((retval = sem_wait(&sem->sem)) == -1) && (errno == EINTR) ) {} 14946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return retval; 15046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 15146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 15246be48730333120a7b939116cef075e61c12c703David 'Digit' TurnerUint32 SDL_SemValue(SDL_sem *sem) 15346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 15446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( ! sem ) { 15546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_SetError("Passed a NULL semaphore"); 15646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return -1; 15746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 15846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 15946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return sem_count(&sem->sem); 16046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 16146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 16246be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerint SDL_SemPost(SDL_sem *sem) 16346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 16446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( ! sem ) { 16546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_SetError("Passed a NULL semaphore"); 16646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return -1; 16746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 16846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 16946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner sem_signal(&sem->sem); 17046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return 0; 17146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 17246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 17346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif /* SDL_THREADS_DISABLED */ 174