Date: Fri, 15 Jul 2005 08:29:01 +0100
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. --HG-- extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%401100
This commit is contained in:
parent
94e3341891
commit
82d3a5b357
1 changed files with 65 additions and 71 deletions
|
@ -20,14 +20,13 @@
|
||||||
slouken@libsdl.org
|
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
|
#ifdef SAVE_RCSID
|
||||||
static char rcsid =
|
static char rcsid =
|
||||||
"@(#) $Id$";
|
"@(#) $Id$";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* An implementation of semaphores using mutexes and condition variables */
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
@ -81,51 +80,40 @@ int SDL_SemPost(SDL_sem *sem)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
struct SDL_semaphore
|
|
||||||
{
|
#include <stdio.h>
|
||||||
Uint32 count;
|
#include <stdlib.h>
|
||||||
Uint32 waiters_count;
|
#include <unistd.h> /* For getpid() */
|
||||||
SDL_mutex *count_lock;
|
#include <pthread.h>
|
||||||
SDL_cond *count_nonzero;
|
#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 *SDL_CreateSemaphore(Uint32 initial_value)
|
||||||
{
|
{
|
||||||
SDL_sem *sem;
|
SDL_sem *sem = (SDL_sem *) malloc(sizeof(SDL_sem));
|
||||||
|
if ( sem ) {
|
||||||
sem = (SDL_sem *)malloc(sizeof(*sem));
|
if ( sem_init(&sem->sem_data, 0, initial_value) < 0 ) {
|
||||||
if ( ! sem ) {
|
SDL_SetError("sem_init() failed");
|
||||||
|
free(sem);
|
||||||
|
sem = NULL;
|
||||||
|
} else {
|
||||||
|
sem->sem = &sem->sem_data;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
SDL_OutOfMemory();
|
SDL_OutOfMemory();
|
||||||
return(0);
|
|
||||||
}
|
}
|
||||||
sem->count = initial_value;
|
return sem;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* WARNING:
|
|
||||||
You cannot call this function when another thread is using the semaphore.
|
|
||||||
*/
|
|
||||||
void SDL_DestroySemaphore(SDL_sem *sem)
|
void SDL_DestroySemaphore(SDL_sem *sem)
|
||||||
{
|
{
|
||||||
if ( sem ) {
|
if ( sem ) {
|
||||||
sem->count = 0xFFFFFFFF;
|
sem_destroy(sem->sem);
|
||||||
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);
|
|
||||||
free(sem);
|
free(sem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -138,15 +126,26 @@ int SDL_SemTryWait(SDL_sem *sem)
|
||||||
SDL_SetError("Passed a NULL semaphore");
|
SDL_SetError("Passed a NULL semaphore");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = SDL_MUTEX_TIMEDOUT;
|
retval = SDL_MUTEX_TIMEDOUT;
|
||||||
SDL_LockMutex(sem->count_lock);
|
if ( sem_trywait(sem->sem) == 0 ) {
|
||||||
if ( sem->count > 0 ) {
|
|
||||||
--sem->count;
|
|
||||||
retval = 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;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,58 +158,53 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* A timeout of 0 is an easy case */
|
/* Try the easy cases first */
|
||||||
if ( timeout == 0 ) {
|
if ( timeout == 0 ) {
|
||||||
return SDL_SemTryWait(sem);
|
return SDL_SemTryWait(sem);
|
||||||
}
|
}
|
||||||
|
if ( timeout == SDL_MUTEX_MAXWAIT ) {
|
||||||
SDL_LockMutex(sem->count_lock);
|
return SDL_SemWait(sem);
|
||||||
++sem->waiters_count;
|
|
||||||
retval = 0;
|
|
||||||
while ( (sem->count == 0) && (retval != SDL_MUTEX_TIMEDOUT) ) {
|
|
||||||
retval = SDL_CondWaitTimeout(sem->count_nonzero,
|
|
||||||
sem->count_lock, timeout);
|
|
||||||
}
|
}
|
||||||
--sem->waiters_count;
|
|
||||||
--sem->count;
|
/* Ack! We have to busy wait... */
|
||||||
SDL_UnlockMutex(sem->count_lock);
|
timeout += SDL_GetTicks();
|
||||||
|
do {
|
||||||
|
retval = SDL_SemTryWait(sem);
|
||||||
|
if ( retval == 0 ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
SDL_Delay(1);
|
||||||
|
} while ( SDL_GetTicks() < timeout );
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SDL_SemWait(SDL_sem *sem)
|
|
||||||
{
|
|
||||||
return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
Uint32 SDL_SemValue(SDL_sem *sem)
|
Uint32 SDL_SemValue(SDL_sem *sem)
|
||||||
{
|
{
|
||||||
Uint32 value;
|
int ret = 0;
|
||||||
|
|
||||||
value = 0;
|
|
||||||
if ( sem ) {
|
if ( sem ) {
|
||||||
SDL_LockMutex(sem->count_lock);
|
sem_getvalue(sem->sem, &ret);
|
||||||
value = sem->count;
|
if ( ret < 0 ) {
|
||||||
SDL_UnlockMutex(sem->count_lock);
|
ret = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return value;
|
return (Uint32)ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SDL_SemPost(SDL_sem *sem)
|
int SDL_SemPost(SDL_sem *sem)
|
||||||
{
|
{
|
||||||
|
int retval;
|
||||||
|
|
||||||
if ( ! sem ) {
|
if ( ! sem ) {
|
||||||
SDL_SetError("Passed a NULL semaphore");
|
SDL_SetError("Passed a NULL semaphore");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_LockMutex(sem->count_lock);
|
retval = sem_post(sem->sem);
|
||||||
if ( sem->waiters_count > 0 ) {
|
if ( retval < 0 ) {
|
||||||
SDL_CondSignal(sem->count_nonzero);
|
SDL_SetError("sem_post() failed");
|
||||||
}
|
}
|
||||||
++sem->count;
|
return retval;
|
||||||
SDL_UnlockMutex(sem->count_lock);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* DISABLE_THREADS */
|
#endif /* DISABLE_THREADS */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue