Skip to content
Permalink
Browse files

Patrice's fixes for GNU Pthread support

  • Loading branch information
slouken committed Apr 1, 2002
1 parent f4ec1f9 commit b6b7baa0952658963ea7c57a89e943ba0a17fceb
@@ -1265,6 +1265,7 @@ CheckPTH()
PTH_LIBS=`$PTH_CONFIG --libs --all`
SDL_CFLAGS="$SDL_CFLAGS $PTH_CFLAGS"
SDL_LIBS="$SDL_LIBS $PTH_LIBS"
CFLAGS="$CFLAGS -DENABLE_PTH"
use_pth=yes
fi
AC_MSG_CHECKING(pth)
@@ -2295,16 +2296,20 @@ case "$target" in
if test x$enable_pth = xyes; then
COPY_ARCH_SRC(src/thread, pth, SDL_systhread.c)
COPY_ARCH_SRC(src/thread, pth, SDL_systhread_c.h)
COPY_ARCH_SRC(src/thread, pth, SDL_sysmutex.c)
COPY_ARCH_SRC(src/thread, pth, SDL_sysmutex_c.h)
COPY_ARCH_SRC(src/thread, pth, SDL_syscond.c)
COPY_ARCH_SRC(src/thread, pth, SDL_syscond_c.h)
else
COPY_ARCH_SRC(src/thread, generic, SDL_systhread.c)
COPY_ARCH_SRC(src/thread, generic, SDL_systhread_c.h)
COPY_ARCH_SRC(src/thread, generic, SDL_sysmutex.c)
COPY_ARCH_SRC(src/thread, generic, SDL_sysmutex_c.h)
COPY_ARCH_SRC(src/thread, generic, SDL_syscond.c)
COPY_ARCH_SRC(src/thread, generic, SDL_syscond_c.h)
fi
COPY_ARCH_SRC(src/thread, generic, SDL_sysmutex.c)
COPY_ARCH_SRC(src/thread, generic, SDL_sysmutex_c.h)
COPY_ARCH_SRC(src/thread, linux, SDL_syssem.c)
COPY_ARCH_SRC(src/thread, generic, SDL_syssem.c)
COPY_ARCH_SRC(src/thread, generic, SDL_syssem_c.h)
COPY_ARCH_SRC(src/thread, generic, SDL_syscond.c)
COPY_ARCH_SRC(src/thread, generic, SDL_syscond_c.h)
fi
# Set up files for the timer library
if test x$enable_timers = xyes; then
@@ -52,6 +52,12 @@ int SDL_ThreadsInit(void)
{
int retval;

#ifdef ENABLE_PTH
if (!pth_init()) {
return -1;
}
#endif

retval = 0;
/* Set the thread lock creation flag so that we can reuse an
existing lock on the system - since this mutex never gets
@@ -80,6 +86,10 @@ void SDL_ThreadsQuit()
if ( mutex != NULL ) {
SDL_DestroyMutex(mutex);
}

#ifdef ENABLE_PTH
pth_kill();
#endif
}

/* Routines for manipulating the thread list */
@@ -0,0 +1,140 @@
/*
* GNU pth conditions variables
*
* Patrice Mandin
*/

#include <stdio.h>
#include <stdlib.h>
#include <pth.h>

#include "SDL_error.h"
#include "SDL_thread.h"
#include "SDL_syscond_c.h"
#include "SDL_sysmutex_c.h"

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

cond = (SDL_cond *) malloc(sizeof(SDL_cond));
if ( cond ) {
if ( pth_cond_init(&(cond->condpth_p)) < 0 ) {
SDL_SetError("pthread_cond_init() failed");
free(cond);
cond = NULL;
}
} else {
SDL_OutOfMemory();
}
return(cond);
}

/* Destroy a condition variable */
void SDL_DestroyCond(SDL_cond *cond)
{
if ( cond ) {
free(cond);
}
}

/* Restart one of the threads that are waiting on the condition variable */
int SDL_CondSignal(SDL_cond *cond)
{
int retval;

if ( ! cond ) {
SDL_SetError("Passed a NULL condition variable");
return -1;
}

retval = 0;
if ( pth_cond_notify(&(cond->condpth_p), FALSE) != 0 ) {
SDL_SetError("pth_cond_notify() failed");
retval = -1;
}
return retval;
}

/* Restart all threads that are waiting on the condition variable */
int SDL_CondBroadcast(SDL_cond *cond)
{
int retval;

if ( ! cond ) {
SDL_SetError("Passed a NULL condition variable");
return -1;
}

retval = 0;
if ( pth_cond_notify(&(cond->condpth_p), TRUE) != 0 ) {
SDL_SetError("pth_cond_notify() failed");
retval = -1;
}
return retval;
}

/* Wait on the condition variable for at most 'ms' milliseconds.
The mutex must be locked before entering this function!
The mutex is unlocked during the wait, and locked again after the wait.
Typical use:
Thread A:
SDL_LockMutex(lock);
while ( ! condition ) {
SDL_CondWait(cond);
}
SDL_UnlockMutex(lock);
Thread B:
SDL_LockMutex(lock);
...
condition = true;
...
SDL_UnlockMutex(lock);
*/
int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
{
int retval;
pth_event_t ev;
int sec;

if ( ! cond ) {
SDL_SetError("Passed a NULL condition variable");
return -1;
}

retval = 0;

sec = ms/1000;
ev = pth_event(PTH_EVENT_TIME, pth_timeout(sec,(ms-sec*1000)*1000));

if ( pth_cond_await(&(cond->condpth_p), &(mutex->mutexpth_p), ev) != 0 ) {
SDL_SetError("pth_cond_await() failed");
retval = -1;
}

pth_event_free(ev, PTH_FREE_ALL);

return retval;
}

/* Wait on the condition variable forever */
int SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex)
{
int retval;

if ( ! cond ) {
SDL_SetError("Passed a NULL condition variable");
return -1;
}

retval = 0;
if ( pth_cond_await(&(cond->condpth_p), &(mutex->mutexpth_p), NULL) != 0 ) {
SDL_SetError("pth_cond_await() failed");
retval = -1;
}
return retval;
}
@@ -0,0 +1,9 @@
#ifndef _SDL_SYSCOND_C_H_
#define _SDL_SYSCOND_C_H_

struct SDL_cond
{
pth_cond_t condpth_p;
};

#endif /* _SDL_SYSCOND_C_H_ */
@@ -0,0 +1,67 @@
/*
* GNU pth mutexes
*
* Patrice Mandin
*/

#include <stdio.h>
#include <stdlib.h>
#include <pth.h>

#include "SDL_error.h"
#include "SDL_mutex.h"
#include "SDL_sysmutex_c.h"

/* Create a mutex */
SDL_mutex *SDL_CreateMutex(void)
{
SDL_mutex *mutex;

/* Allocate mutex memory */
mutex = (SDL_mutex *)malloc(sizeof(*mutex));
if ( mutex ) {
/* Create the mutex, with initial value signaled */
if (!pth_mutex_init(&(mutex->mutexpth_p))) {
SDL_SetError("Couldn't create mutex");
free(mutex);
mutex = NULL;
}
} else {
SDL_OutOfMemory();
}
return(mutex);
}

/* Free the mutex */
void SDL_DestroyMutex(SDL_mutex *mutex)
{
if ( mutex ) {
free(mutex);
}
}

/* Lock the mutex */
int SDL_mutexP(SDL_mutex *mutex)
{
if ( mutex == NULL ) {
SDL_SetError("Passed a NULL mutex");
return -1;
}

pth_mutex_acquire(&(mutex->mutexpth_p), FALSE, NULL);

return(0);
}

/* Unlock the mutex */
int SDL_mutexV(SDL_mutex *mutex)
{
if ( mutex == NULL ) {
SDL_SetError("Passed a NULL mutex");
return -1;
}

pth_mutex_release(&(mutex->mutexpth_p));

return(0);
}
@@ -0,0 +1,8 @@
#ifndef _SDL_SYSMUTEX_C_H_
#define _SDL_SYSMUTEX_C_H_

struct SDL_mutex {
pth_mutex_t mutexpth_p;
};

#endif /* _SDL_SYSMUTEX_C_H_ */
@@ -25,7 +25,11 @@ static char rcsid =
"@(#) $Id$";
#endif

/* Pth thread management routines for SDL */
/*
* GNU pth threads
*
* Patrice Mandin
*/

#include "SDL_error.h"
#include "SDL_thread.h"
@@ -51,17 +55,16 @@ int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
{
pth_attr_t type;

/* Create a new attribute */
type = pth_attr_new();

/* Set the thread attributes */
if ( pth_attr_init(type) != 0 ) {
if ( type == NULL ) {
SDL_SetError("Couldn't initialize pth attributes");
return(-1);
}
pth_attr_set(type, PTH_ATTR_JOINABLE, TRUE);

/* Create the thread and go! */
if ( pth_spawn(type, RunThread, args) != 0 ) {
if ( pth_spawn(type, RunThread, args) == NULL ) {
SDL_SetError("Not enough resources to create thread");
return(-1);
}
@@ -72,6 +75,7 @@ void SDL_SYS_SetupThread(void)
{
int i;
sigset_t mask;
int oldstate;

/* Mask asynchronous signals for this thread */
sigemptyset(&mask);
@@ -81,9 +85,7 @@ void SDL_SYS_SetupThread(void)
pth_sigmask(SIG_BLOCK, &mask, 0);

/* Allow ourselves to be asynchronously cancelled */
{ int oldstate;
pth_cancel_state(PTH_CANCEL_ASYNCHRONOUS, &oldstate);
}
pth_cancel_state(PTH_CANCEL_ASYNCHRONOUS, &oldstate);
}

/* WARNING: This may not work for systems with 64-bit pid_t */
@@ -20,6 +20,11 @@
slouken@libsdl.org
*/

#ifndef _SDL_SYSTHREAD_C_H_
#define _SDL_SYSTHREAD_C_H_

#include <pth.h>

typedef pth_t SYS_ThreadHandle;

#endif /* _SDL_SYSTHREAD_C_H_ */

0 comments on commit b6b7baa

Please sign in to comment.