Home | History | Annotate | Download | only in riscos
      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 /* RISC OS semiphores based on linux code */
     28 
     29 
     30 #include "SDL_timer.h"
     31 #include "SDL_thread.h"
     32 #include "SDL_systhread_c.h"
     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 
     79 #include <unistd.h>			/* For getpid() */
     80 #include <pthread.h>
     81 #include <semaphore.h>
     82 
     83 struct SDL_semaphore {
     84 	sem_t *sem;
     85 	sem_t sem_data;
     86 };
     87 
     88 /* Create a semaphore, initialized with value */
     89 SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
     90 {
     91 	SDL_sem *sem = (SDL_sem *) SDL_malloc(sizeof(SDL_sem));
     92 	if ( sem ) {
     93 		if ( sem_init(&sem->sem_data, 0, initial_value) < 0 ) {
     94 			SDL_SetError("sem_init() failed");
     95 			SDL_free(sem);
     96 			sem = NULL;
     97 		} else {
     98 			sem->sem = &sem->sem_data;
     99 		}
    100 	} else {
    101 		SDL_OutOfMemory();
    102 	}
    103 	return sem;
    104 }
    105 
    106 void SDL_DestroySemaphore(SDL_sem *sem)
    107 {
    108 	if ( sem ) {
    109 		sem_destroy(sem->sem);
    110 		SDL_free(sem);
    111 	}
    112 }
    113 
    114 int SDL_SemTryWait(SDL_sem *sem)
    115 {
    116 	int retval;
    117 
    118 	if ( ! sem ) {
    119 		SDL_SetError("Passed a NULL semaphore");
    120 		return -1;
    121 	}
    122 	retval = SDL_MUTEX_TIMEDOUT;
    123 	if ( sem_trywait(sem->sem) == 0 ) {
    124 		retval = 0;
    125 	}
    126 	return retval;
    127 }
    128 
    129 int SDL_SemWait(SDL_sem *sem)
    130 {
    131 	int retval;
    132 
    133 	if ( ! sem ) {
    134 		SDL_SetError("Passed a NULL semaphore");
    135 		return -1;
    136 	}
    137 
    138 	while ( ((retval = sem_wait(sem->sem)) == -1) && (errno == EINTR) ) {}
    139 	if ( retval < 0 ) {
    140 		SDL_SetError("sem_wait() failed");
    141 	}
    142 	return retval;
    143 }
    144 
    145 int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
    146 {
    147 	int retval;
    148 
    149 	if ( ! sem ) {
    150 		SDL_SetError("Passed a NULL semaphore");
    151 		return -1;
    152 	}
    153 
    154 	/* Try the easy cases first */
    155 	if ( timeout == 0 ) {
    156 		return SDL_SemTryWait(sem);
    157 	}
    158 	if ( timeout == SDL_MUTEX_MAXWAIT ) {
    159 		return SDL_SemWait(sem);
    160 	}
    161 
    162 	/* Ack!  We have to busy wait... */
    163 	timeout += SDL_GetTicks();
    164 	do {
    165 		retval = SDL_SemTryWait(sem);
    166 		if ( retval == 0 ) {
    167 			break;
    168 		}
    169 		SDL_Delay(1);
    170 	} while ( SDL_GetTicks() < timeout );
    171 
    172 	return retval;
    173 }
    174 
    175 Uint32 SDL_SemValue(SDL_sem *sem)
    176 {
    177 	int ret = 0;
    178 	if ( sem ) {
    179 		sem_getvalue(sem->sem, &ret);
    180 		if ( ret < 0 ) {
    181 			ret = 0;
    182 		}
    183 	}
    184 	return (Uint32)ret;
    185 }
    186 
    187 int SDL_SemPost(SDL_sem *sem)
    188 {
    189 	int retval;
    190 
    191 	if ( ! sem ) {
    192 		SDL_SetError("Passed a NULL semaphore");
    193 		return -1;
    194 	}
    195 
    196 	retval = sem_post(sem->sem);
    197 	if ( retval < 0 ) {
    198 		SDL_SetError("sem_post() failed");
    199 	}
    200 	return retval;
    201 }
    202 
    203 #endif /* !SDL_THREADS_DISABLED */
    204