Commit e3affe9e authored by Sam Lantinga's avatar Sam Lantinga

Patrice's fixes for GNU Pthread support

--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%40330
parent 471f52e3
...@@ -1265,6 +1265,7 @@ CheckPTH() ...@@ -1265,6 +1265,7 @@ CheckPTH()
PTH_LIBS=`$PTH_CONFIG --libs --all` PTH_LIBS=`$PTH_CONFIG --libs --all`
SDL_CFLAGS="$SDL_CFLAGS $PTH_CFLAGS" SDL_CFLAGS="$SDL_CFLAGS $PTH_CFLAGS"
SDL_LIBS="$SDL_LIBS $PTH_LIBS" SDL_LIBS="$SDL_LIBS $PTH_LIBS"
CFLAGS="$CFLAGS -DENABLE_PTH"
use_pth=yes use_pth=yes
fi fi
AC_MSG_CHECKING(pth) AC_MSG_CHECKING(pth)
...@@ -2295,16 +2296,20 @@ case "$target" in ...@@ -2295,16 +2296,20 @@ case "$target" in
if test x$enable_pth = xyes; then 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)
COPY_ARCH_SRC(src/thread, pth, SDL_systhread_c.h) 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 else
COPY_ARCH_SRC(src/thread, generic, SDL_systhread.c) 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_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 fi
COPY_ARCH_SRC(src/thread, generic, SDL_sysmutex.c) COPY_ARCH_SRC(src/thread, generic, SDL_syssem.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.h) 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 fi
# Set up files for the timer library # Set up files for the timer library
if test x$enable_timers = xyes; then if test x$enable_timers = xyes; then
......
...@@ -52,6 +52,12 @@ int SDL_ThreadsInit(void) ...@@ -52,6 +52,12 @@ int SDL_ThreadsInit(void)
{ {
int retval; int retval;
#ifdef ENABLE_PTH
if (!pth_init()) {
return -1;
}
#endif
retval = 0; retval = 0;
/* Set the thread lock creation flag so that we can reuse an /* Set the thread lock creation flag so that we can reuse an
existing lock on the system - since this mutex never gets existing lock on the system - since this mutex never gets
...@@ -80,6 +86,10 @@ void SDL_ThreadsQuit() ...@@ -80,6 +86,10 @@ void SDL_ThreadsQuit()
if ( mutex != NULL ) { if ( mutex != NULL ) {
SDL_DestroyMutex(mutex); SDL_DestroyMutex(mutex);
} }
#ifdef ENABLE_PTH
pth_kill();
#endif
} }
/* Routines for manipulating the thread list */ /* Routines for manipulating the thread list */
......
/*
* 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;
}
#ifndef _SDL_SYSCOND_C_H_
#define _SDL_SYSCOND_C_H_
struct SDL_cond
{
pth_cond_t condpth_p;
};
#endif /* _SDL_SYSCOND_C_H_ */
/*
* 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);
}
#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 = ...@@ -25,7 +25,11 @@ static char rcsid =
"@(#) $Id$"; "@(#) $Id$";
#endif #endif
/* Pth thread management routines for SDL */ /*
* GNU pth threads
*
* Patrice Mandin
*/
#include "SDL_error.h" #include "SDL_error.h"
#include "SDL_thread.h" #include "SDL_thread.h"
...@@ -51,17 +55,16 @@ int SDL_SYS_CreateThread(SDL_Thread *thread, void *args) ...@@ -51,17 +55,16 @@ int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
{ {
pth_attr_t type; pth_attr_t type;
/* Create a new attribute */
type = pth_attr_new(); type = pth_attr_new();
if ( type == NULL ) {
/* Set the thread attributes */
if ( pth_attr_init(type) != 0 ) {
SDL_SetError("Couldn't initialize pth attributes"); SDL_SetError("Couldn't initialize pth attributes");
return(-1); return(-1);
} }
pth_attr_set(type, PTH_ATTR_JOINABLE, TRUE); pth_attr_set(type, PTH_ATTR_JOINABLE, TRUE);
/* Create the thread and go! */ /* 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"); SDL_SetError("Not enough resources to create thread");
return(-1); return(-1);
} }
...@@ -72,6 +75,7 @@ void SDL_SYS_SetupThread(void) ...@@ -72,6 +75,7 @@ void SDL_SYS_SetupThread(void)
{ {
int i; int i;
sigset_t mask; sigset_t mask;
int oldstate;
/* Mask asynchronous signals for this thread */ /* Mask asynchronous signals for this thread */
sigemptyset(&mask); sigemptyset(&mask);
...@@ -81,9 +85,7 @@ void SDL_SYS_SetupThread(void) ...@@ -81,9 +85,7 @@ void SDL_SYS_SetupThread(void)
pth_sigmask(SIG_BLOCK, &mask, 0); pth_sigmask(SIG_BLOCK, &mask, 0);
/* Allow ourselves to be asynchronously cancelled */ /* 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 */ /* WARNING: This may not work for systems with 64-bit pid_t */
......
...@@ -20,6 +20,11 @@ ...@@ -20,6 +20,11 @@
slouken@libsdl.org slouken@libsdl.org
*/ */
#ifndef _SDL_SYSTHREAD_C_H_
#define _SDL_SYSTHREAD_C_H_
#include <pth.h> #include <pth.h>
typedef pth_t SYS_ThreadHandle; typedef pth_t SYS_ThreadHandle;
#endif /* _SDL_SYSTHREAD_C_H_ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment