Patrice's fixes for GNU Pthread support
--HG-- extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%40330
This commit is contained in:
parent
471f52e3e4
commit
e3affe9e81
8 changed files with 259 additions and 13 deletions
11
configure.in
11
configure.in
|
@ -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 */
|
||||
|
|
140
src/thread/pth/SDL_syscond.c
Normal file
140
src/thread/pth/SDL_syscond.c
Normal file
|
@ -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;
|
||||
}
|
9
src/thread/pth/SDL_syscond_c.h
Normal file
9
src/thread/pth/SDL_syscond_c.h
Normal file
|
@ -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_ */
|
67
src/thread/pth/SDL_sysmutex.c
Normal file
67
src/thread/pth/SDL_sysmutex.c
Normal file
|
@ -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);
|
||||
}
|
8
src/thread/pth/SDL_sysmutex_c.h
Normal file
8
src/thread/pth/SDL_sysmutex_c.h
Normal file
|
@ -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,10 +85,8 @@ 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 */
|
||||
Uint32 SDL_ThreadID(void)
|
||||
|
|
|
@ -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_ */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue