Home | History | Annotate | Download | only in dc
      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 
     23 #include <errno.h>
     24 
     25 #include "SDL_config.h"
     26 
     27 /* An implementation of semaphores using mutexes and condition variables */
     28 
     29 #include "SDL_timer.h"
     30 #include "SDL_thread.h"
     31 #include "SDL_systhread_c.h"
     32 
     33 
     34 #if SDL_THREADS_DISABLED
     35 
     36 SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
     37 {
     38 	SDL_SetError("SDL not configured with thread support");
     39 	return (SDL_sem *)0;
     40 }
     41 
     42 void SDL_DestroySemaphore(SDL_sem *sem)
     43 {
     44 	return;
     45 }
     46 
     47 int SDL_SemTryWait(SDL_sem *sem)
     48 {
     49 	SDL_SetError("SDL not configured with thread support");
     50 	return -1;
     51 }
     52 
     53 int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
     54 {
     55 	SDL_SetError("SDL not configured with thread support");
     56 	return -1;
     57 }
     58 
     59 int SDL_SemWait(SDL_sem *sem)
     60 {
     61 	SDL_SetError("SDL not configured with thread support");
     62 	return -1;
     63 }
     64 
     65 Uint32 SDL_SemValue(SDL_sem *sem)
     66 {
     67 	return 0;
     68 }
     69 
     70 int SDL_SemPost(SDL_sem *sem)
     71 {
     72 	SDL_SetError("SDL not configured with thread support");
     73 	return -1;
     74 }
     75 
     76 #else
     77 
     78 #include <kos/sem.h>
     79 
     80 struct SDL_semaphore
     81 {
     82 	semaphore_t sem;
     83 };
     84 
     85 SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
     86 {
     87 	return (SDL_sem *)sem_create(initial_value);
     88 }
     89 
     90 /* WARNING:
     91    You cannot call this function when another thread is using the semaphore.
     92 */
     93 void SDL_DestroySemaphore(SDL_sem *sem)
     94 {
     95 	if ( ! sem ) {
     96 		SDL_SetError("Passed a NULL semaphore");
     97 		return;
     98 	}
     99 
    100 	sem_destroy(&sem->sem);
    101 }
    102 
    103 int SDL_SemTryWait(SDL_sem *sem)
    104 {
    105 	int retval;
    106 
    107 	if ( ! sem ) {
    108 		SDL_SetError("Passed a NULL semaphore");
    109 		return -1;
    110 	}
    111 
    112 	retval = sem_trywait(&sem->sem);
    113 	if (retval==0) return 0;
    114 	else return SDL_MUTEX_TIMEDOUT;
    115 
    116 	return retval;
    117 }
    118 
    119 int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
    120 {
    121 	int retval;
    122 
    123 	if ( ! sem ) {
    124 		SDL_SetError("Passed a NULL semaphore");
    125 		return -1;
    126 	}
    127 
    128 	/* A timeout of 0 is an easy case */
    129 	if ( timeout == 0 ) {
    130 		return SDL_SemTryWait(sem);
    131 	}
    132 
    133 	retval = sem_wait_timed(&sem->sem,timeout);
    134 	if (retval==-1) retval= SDL_MUTEX_TIMEDOUT;
    135 
    136 	return retval;
    137 }
    138 
    139 int SDL_SemWait(SDL_sem *sem)
    140 {
    141 	int retval;
    142 
    143 	if ( ! sem ) {
    144 		SDL_SetError("Passed a NULL semaphore");
    145 		return -1;
    146 	}
    147 
    148 	while ( ((retval = sem_wait(&sem->sem)) == -1) && (errno == EINTR) ) {}
    149 	return retval;
    150 }
    151 
    152 Uint32 SDL_SemValue(SDL_sem *sem)
    153 {
    154 	if ( ! sem ) {
    155 		SDL_SetError("Passed a NULL semaphore");
    156 		return -1;
    157 	}
    158 
    159 	return sem_count(&sem->sem);
    160 }
    161 
    162 int SDL_SemPost(SDL_sem *sem)
    163 {
    164 	if ( ! sem ) {
    165 		SDL_SetError("Passed a NULL semaphore");
    166 		return -1;
    167 	}
    168 
    169 	sem_signal(&sem->sem);
    170 	return 0;
    171 }
    172 
    173 #endif /* SDL_THREADS_DISABLED */
    174