Conditions variables and semaphores in SDL

This is a new patch against the CVS version of SDL 1.1.

What it does :

  • New API for condition variables, in SDL_cond.h :

/* Create a condition variable */
extern DECLSPEC SDL_cond * SDL_CreateCond(void);

/* Destroy a condition variable */
extern DECLSPEC void SDL_DestroyCond(SDL_cond *cond);

/* Restart one of the threads that are waiting on the condition variable */
extern DECLSPEC void SDL_CondSignal(SDL_cond *cond);

/* Restart all threads that are waiting on the condition variable */
extern DECLSPEC void SDL_CondBroadcast(SDL_cond *cond);

/* Wait on the condition variable, unlocking the provided mutex.
The mutex must be locked before entering this function!
*/
extern DECLSPEC void SDL_CondWait(SDL_cond *cond, SDL_mutex *mut);

/* Waits for at most ‘ms’ milliseconds, and returns SDL_FALSE if it timed out */
extern DECLSPEC SDL_bool SDL_CondTimedWait(SDL_cond *cond, SDL_mutex *mut,
Uint32 ms);

This is basically a wrapper around the POSIX condition variables, and its usage
is identical. Actually it is only implemented for Unix systems with POSIX
threads right now, so we need to implement those for Win32, MacOS and BeOS as
well.

  • Native implementation of semaphores (on top of POSIX for Unix), enabled by
    default in configure
  • Reimplemented the generic semaphore implementation using a condition
    variable. This should be correct now, although I have some doubts about my
    implementation of SDL_DestroySemaphore() …

Comments are welcome :). With all that, we have all basic synchronization
mechanisms in SDL (mutexes, condition variables and counting semaphores).–
Stephane Peter
Programmer
Loki Entertainment Software

“Microsoft has done to computers what McDonald’s has done to gastronomy”
-------------- next part --------------
Index: configure.in

RCS file: /cvs/SDL/configure.in,v
retrieving revision 1.25.2.48
diff -u -r1.25.2.48 configure.in
configure.in 2000/04/15 01:40:49 1.25.2.48
+++ configure.in 2000/04/19 23:13:31
@@ -545,6 +545,15 @@
AM_CONDITIONAL(USE_CLONE, test x$use_clone = xyes)
}

+dnl Check if we want to include native semaphore code
+CheckSEM()
+{

  • AC_ARG_ENABLE(native-sem,
    +[ --enable-native-sem Use native semaphores [default=yes]],
  •   , enable_native_sem=yes)
    
  • AM_CONDITIONAL(USE_NATIVE_SEM, test x$enable_native_sem = xyes)
    +}

