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()
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,17 +2296,21 @@ 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)
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.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_syssem.c)
COPY_ARCH_SRC(src/thread, generic, SDL_syssem_c.h)
fi
# Set up files for the timer library
if test x$enable_timers = xyes; then
COPY_ARCH_SRC(src/timer, mint, SDL_systimer.c)
......
......@@ -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 */
......
/*
* 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 =
"@(#) $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);
}
}
/* 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_ */
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