Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Patrice's fixes for GNU Pthread support
  • Loading branch information
slouken committed Apr 1, 2002
1 parent f4ec1f9 commit b6b7baa
Show file tree
Hide file tree
Showing 8 changed files with 259 additions and 13 deletions.
15 changes: 10 additions & 5 deletions configure.in
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down
10 changes: 10 additions & 0 deletions src/thread/SDL_thread.c
Expand Up @@ -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
Expand Down Expand Up @@ -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 */
Expand Down
140 changes: 140 additions & 0 deletions src/thread/pth/SDL_syscond.c
@@ -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 changes: 9 additions & 0 deletions src/thread/pth/SDL_syscond_c.h
@@ -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 changes: 67 additions & 0 deletions src/thread/pth/SDL_sysmutex.c
@@ -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 changes: 8 additions & 0 deletions src/thread/pth/SDL_sysmutex_c.h
@@ -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_ */
18 changes: 10 additions & 8 deletions src/thread/pth/SDL_systhread.c
Expand Up @@ -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"
Expand All @@ -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);
}
Expand All @@ -72,6 +75,7 @@ void SDL_SYS_SetupThread(void)
{
int i;
sigset_t mask;
int oldstate;

/* Mask asynchronous signals for this thread */
sigemptyset(&mask);
Expand All @@ -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 */
Expand Down
5 changes: 5 additions & 0 deletions src/thread/pth/SDL_systhread_c.h
Expand Up @@ -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.