Skip to content

Commit

Permalink
Date: Fri, 15 Jul 2005 08:29:01 +0100
Browse files Browse the repository at this point in the history
From: "alan buckley"
Subject: SDL Improved semiphore implementation for RISC OS (version 2)

I've attached a new version of the patch for the RISC OS
semaphore processing (in a zip file) that updates it to use
the improved semaphores support in UnixLiib.
  • Loading branch information
slouken committed Jul 21, 2005
1 parent 3ab9bf8 commit d88d9e2
Showing 1 changed file with 65 additions and 71 deletions.
136 changes: 65 additions & 71 deletions src/thread/riscos/SDL_syssem.c
Expand Up @@ -20,14 +20,13 @@
slouken@libsdl.org
*/

/* RISC OS doesn't have semiphores so use code based on generic implementation */
/* RISC OS semiphores based on linux code */

#ifdef SAVE_RCSID
static char rcsid =
"@(#) $Id$";
#endif

/* An implementation of semaphores using mutexes and condition variables */

#include <stdlib.h>

Expand Down Expand Up @@ -81,51 +80,40 @@ int SDL_SemPost(SDL_sem *sem)

#else

struct SDL_semaphore
{
Uint32 count;
Uint32 waiters_count;
SDL_mutex *count_lock;
SDL_cond *count_nonzero;

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> /* For getpid() */
#include <pthread.h>
#include <semaphore.h>

struct SDL_semaphore {
sem_t *sem;
sem_t sem_data;
};

/* Create a semaphore, initialized with value */
SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
{
SDL_sem *sem;

sem = (SDL_sem *)malloc(sizeof(*sem));
if ( ! sem ) {
SDL_sem *sem = (SDL_sem *) malloc(sizeof(SDL_sem));
if ( sem ) {
if ( sem_init(&sem->sem_data, 0, initial_value) < 0 ) {
SDL_SetError("sem_init() failed");
free(sem);
sem = NULL;
} else {
sem->sem = &sem->sem_data;
}
} else {
SDL_OutOfMemory();
return(0);
}
sem->count = initial_value;
sem->waiters_count = 0;

sem->count_lock = SDL_CreateMutex();
sem->count_nonzero = SDL_CreateCond();
if ( ! sem->count_lock || ! sem->count_nonzero ) {
SDL_DestroySemaphore(sem);
return(0);
}

return(sem);
return sem;
}

/* WARNING:
You cannot call this function when another thread is using the semaphore.
*/
void SDL_DestroySemaphore(SDL_sem *sem)
{
if ( sem ) {
sem->count = 0xFFFFFFFF;
while ( sem->waiters_count > 0) {
SDL_CondSignal(sem->count_nonzero);
SDL_Delay(10);
}
SDL_DestroyCond(sem->count_nonzero);
SDL_mutexP(sem->count_lock);
SDL_mutexV(sem->count_lock);
SDL_DestroyMutex(sem->count_lock);
sem_destroy(sem->sem);
free(sem);
}
}
Expand All @@ -138,15 +126,26 @@ int SDL_SemTryWait(SDL_sem *sem)
SDL_SetError("Passed a NULL semaphore");
return -1;
}

retval = SDL_MUTEX_TIMEDOUT;
SDL_LockMutex(sem->count_lock);
if ( sem->count > 0 ) {
--sem->count;
if ( sem_trywait(sem->sem) == 0 ) {
retval = 0;
}
SDL_UnlockMutex(sem->count_lock);
return retval;
}

int SDL_SemWait(SDL_sem *sem)
{
int retval;

if ( ! sem ) {
SDL_SetError("Passed a NULL semaphore");
return -1;
}

retval = sem_wait(sem->sem);
if ( retval < 0 ) {
SDL_SetError("sem_wait() failed");
}
return retval;
}

Expand All @@ -159,58 +158,53 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
return -1;
}

/* A timeout of 0 is an easy case */
/* Try the easy cases first */
if ( timeout == 0 ) {
return SDL_SemTryWait(sem);
}

SDL_LockMutex(sem->count_lock);
++sem->waiters_count;
retval = 0;
while ( (sem->count == 0) && (retval != SDL_MUTEX_TIMEDOUT) ) {
retval = SDL_CondWaitTimeout(sem->count_nonzero,
sem->count_lock, timeout);
if ( timeout == SDL_MUTEX_MAXWAIT ) {
return SDL_SemWait(sem);
}
--sem->waiters_count;
--sem->count;
SDL_UnlockMutex(sem->count_lock);

return retval;
}
/* Ack! We have to busy wait... */
timeout += SDL_GetTicks();
do {
retval = SDL_SemTryWait(sem);
if ( retval == 0 ) {
break;
}
SDL_Delay(1);
} while ( SDL_GetTicks() < timeout );

int SDL_SemWait(SDL_sem *sem)
{
return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
return retval;
}

Uint32 SDL_SemValue(SDL_sem *sem)
{
Uint32 value;

value = 0;
int ret = 0;
if ( sem ) {
SDL_LockMutex(sem->count_lock);
value = sem->count;
SDL_UnlockMutex(sem->count_lock);
sem_getvalue(sem->sem, &ret);
if ( ret < 0 ) {
ret = 0;
}
}
return value;
return (Uint32)ret;
}

int SDL_SemPost(SDL_sem *sem)
{
int retval;

if ( ! sem ) {
SDL_SetError("Passed a NULL semaphore");
return -1;
}

SDL_LockMutex(sem->count_lock);
if ( sem->waiters_count > 0 ) {
SDL_CondSignal(sem->count_nonzero);
retval = sem_post(sem->sem);
if ( retval < 0 ) {
SDL_SetError("sem_post() failed");
}
++sem->count;
SDL_UnlockMutex(sem->count_lock);

return 0;
return retval;
}

#endif /* DISABLE_THREADS */

0 comments on commit d88d9e2

Please sign in to comment.