dnl Determine whether the compiler can produce Win32 executables
CheckWIN32()
{
@@ -635,6 +644,7 @@
CheckAAlib
CheckOpenGL
CheckPTHREAD

  •   CheckSEM
       # Set up files for the main() stub
       COPY_ARCH_SRC(src/main, linux, SDL_main.c)
       # Set up files for the audio library
    

@@ -654,7 +664,10 @@
COPY_ARCH_SRC(src/thread, linux, clone.S)
fi
COPY_ARCH_SRC(src/thread, linux, SDL_mutex.c)

  •        COPY_ARCH_SRC(src/thread, linux, SDL_mutex_c.h)
           COPY_ARCH_SRC(src/thread, linux, SDL_systhread.c)
    
  •        COPY_ARCH_SRC(src/thread, linux, SDL_syssem.c)
    
  •        COPY_ARCH_SRC(src/thread, linux, SDL_syscond.c)
           COPY_ARCH_SRC(src/thread, linux, SDL_systhread_c.h)
       fi
       # Set up files for the timer library
    

@@ -670,6 +683,7 @@
CheckOpenGL
CheckPTHREAD
CheckKSTAT

  •   CheckSEM
       # Set up files for the main() stub
       COPY_ARCH_SRC(src/main, linux, SDL_main.c)
       # Set up files for the audio library
    

@@ -687,7 +701,10 @@
# Set up files for the thread library
if test x$enable_threads = xyes; then
COPY_ARCH_SRC(src/thread, linux, SDL_mutex.c)

  •        COPY_ARCH_SRC(src/thread, linux, SDL_mutex_c.h)
           COPY_ARCH_SRC(src/thread, linux, SDL_systhread.c)
    
  •        COPY_ARCH_SRC(src/thread, linux, SDL_syssem.c)
    
  •        COPY_ARCH_SRC(src/thread, linux, SDL_syscond.c)
           COPY_ARCH_SRC(src/thread, linux, SDL_systhread_c.h)
       fi
       # Set up files for the timer library
    

@@ -717,6 +734,8 @@
# Set up files for the thread library
if test x$enable_threads = xyes; then
COPY_ARCH_SRC(src/thread, linux, SDL_mutex.c)

  •        COPY_ARCH_SRC(src/thread, linux, SDL_mutex_c.h)
    
  •        COPY_ARCH_SRC(src/thread, linux, SDL_syscond.c)
           COPY_ARCH_SRC(src/thread, irix, SDL_systhread.c)
           COPY_ARCH_SRC(src/thread, irix, SDL_systhread_c.h)
       fi
    

@@ -732,6 +751,7 @@
CheckAAlib
CheckOpenGL
CheckPTHREAD

  •   CheckSEM
       # Set up files for the main() stub
       COPY_ARCH_SRC(src/main, linux, SDL_main.c)
       # Set up files for the audio library
    

@@ -749,7 +769,10 @@
# Set up files for the thread library
if test x$enable_threads = xyes; then
COPY_ARCH_SRC(src/thread, linux, SDL_mutex.c)

  •        COPY_ARCH_SRC(src/thread, linux, SDL_mutex_c.h)
    
  •        COPY_ARCH_SRC(src/thread, linux, SDL_syscond.c)
           COPY_ARCH_SRC(src/thread, linux, SDL_systhread.c)
    
  •        COPY_ARCH_SRC(src/thread, linux, SDL_syssem.c)
           COPY_ARCH_SRC(src/thread, linux, SDL_systhread_c.h)
       fi
       # Set up files for the timer library
    

@@ -764,6 +787,7 @@
CheckAAlib
CheckOpenGL
CheckPTHREAD

  •   CheckSEM
       # Set up files for the main() stub
       COPY_ARCH_SRC(src/main, linux, SDL_main.c)
       # Set up files for the audio library
    

@@ -784,7 +808,10 @@
# Set up files for the thread library
if test x$enable_threads = xyes; then
COPY_ARCH_SRC(src/thread, linux, SDL_mutex.c)

  •        COPY_ARCH_SRC(src/thread, linux, SDL_mutex_c.h)
    
  •        COPY_ARCH_SRC(src/thread, linux, SDL_syscond.c)
           COPY_ARCH_SRC(src/thread, linux, SDL_systhread.c)
    
  •        COPY_ARCH_SRC(src/thread, linux, SDL_syssem.c)
           COPY_ARCH_SRC(src/thread, linux, SDL_systhread_c.h)
       fi
       # Set up files for the timer library
    

@@ -802,6 +829,7 @@
CheckAAlib
CheckOpenGL
CheckPTHREAD

  •   CheckSEM
       # Set up files for the main() stub
       COPY_ARCH_SRC(src/main, linux, SDL_main.c)
       # Set up files for the audio library
    

@@ -819,7 +847,10 @@
# Set up files for the thread library
if test x$enable_threads = xyes; then
COPY_ARCH_SRC(src/thread, linux, SDL_mutex.c)

  •        COPY_ARCH_SRC(src/thread, linux, SDL_mutex_c.h)
    
  •        COPY_ARCH_SRC(src/thread, linux, SDL_syscond.c)
           COPY_ARCH_SRC(src/thread, linux, SDL_systhread.c)
    
  •        COPY_ARCH_SRC(src/thread, linux, SDL_syssem.c)
           COPY_ARCH_SRC(src/thread, linux, SDL_systhread_c.h)
       fi
       # Set up files for the timer library
    

Index: include/Makefile.am

RCS file: /cvs/SDL/include/Makefile.am,v
retrieving revision 1.3.2.3
diff -u -r1.3.2.3 Makefile.am
— include/Makefile.am 2000/04/19 04:08:53 1.3.2.3
+++ include/Makefile.am 2000/04/19 23:13:31
@@ -24,6 +24,7 @@
SDL_quit.h
SDL_rwops.h
SDL_semaphore.h \

  • SDL_cond.h
    SDL_syswm.h
    SDL_thread.h
    SDL_timer.h
    Index: include/SDL_cond.h
    ===================================================================
    RCS file: SDL_cond.h
    diff -N SDL_cond.h
    — /dev/null Tue May 5 13:32:27 1998
    +++ SDL_cond.h Wed Apr 19 16:13:31 2000
    @@ -0,0 +1,74 @@
    +/*
  • SDL - Simple DirectMedia Layer
  • Copyright © 1997, 1998, 1999, 2000 Sam Lantinga
  • This library is free software; you can redistribute it and/or
  • modify it under the terms of the GNU Library General Public
  • License as published by the Free Software Foundation; either
  • version 2 of the License, or (at your option) any later version.
  • This library is distributed in the hope that it will be useful,
  • but WITHOUT ANY WARRANTY; without even the implied warranty of
  • MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  • Library General Public License for more details.
  • You should have received a copy of the GNU Library General Public
  • License along with this library; if not, write to the Free
  • Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  • Sam Lantinga
  • slouken at devolution.com
    +*/

+#ifdef SAVE_RCSID
+static char rcsid =

  • “@(#) $Id: SDL_cond.h,v 1.4.2.1 2000/03/16 15:20:37 hercules Exp $”;
    +#endif

+#ifndef _SDL_cond_h
+#define _SDL_cond_h
+
+#include “SDL_mutex.h”
+#include “SDL_types.h”
+
+/*

  • Header for the SDL condition variables
    +*/

+#include “begin_code.h”
+/* Set up for C function definitions, even when using C++ /
+#ifdef __cplusplus
+extern “C” {
+#endif
+
+/
The SDL condition variable structure, defined in SDL_cond.c /
+struct SDL_cond;
+typedef struct SDL_cond SDL_cond;
+
+/
Create a condition variable /
+extern DECLSPEC SDL_cond * SDL_CreateCond(void);
+
+/
Destroy a condition variable */
+extern DECLSPEC void SDL_DestroyCond(SDL_cond cond);
+
+/
Restart one of the threads that are waiting on the condition variable */
+extern DECLSPEC void SDL_CondSignal(SDL_cond cond);
+
+/
Restart all threads that are waiting on the condition variable */
+extern DECLSPEC void SDL_CondBroadcast(SDL_cond cond);
+
+/
Wait on the condition variable, unlocking the provided mutex.

  • The mutex must be locked before entering this function!
  • */
    +extern DECLSPEC void SDL_CondWait(SDL_cond *cond, SDL_mutex *mut);

+/* Waits for at most ‘ms’ milliseconds, and returns SDL_FALSE if it timed out *
/
+extern DECLSPEC SDL_bool SDL_CondTimedWait(SDL_cond *cond, SDL_mutex mut, Uint
32 ms);
+
+/
Ends C function definitions when using C++ /
+#ifdef __cplusplus
+};
+#endif
+#include “close_code.h”
+
+#endif /
_SDL_cond_h */
Index: src/thread/Makefile.am

RCS file: /cvs/SDL/src/thread/Makefile.am,v
retrieving revision 1.1.1.1.2.2
diff -u -r1.1.1.1.2.2 Makefile.am
— src/thread/Makefile.am 2000/04/19 03:14:04 1.1.1.1.2.2
+++ src/thread/Makefile.am 2000/04/19 23:13:32
@@ -13,18 +13,36 @@
endif

Include the architecture-independent sources

+if USE_NATIVE_SEM
COMMON_SRCS =
SDL_systhread.h
SDL_thread.c
SDL_thread_c.h
+else
+COMMON_SRCS = \

  • SDL_systhread.h \
  • SDL_thread.c \
  • SDL_sem.c \
  • SDL_thread_c.h
    +endif

Include the architecture-specific sources

+if USE_NATIVE_SEM
+ARCH_SRCS = \

  • SDL_mutex.c \
  • SDL_syssem.c \
  • SDL_syscond.c \
  • SDL_systhread.c \
  • SDL_systhread_c.h \
  • $(THREAD_ASM_SRC)
    +else
    ARCH_SRCS = \
  • SDL_mutex.c \
  • SDL_sem.c \
  • SDL_mutex.c \
  • SDL_syscond.c
    SDL_systhread.c
    SDL_systhread_c.h
    $(THREAD_ASM_SRC)
    +endif

libthread_la_SOURCES = $(COMMON_SRCS) $(ARCH_SRCS)

Index: src/thread/SDL_sem.c

RCS file: /cvs/SDL/src/thread/Attic/SDL_sem.c,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 SDL_sem.c
— src/thread/SDL_sem.c 2000/04/19 04:08:53 1.1.2.2
+++ src/thread/SDL_sem.c 2000/04/19 23:13:32
@@ -28,15 +28,15 @@
/* An implementation of counting semaphores using mutexes */

#include “SDL_error.h”
-#include “SDL_mutex.h”
+#include “SDL_cond.h”
#include “SDL_semaphore.h”

struct SDL_semaphore
{

  • Sint32 count;
  • Uint32 count;
  • Uint32 waiters_count;
    SDL_mutex *count_lock;
  • SDL_mutex *wait_lock;
  • SDL_cond *count_nonzero;
    };

SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
@@ -48,15 +48,15 @@
SDL_OutOfMemory();
return(0);
}

  • sem->count = (Sint32) initial_value;
  • sem->count = initial_value;

  • sem->waiters_count = 0;

    sem->count_lock = SDL_CreateMutex();

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

    return(sem);
    }
    @@ -64,76 +64,57 @@
    void SDL_DestroySemaphore(SDL_sem *sem)
    {
    if ( sem ) {

  •   if ( sem->count_lock ) {
    
  •   	/* Small attempt at releasing threads */
    
  •   	SDL_LockMutex(sem->count_lock);
    
  •   	while ( sem->count < 0 ) {
    
  •   		SDL_UnlockMutex(sem->wait_lock);
    
  •   		++sem->count;
    
  •   	}
    
  •   	SDL_UnlockMutex(sem->count_lock);
    
  •   	SDL_DestroyMutex(sem->count_lock);
    
  •   }
    
  •   if ( sem->wait_lock ) {
    
  •   	SDL_DestroyMutex(sem->wait_lock);
    
  •   SDL_LockMutex(sem->count_lock);
    
  •   while ( sem->waiters_count > 0) {
    
  •   	SDL_CondWait(sem->count_nonzero, sem->count_lock);
      }
    
  •   SDL_UnlockMutex(sem->count_lock);
    
  •   SDL_DestroyCond(sem->count_nonzero);
    
  •   SDL_DestroyMutex(sem->count_lock);
      free(sem);
    
    }
    }

void SDL_SemWait(SDL_sem *sem)
{

  • SDL_bool must_wait;
  • SDL_LockMutex(sem->count_lock);
  • if ( sem->count > 0 ) {
  •   must_wait = SDL_FALSE;
    
  • } else {
  •   must_wait = SDL_TRUE;
    
  • }
  • ++sem->waiters_count;
  • while(sem->count == 0)
  •   SDL_CondWait(sem->count_nonzero, sem->count_lock);
    
  • –sem->waiters_count;
    –sem->count;
    SDL_UnlockMutex(sem->count_lock);
  • if ( must_wait ) {
  •   SDL_LockMutex(sem->wait_lock);
    
  • }
    }

SDL_bool SDL_SemTryWait(SDL_sem *sem)
{

  • SDL_bool must_wait;
  • SDL_bool ret = SDL_FALSE;

    SDL_LockMutex(sem->count_lock);
    if ( sem->count > 0 ) {

  •   must_wait = SDL_FALSE;
    
  • } else {
  •   must_wait = SDL_TRUE;
    
  • }
  • if ( ! must_wait ) {
    –sem->count;
  •   ret = SDL_TRUE;
    
    }
    SDL_UnlockMutex(sem->count_lock);
  • return !must_wait;
  • return(ret);
    }

Uint32 SDL_SemValue(SDL_sem *sem)
{
Uint32 value;

  • if ( sem->count < 0 ) {
  •   value = 0;
    
  • } else {
  •   value = (Uint32) sem->count;
    
  • }
  • SDL_LockMutex(sem->count_lock);
  • value = sem->count;
  • SDL_UnlockMutex(sem->count_lock);
    return value;
    }

void SDL_SemPost(SDL_sem *sem)
{
SDL_LockMutex(sem->count_lock);

  • if ( sem->count < 0 ) {
  •   SDL_UnlockMutex(sem->wait_lock);
    
  • if ( sem->waiters_count > 0 ) {
  •   SDL_CondSignal(sem->count_nonzero);
    
    }
    ++sem->count;
    SDL_UnlockMutex(sem->count_lock);
    Index: src/thread/linux/SDL_mutex_c.h
    ===================================================================
    RCS file: SDL_mutex_c.h
    diff -N SDL_mutex_c.h
    — /dev/null Tue May 5 13:32:27 1998
    +++ SDL_mutex_c.h Wed Apr 19 16:13:32 2000
    @@ -0,0 +1,46 @@
    +/*
  • SDL - Simple DirectMedia Layer
  • Copyright © 1997, 1998, 1999, 2000 Sam Lantinga
  • This library is free software; you can redistribute it and/or
  • modify it under the terms of the GNU Library General Public
  • License as published by the Free Software Foundation; either
  • version 2 of the License, or (at your option) any later version.
  • This library is distributed in the hope that it will be useful,
  • but WITHOUT ANY WARRANTY; without even the implied warranty of
  • MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  • Library General Public License for more details.
  • You should have received a copy of the GNU Library General Public
  • License along with this library; if not, write to the Free
  • Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  • Sam Lantinga
  • slouken at devolution.com
    +*/

+#ifdef SAVE_RCSID
+static char rcsid =

  • “@(#) $Id: SDL_thread_c.h,v 1.2.2.1 2000/03/16 15:20:38 hercules Exp $”;
    +#endif

+#ifndef _SDL_mutex_c_h
+#define _SDL_mutex_c_h
+
+#ifdef SDL_USE_PTHREADS
+
+struct SDL_mutex {

  • pthread_mutex_t id;
    +};

+#else
+
+struct SDL_mutex {

  • int id;
    +};

+#endif
+
+
+#endif /* _SDL_mutex_c_h */
Index: src/thread/linux/SDL_syscond.c

RCS file: SDL_syscond.c
diff -N SDL_syscond.c
— /dev/null Tue May 5 13:32:27 1998
+++ SDL_syscond.c Wed Apr 19 16:13:32 2000
@@ -0,0 +1,110 @@
+/*

  • SDL - Simple DirectMedia Layer
  • Copyright © 1997, 1998, 1999, 2000 Sam Lantinga
  • This library is free software; you can redistribute it and/or
  • modify it under the terms of the GNU Library General Public
  • License as published by the Free Software Foundation; either
  • version 2 of the License, or (at your option) any later version.
  • This library is distributed in the hope that it will be useful,
  • but WITHOUT ANY WARRANTY; without even the implied warranty of
  • MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  • Library General Public License for more details.
  • You should have received a copy of the GNU Library General Public
  • License along with this library; if not, write to the Free
  • Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  • Sam Lantinga
  • slouken at devolution.com
    +*/

+#ifdef SAVE_RCSID
+static char rcsid =

  • “@(#) $Id: SDL_thread.c,v 1.2.2.3 2000/03/30 06:30:31 hercules Exp $”;
    +#endif

+#ifndef SDL_USE_PTHREADS
+#error You must use POSIX threads for native condition variables on this system
!
+#endif
+
+#include “SDL_error.h”
+#include “SDL_cond.h”
+#include <pthread.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+#include “SDL_mutex_c.h”
+
+struct SDL_cond
+{

  • pthread_cond_t cond;
    +};

+/* Create a condition variable */
+SDL_cond * SDL_CreateCond(void)
+{

  • SDL_cond *ptr;
  • ptr = (SDL_cond *) malloc(sizeof(SDL_cond));
  • pthread_cond_init(&ptr->cond, NULL);
  • return(ptr);
    +}

+/* Destroy a condition variable */
+void SDL_DestroyCond(SDL_cond *cond)
+{

  • if ( cond ) {
  •   pthread_cond_destroy(&cond->cond);
    
  •   free(cond);
    
  • }
    +}

+/* Restart one of the threads that are waiting on the condition variable */
+void SDL_CondSignal(SDL_cond *cond)
+{

  • if ( cond ) {
  •   pthread_cond_signal(&cond->cond);
    
  • }
    +}

+/* Restart all threads that are waiting on the condition variable */
+void SDL_CondBroadcast(SDL_cond *cond)
+{

  • if ( cond ) {
  •   pthread_cond_broadcast(&cond->cond);
    
  • }
    +}

+/* Wait on the condition variable, unlocking the provided mutex.

  • The mutex must be locked before entering this function!
  • */
    +void SDL_CondWait(SDL_cond *cond, SDL_mutex *mut)
    +{
  • if ( cond ) {
  •   pthread_cond_wait(&cond->cond, &mut->id);
    
  • }
    +}

+/* Waits for at most ‘ms’ milliseconds, and returns SDL_FALSE if it timed out *
/
+SDL_bool SDL_CondTimedWait(SDL_cond *cond, SDL_mutex *mut, Uint32 ms)
+{

  • if ( cond ) {
  •   struct timeval delta;
    
  •   struct timespec abstime;
    
  •   int ret;
    
  •   gettimeofday(&delta, NULL);
    
  •   abstime.tv_sec = delta.tv_sec + (ms/1000);
    
  •   abstime.tv_nsec = delta.tv_usec * 1000;
    
  •   ret = pthread_cond_timedwait(&cond->cond, &mut->id, &abstime);
    
  •   if ( ! ret ) {
    
  •   	return(SDL_TRUE);
    
  •   }
    
  • }
  • return(SDL_FALSE);
    +}
    Index: src/thread/linux/SDL_syssem.c
    ===================================================================
    RCS file: SDL_syssem.c
    diff -N SDL_syssem.c
    — /dev/null Tue May 5 13:32:27 1998
    +++ SDL_syssem.c Wed Apr 19 16:13:32 2000
    @@ -0,0 +1,89 @@
    +/*
  • SDL - Simple DirectMedia Layer
  • Copyright © 1997, 1998, 1999, 2000 Sam Lantinga
  • This library is free software; you can redistribute it and/or
  • modify it under the terms of the GNU Library General Public
  • License as published by the Free Software Foundation; either
  • version 2 of the License, or (at your option) any later version.
  • This library is distributed in the hope that it will be useful,
  • but WITHOUT ANY WARRANTY; without even the implied warranty of
  • MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  • Library General Public License for more details.
  • You should have received a copy of the GNU Library General Public
  • License along with this library; if not, write to the Free
  • Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  • Sam Lantinga
  • slouken at devolution.com
    +*/

+#ifdef SAVE_RCSID
+static char rcsid =

  • “@(#) $Id: SDL_thread.c,v 1.2.2.3 2000/03/30 06:30:31 hercules Exp $”;
    +#endif

+#include “SDL_error.h”
+#include “SDL_semaphore.h”
+#include <semaphore.h>
+
+/* Wrapper around POSIX 1003.1b semaphores */
+
+struct SDL_semaphore {

  • sem_t sem;
    +};

+/* Create a semaphore, initialized with value */
+SDL_sem * SDL_CreateSemaphore(Uint32 value)
+{

  • SDL_sem *sem = (SDL_sem *) malloc(sizeof(SDL_sem));
  • if ( sem ) {
  •   sem_init(&sem->sem, 0, value);
    
  • }
  • return sem;
    +}

+/* Destroy a semaphore */
+void SDL_DestroySemaphore(SDL_sem *sem)
+{

  • if ( sem ) {
  •   sem_destroy(&sem->sem);
    
  •   free(sem);
    
  • }
    +}

+/* Suspend the calling thread until the semaphore count is non-zero,

  • then decreases the counter
  • */
    +void SDL_SemWait(SDL_sem *sem)
    +{
  • sem_wait(&sem->sem);
    +}

+/* Non-blocking variant of SDL_SemWait(), returns SDL_FALSE if counter is zero
*/
+SDL_bool SDL_SemTryWait(SDL_sem *sem)
+{

  • SDL_bool ret = SDL_FALSE;
  • if ( sem ) {
  •   ret = (sem_trywait(&sem->sem) == 0);
    
  • }
  • return ret;
    +}

+/* Returns the current count of the semaphore */
+Uint32 SDL_SemValue(SDL_sem *sem)
+{

  • Uint32 ret = 0;
  • if ( sem ) {
  •   sem_getvalue(&sem->sem, &ret);
    
  • }
  • return ret;
    +}

+/* Atomically increases the semaphore’s count (not blocking) */
+void SDL_SemPost(SDL_sem *sem)
+{

  • sem_post(&sem->sem);
    +}

I have only played with counting semaphores as are documented in Modern
Operating Systems by Andrew Tanenbaum. Is this the same thing?

If so… COOL. I can’t wait to play with this stuff!!!

Dave

I have only played with counting semaphores as are documented in Modern
Operating Systems by Andrew Tanenbaum. Is this the same thing?

If so… COOL. I can’t wait to play with this stuff!!!

Yep, but it’s at an unstable state until it’s implemented on all platforms.

The condition variable stuff is the most tricky, since neither Win32 nor
BeOS nor Linux prior to glibc-2.1 have them implemented natively, and code
that I’ve found for BeOS and Win32 looks like it might have subtle bugs.

See ya,
-Sam Lantinga, Lead Programmer, Loki Entertainment Software

In article ,
Sam Lantinga writes:

I have only played with counting semaphores as are documented in Modern
Operating Systems by Andrew Tanenbaum. Is this the same thing?

If so… COOL. I can’t wait to play with this stuff!!!

Yep, but it’s at an unstable state until it’s implemented on all platforms.

The condition variable stuff is the most tricky, since neither Win32 nor
BeOS nor Linux prior to glibc-2.1 have them implemented natively, and code
that I’ve found for BeOS and Win32 looks like it might have subtle bugs.

AFAIK, the condition variables have been an integral part of libpthread from
the beginning, so they should be available on glibc 2.0 as well. Though you
had to install LinuxThreads on libc5…–
Stephane Peter
Programmer
Loki Entertainment Software

“Microsoft has done to computers what McDonald’s has done to gastronomy”

AFAIK, the condition variables have been an integral part of libpthread from
the beginning, so they should be available on glibc 2.0 as well. Though you
had to install LinuxThreads on libc5…

There’s a bug in LinuxThreads versions prior to glibc-2.1 in which threads
do not receive signals sent by the thread manager, resulting in hangs in
mutex and thread creation operations. I’m assuming similar problems occur
with condition variables.

See ya,
-Sam Lantinga, Lead Programmer, Loki Entertainment Software