New configure-based build system. Still work in progress, but much improved

--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%401365
This commit is contained in:
Sam Lantinga 2006-02-16 10:11:48 +00:00
parent 1507846225
commit d3805eef09
453 changed files with 3534 additions and 6707 deletions

View file

@ -1,52 +0,0 @@
## Makefile.am for the SDL thread library
noinst_LTLIBRARIES = libthread.la
ARCH_SUBDIRS = $(srcdir)/generic \
$(srcdir)/amigaos \
$(srcdir)/beos \
$(srcdir)/bsdi \
$(srcdir)/dc \
$(srcdir)/epoc \
$(srcdir)/irix \
$(srcdir)/linux \
$(srcdir)/pth \
$(srcdir)/win32
# Older versions of Linux require an asm clone() implementation
if USE_CLONE
THREAD_ASM_SRC = linux/clone.S
else
THREAD_ASM_SRC =
endif
COMMON_SRCS = \
SDL_systhread.h \
SDL_thread.c \
SDL_thread_c.h
ARCH_SRCS = \
SDL_systhread.c \
SDL_systhread_c.h \
SDL_sysmutex.c \
SDL_sysmutex_c.h \
SDL_syssem.c \
SDL_syssem_c.h \
SDL_syscond.c \
SDL_syscond_c.h \
$(THREAD_ASM_SRC)
libthread_la_SOURCES = $(COMMON_SRCS) $(ARCH_SRCS)
## Let automake know that it shouldn't distribute linked sources
BUILT_SOURCES = $(ARCH_SRCS)
## Let automake know that it should remove these for distribution
DISTCLEANFILES = $(ARCH_SRCS)
# The architecture specific directories need to be copied into place
# when building a distribution.
dist-hook:
(cd $(distdir) && rm -f $(BUILT_SOURCES))
cp -rp $(ARCH_SUBDIRS) $(distdir)
(cd $(distdir) && rm -rf `find . -name CVS`)

View file

@ -22,7 +22,10 @@
/* These are functions that need to be implemented by a port of SDL */
#include "SDL_thread_c.h"
#ifndef _SDL_systhread_h
#define _SDL_systhread_h
#include "SDL_thread.h"
/* This function creates a thread, passing args to SDL_RunThread(),
saves a system-dependent thread id in thread->id, and returns 0
@ -45,3 +48,4 @@ extern void SDL_SYS_WaitThread(SDL_Thread *thread);
/* This function kills the thread and returns */
extern void SDL_SYS_KillThread(SDL_Thread *thread);
#endif /* _SDL_systhread_h */

View file

@ -23,8 +23,32 @@
#ifndef _SDL_thread_c_h
#define _SDL_thread_c_h
#include "SDL_error_c.h"
#include "SDL_systhread_c.h"
/* Need the definitions of SYS_ThreadHandle */
#if SDL_THREADS_DISABLED
#include "generic/SDL_systhread_c.h"
#elif SDL_THREAD_AMIGA
#include "amigaos/SDL_systhread_c.h"
#elif SDL_THREAD_BEOS
#include "beos/SDL_systhread_c.h"
#elif SDL_THREAD_DC
#include "dc/SDL_systhread_c.h"
#elif SDL_THREAD_EPOC
#include "epoc/SDL_systhread_c.h"
#elif SDL_THREAD_OS2
#include "os2/SDL_systhread_c.h"
#elif SDL_THREAD_PTH
#include "pth/SDL_systhread_c.h"
#elif SDL_THREAD_PTHREAD
#include "pthread/SDL_systhread_c.h"
#elif SDL_THREAD_SPROC
#include "irix/SDL_systhread_c.h"
#elif SDL_THREAD_WIN32
#include "win32/SDL_systhread_c.h"
#else
#error Need thread implementation for this platform
#include "generic/SDL_systhread_c.h"
#endif
#include "../SDL_error_c.h"
/* This is the system-independent thread info structure */
struct SDL_Thread {
@ -38,7 +62,4 @@ struct SDL_Thread {
/* This is the function called to run a thread */
extern void SDL_RunThread(void *data);
/* Routine to get the thread-specific error variable */
extern SDL_error *SDL_GetErrBuf(void);
#endif /* _SDL_thread_c_h */

View file

@ -29,10 +29,6 @@
struct SDL_semaphore
{
struct SignalSemaphore Sem;
Uint32 count;
Uint32 waiters_count;
SDL_mutex *count_lock;
SDL_cond *count_nonzero;
};
#undef D
@ -98,20 +94,9 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
/* A timeout of 0 is an easy case */
if ( timeout == 0 ) {
return SDL_SemTryWait(sem);
ObtainSemaphore(&sem->Sem);
return 1;
}
/*
SDL_LockMutex(sem->count_lock);
++sem->waiters_count;
retval = 0;
while ( (sem->count == 0) && (retval != SDL_MUTEX_TIMEDOUT) ) {
retval = SDL_CondWaitTimeout(sem->count_nonzero,
sem->count_lock, timeout);
}
--sem->waiters_count;
--sem->count;
SDL_UnlockMutex(sem->count_lock);
*/
if(!(retval=AttemptSemaphore(&sem->Sem)))
{
SDL_Delay(timeout);
@ -131,7 +116,6 @@ int SDL_SemWait(SDL_sem *sem)
{
ObtainSemaphore(&sem->Sem);
return 0;
// return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
}
Uint32 SDL_SemValue(SDL_sem *sem)
@ -145,7 +129,6 @@ Uint32 SDL_SemValue(SDL_sem *sem)
#else
value = sem->Sem.ss_NestCount;
#endif
// SDL_UnlockMutex(sem->count_lock);
}
return value;
}
@ -159,14 +142,6 @@ int SDL_SemPost(SDL_sem *sem)
D(bug("SemPost semaphore...%lx\n",sem));
ReleaseSemaphore(&sem->Sem);
#if 0
SDL_LockMutex(sem->count_lock);
if ( sem->waiters_count > 0 ) {
SDL_CondSignal(sem->count_nonzero);
}
++sem->count;
SDL_UnlockMutex(sem->count_lock);
#endif
return 0;
}

View file

@ -24,8 +24,8 @@
#include "SDL_mutex.h"
#include "SDL_thread.h"
#include "SDL_thread_c.h"
#include "SDL_systhread.h"
#include "../SDL_thread_c.h"
#include "../SDL_systhread.h"
#include "mydebug.h"
typedef struct {

View file

@ -24,8 +24,8 @@
#include "SDL_mutex.h"
#include "SDL_thread.h"
#include "SDL_thread_c.h"
#include "SDL_systhread.h"
#include "../SDL_thread_c.h"
#include "../SDL_systhread.h"
#define ARRAY_CHUNKSIZE 32
/* The array of threads currently active in the application

View file

@ -28,8 +28,8 @@
#include "SDL_mutex.h"
#include "SDL_thread.h"
#include "SDL_thread_c.h"
#include "SDL_systhread.h"
#include "../SDL_thread_c.h"
#include "../SDL_systhread.h"
static int sig_list[] = {

View file

@ -1,498 +0,0 @@
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2006 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_thread.h"
#include "SDL_timer.h"
#ifdef SDL_USE_PTHREADS
#include <unistd.h> /* For getpid() */
#include <pthread.h>
/*
* This is semaphore.h inlined here so that BSD/OS POSIX semaphore are
* completely selfcontained without requiring any additional include files
* or libraries not present in the stock system
*/
/* semaphore.h: POSIX 1003.1b semaphores */
/*-
* Copyright (c) 1996, 1997
* HD Associates, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by HD Associates, Inc
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY HD ASSOCIATES AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL HD ASSOCIATES OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD: src/sys/posix4/semaphore.h,v 1.6 2000/01/20 07:55:42 jasone Exp $
*/
#include <machine/limits.h>
#include <sys/types.h>
#include <fcntl.h>
/* Opaque type definition. */
struct sem;
typedef struct sem *sem_t;
#define SEM_FAILED ((sem_t *)0)
#define SEM_VALUE_MAX UINT_MAX
#include <sys/cdefs.h>
__BEGIN_DECLS
int sem_init __P((sem_t *, int, unsigned int));
int sem_destroy __P((sem_t *));
sem_t *sem_open __P((const char *, int, ...));
int sem_close __P((sem_t *));
int sem_unlink __P((const char *));
int sem_wait __P((sem_t *));
int sem_trywait __P((sem_t *));
int sem_post __P((sem_t *));
int sem_getvalue __P((sem_t *, int *));
__END_DECLS
/* END of inlined semaphore.h */
/* Wrapper around POSIX 1003.1b semaphores */
struct SDL_semaphore {
sem_t *sem;
sem_t sem_data;
};
/* Create a semaphore, initialized with value */
SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
{
SDL_sem *sem = (SDL_sem *) SDL_malloc(sizeof(SDL_sem));
if ( sem ) {
if ( sem_init(&sem->sem_data, 0, initial_value) < 0 ) {
SDL_SetError("sem_init() failed");
SDL_free(sem);
sem = NULL;
} else {
sem->sem = &sem->sem_data;
}
} else {
SDL_OutOfMemory();
}
return sem;
}
void SDL_DestroySemaphore(SDL_sem *sem)
{
if ( sem ) {
sem_destroy(sem->sem);
SDL_free(sem);
}
}
int SDL_SemTryWait(SDL_sem *sem)
{
int retval;
if ( ! sem ) {
SDL_SetError("Passed a NULL semaphore");
return -1;
}
retval = SDL_MUTEX_TIMEDOUT;
if ( sem_trywait(sem->sem) == 0 )
retval = 0;
return retval;
}
int SDL_SemWait(SDL_sem *sem)
{
int retval;
if ( ! sem ) {
SDL_SetError("Passed a NULL semaphore");
return -1;
}
retval = sem_wait(sem->sem);
if ( retval < 0 ) {
SDL_SetError("sem_wait() failed");
}
return retval;
}
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
{
int retval;
if ( ! sem ) {
SDL_SetError("Passed a NULL semaphore");
return -1;
}
/* Try the easy cases first */
if ( timeout == 0 ) {
return SDL_SemTryWait(sem);
}
if ( timeout == SDL_MUTEX_MAXWAIT ) {
return SDL_SemWait(sem);
}
/* Ack! We have to busy wait... */
timeout += SDL_GetTicks();
do {
retval = SDL_SemTryWait(sem);
if ( retval == 0 ) {
break;
}
SDL_Delay(1);
} while ( SDL_GetTicks() < timeout );
return retval;
}
Uint32 SDL_SemValue(SDL_sem *sem)
{
int ret = 0;
if ( sem ) {
sem_getvalue(sem->sem, &ret);
if ( ret < 0 ) {
ret = 0;
}
}
return (Uint32)ret;
}
int SDL_SemPost(SDL_sem *sem)
{
int retval;
if ( ! sem ) {
SDL_SetError("Passed a NULL semaphore");
return -1;
}
retval = sem_post(sem->sem);
if ( retval < 0 ) {
SDL_SetError("sem_post() failed");
}
return retval;
}
/*
* BEGIN inlined uthread_sem.c. This is done here so that no extra libraries
* or include files not present in BSD/OS are required
*/
/*
* Copyright (C) 2000 Jason Evans <jasone@freebsd.org>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice(s), this list of conditions and the following disclaimer as
* the first lines of this file unmodified other than the possible
* addition of one or more copyright notices.
* 2. Redistributions in binary form must reproduce the above copyright
* notice(s), this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD: src/lib/libc_r/uthread/uthread_sem.c,v 1.3.2.1 2000/07/18 02:05:57 jasone Exp $
*/
#include <errno.h>
#include <pthread.h>
/* Begin thread_private.h kluge */
/*
* These come out of (or should go into) thread_private.h - rather than have
* to copy (or symlink) the files from the source tree these definitions are
* inlined here. Obviously these go away when this module is part of libc.
*/
struct sem {
#define SEM_MAGIC ((u_int32_t) 0x09fa4012)
u_int32_t magic;
pthread_mutex_t lock;
pthread_cond_t gtzero;
u_int32_t count;
u_int32_t nwaiters;
};
extern pthread_once_t _thread_init_once;
extern int _threads_initialized;
extern void _thread_init __P((void));
#define THREAD_INIT() \
(void) pthread_once(&_thread_init_once, _thread_init)
#define THREAD_SAFE() \
(_threads_initialized != 0)
#define _SEM_CHECK_VALIDITY(sem) \
if ((*(sem))->magic != SEM_MAGIC) { \
errno = EINVAL; \
retval = -1; \
goto RETURN; \
}
/* End thread_private.h kluge */
int
sem_init(sem_t *sem, int pshared, unsigned int value)
{
int retval;
if (!THREAD_SAFE())
THREAD_INIT();
/*
* Range check the arguments.
*/
if (pshared != 0) {
/*
* The user wants a semaphore that can be shared among
* processes, which this implementation can't do. Sounds like a
* permissions problem to me (yeah right).
*/
errno = EPERM;
retval = -1;
goto RETURN;
}
if (value > SEM_VALUE_MAX) {
errno = EINVAL;
retval = -1;
goto RETURN;
}
*sem = (sem_t)SDL_malloc(sizeof(struct sem));
if (*sem == NULL) {
errno = ENOSPC;
retval = -1;
goto RETURN;
}
/*
* Initialize the semaphore.
*/
if (pthread_mutex_init(&(*sem)->lock, NULL) != 0) {
SDL_free(*sem);
errno = ENOSPC;
retval = -1;
goto RETURN;
}
if (pthread_cond_init(&(*sem)->gtzero, NULL) != 0) {
pthread_mutex_destroy(&(*sem)->lock);
SDL_free(*sem);
errno = ENOSPC;
retval = -1;
goto RETURN;
}
(*sem)->count = (u_int32_t)value;
(*sem)->nwaiters = 0;
(*sem)->magic = SEM_MAGIC;
retval = 0;
RETURN:
return retval;
}
int
sem_destroy(sem_t *sem)
{
int retval;
_SEM_CHECK_VALIDITY(sem);
/* Make sure there are no waiters. */
pthread_mutex_lock(&(*sem)->lock);
if ((*sem)->nwaiters > 0) {
pthread_mutex_unlock(&(*sem)->lock);
errno = EBUSY;
retval = -1;
goto RETURN;
}
pthread_mutex_unlock(&(*sem)->lock);
pthread_mutex_destroy(&(*sem)->lock);
pthread_cond_destroy(&(*sem)->gtzero);
(*sem)->magic = 0;
SDL_free(*sem);
retval = 0;
RETURN:
return retval;
}
sem_t *
sem_open(const char *name, int oflag, ...)
{
errno = ENOSYS;
return SEM_FAILED;
}
int
sem_close(sem_t *sem)
{
errno = ENOSYS;
return -1;
}
int
sem_unlink(const char *name)
{
errno = ENOSYS;
return -1;
}
int
sem_wait(sem_t *sem)
{
int retval;
pthread_testcancel();
_SEM_CHECK_VALIDITY(sem);
pthread_mutex_lock(&(*sem)->lock);
while ((*sem)->count == 0) {
(*sem)->nwaiters++;
pthread_cond_wait(&(*sem)->gtzero, &(*sem)->lock);
(*sem)->nwaiters--;
}
(*sem)->count--;
pthread_mutex_unlock(&(*sem)->lock);
retval = 0;
RETURN:
pthread_testcancel();
return retval;
}
int
sem_trywait(sem_t *sem)
{
int retval;
_SEM_CHECK_VALIDITY(sem);
pthread_mutex_lock(&(*sem)->lock);
if ((*sem)->count > 0) {
(*sem)->count--;
retval = 0;
} else {
errno = EAGAIN;
retval = -1;
}
pthread_mutex_unlock(&(*sem)->lock);
RETURN:
return retval;
}
int
sem_post(sem_t *sem)
{
int retval;
_SEM_CHECK_VALIDITY(sem);
pthread_mutex_lock(&(*sem)->lock);
(*sem)->count++;
if ((*sem)->nwaiters > 0) {
/*
* We must use pthread_cond_broadcast() rather than
* pthread_cond_signal() in order to assure that the highest
* priority thread is run by the scheduler, since
* pthread_cond_signal() signals waiting threads in FIFO order.
*/
pthread_cond_broadcast(&(*sem)->gtzero);
}
pthread_mutex_unlock(&(*sem)->lock);
retval = 0;
RETURN:
return retval;
}
int
sem_getvalue(sem_t *sem, int *sval)
{
int retval;
_SEM_CHECK_VALIDITY(sem);
pthread_mutex_lock(&(*sem)->lock);
*sval = (int)(*sem)->count;
pthread_mutex_unlock(&(*sem)->lock);
retval = 0;
RETURN:
return retval;
}
/* END of inlined uthread_sem.c */
#endif /* SDL_USE_PTHREADS */

View file

@ -61,8 +61,8 @@ void SDL_DestroyMutex(SDL_mutex *mutex)
/* Lock the semaphore */
int SDL_mutexP(SDL_mutex *mutex)
{
#ifdef DISABLE_THREADS
return 0;
#if SDL_THREADS_DISABLED
return SDL_arraysize(return ),0;
#else
Uint32 this_thread;
@ -85,13 +85,13 @@ int SDL_mutexP(SDL_mutex *mutex)
}
return 0;
#endif /* DISABLE_THREADS */
#endif /* SDL_THREADS_DISABLED */
}
/* Unlock the mutex */
int SDL_mutexV(SDL_mutex *mutex)
{
#ifdef DISABLE_THREADS
#if SDL_THREADS_DISABLED
return 0;
#else
if ( mutex == NULL ) {
@ -117,5 +117,5 @@ int SDL_mutexV(SDL_mutex *mutex)
spinlock_unlock(&mutex->mutex);
}
return 0;
#endif /* DISABLE_THREADS */
#endif /* SDL_THREADS_DISABLED */
}

View file

@ -27,7 +27,7 @@
#include "SDL_systhread_c.h"
#ifdef DISABLE_THREADS
#if SDL_THREADS_DISABLED
SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
{
@ -164,4 +164,4 @@ int SDL_SemPost(SDL_sem *sem)
return 0;
}
#endif /* DISABLE_THREADS */
#endif /* SDL_THREADS_DISABLED */

View file

@ -23,11 +23,11 @@
/* Thread management routines for SDL */
#include "SDL_thread.h"
#include "SDL_systhread.h"
#include "../SDL_systhread.h"
#include <kos/thread.h>
#ifdef DISABLE_THREADS
#if SDL_THREADS_DISABLED
int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
{
SDL_SetError("Threads are not supported on this platform");

View file

@ -20,10 +20,4 @@
slouken@libsdl.org
*/
/* Stub until we implement threads on this platform */
typedef struct kthread* SYS_ThreadHandle;
/*
#ifndef DISABLE_THREADS
#define DISABLE_THREADS
#endif
*/

View file

@ -32,7 +32,7 @@ extern "C" {
#undef NULL
#include "SDL_error.h"
#include "SDL_thread.h"
#include "SDL_systhread.h"
#include "../SDL_systhread.h"
};
#include <e32std.h>

View file

@ -1,22 +0,0 @@
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2006 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/

View file

@ -68,7 +68,7 @@ void SDL_DestroyMutex(SDL_mutex *mutex)
/* Lock the semaphore */
int SDL_mutexP(SDL_mutex *mutex)
{
#ifdef DISABLE_THREADS
#if SDL_THREADS_DISABLED
return 0;
#else
Uint32 this_thread;
@ -92,13 +92,13 @@ int SDL_mutexP(SDL_mutex *mutex)
}
return 0;
#endif /* DISABLE_THREADS */
#endif /* SDL_THREADS_DISABLED */
}
/* Unlock the mutex */
int SDL_mutexV(SDL_mutex *mutex)
{
#ifdef DISABLE_THREADS
#if SDL_THREADS_DISABLED
return 0;
#else
if ( mutex == NULL ) {
@ -124,5 +124,5 @@ int SDL_mutexV(SDL_mutex *mutex)
SDL_SemPost(mutex->sem);
}
return 0;
#endif /* DISABLE_THREADS */
#endif /* SDL_THREADS_DISABLED */
}

View file

@ -27,7 +27,7 @@
#include "SDL_systhread_c.h"
#ifdef DISABLE_THREADS
#if SDL_THREADS_DISABLED
SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
{
@ -203,4 +203,4 @@ int SDL_SemPost(SDL_sem *sem)
return 0;
}
#endif /* DISABLE_THREADS */
#endif /* SDL_THREADS_DISABLED */

View file

@ -1,22 +0,0 @@
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2006 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/

View file

@ -23,7 +23,7 @@
/* Thread management routines for SDL */
#include "SDL_thread.h"
#include "SDL_systhread.h"
#include "../SDL_systhread.h"
int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
{

View file

@ -22,7 +22,3 @@
/* Stub until we implement threads on this platform */
typedef int SYS_ThreadHandle;
#ifndef DISABLE_THREADS
#define DISABLE_THREADS
#endif

View file

@ -23,180 +23,6 @@
#include "SDL_thread.h"
#include "SDL_timer.h"
#ifdef linux
/* Look to see if glibc is available, and if so, what version */
#include <features.h>
#if (__GLIBC__ == 2) && (__GLIBC_MINOR__ == 0)
#warning Working around a bug in glibc 2.0 pthreads
#undef SDL_USE_PTHREADS
/* The bug is actually a problem where threads are suspended, but don't
wake up when the thread manager sends them a signal. This is a problem
with thread creation too, but it happens less often. :-/
We avoid this by using System V IPC for semaphores.
*/
#endif /* glibc 2.0 */
#endif /* linux */
#ifdef SDL_USE_PTHREADS
#ifdef SDL_NO_PTHREAD_SEMAPHORES
#include "generic/SDL_syssem.c"
#else
#include <pthread.h>
#include <semaphore.h>
/* Wrapper around POSIX 1003.1b semaphores */
#ifdef MACOSX
#define USE_NAMED_SEMAPHORES
#endif /* MACOSX */
struct SDL_semaphore {
sem_t *sem;
#ifndef USE_NAMED_SEMAPHORES
sem_t sem_data;
#endif
};
/* Create a semaphore, initialized with value */
SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
{
SDL_sem *sem = (SDL_sem *) SDL_malloc(sizeof(SDL_sem));
if ( sem ) {
#ifdef USE_NAMED_SEMAPHORES
static int semnum = 0;
char name[32];
SDL_snprintf(name, SDL_arraysize(name), "/SDL_sem-%d-%4.4d", getpid(), semnum++);
sem->sem = sem_open(name, O_CREAT, 0600, initial_value);
if ( sem->sem == (sem_t *)SEM_FAILED ) {
SDL_SetError("sem_open(%s) failed", name);
SDL_free(sem);
sem = NULL;
} else {
sem_unlink(name);
}
#else
if ( sem_init(&sem->sem_data, 0, initial_value) < 0 ) {
SDL_SetError("sem_init() failed");
SDL_free(sem);
sem = NULL;
} else {
sem->sem = &sem->sem_data;
}
#endif /* USE_NAMED_SEMAPHORES */
} else {
SDL_OutOfMemory();
}
return sem;
}
void SDL_DestroySemaphore(SDL_sem *sem)
{
if ( sem ) {
#ifdef USE_NAMED_SEMAPHORES
sem_close(sem->sem);
#else
sem_destroy(sem->sem);
#endif
SDL_free(sem);
}
}
int SDL_SemTryWait(SDL_sem *sem)
{
int retval;
if ( ! sem ) {
SDL_SetError("Passed a NULL semaphore");
return -1;
}
retval = SDL_MUTEX_TIMEDOUT;
if ( sem_trywait(sem->sem) == 0 ) {
retval = 0;
}
return retval;
}
int SDL_SemWait(SDL_sem *sem)
{
int retval;
if ( ! sem ) {
SDL_SetError("Passed a NULL semaphore");
return -1;
}
retval = sem_wait(sem->sem);
if ( retval < 0 ) {
SDL_SetError("sem_wait() failed");
}
return retval;
}
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
{
int retval;
if ( ! sem ) {
SDL_SetError("Passed a NULL semaphore");
return -1;
}
/* Try the easy cases first */
if ( timeout == 0 ) {
return SDL_SemTryWait(sem);
}
if ( timeout == SDL_MUTEX_MAXWAIT ) {
return SDL_SemWait(sem);
}
/* Ack! We have to busy wait... */
timeout += SDL_GetTicks();
do {
retval = SDL_SemTryWait(sem);
if ( retval == 0 ) {
break;
}
SDL_Delay(1);
} while ( SDL_GetTicks() < timeout );
return retval;
}
Uint32 SDL_SemValue(SDL_sem *sem)
{
int ret = 0;
if ( sem ) {
sem_getvalue(sem->sem, &ret);
if ( ret < 0 ) {
ret = 0;
}
}
return (Uint32)ret;
}
int SDL_SemPost(SDL_sem *sem)
{
int retval;
if ( ! sem ) {
SDL_SetError("Passed a NULL semaphore");
return -1;
}
retval = sem_post(sem->sem);
if ( retval < 0 ) {
SDL_SetError("sem_post() failed");
}
return retval;
}
#endif /* NO_PTHREAD_SEMAPHORES */
#else /* System V IPC implementation */
#include <stdio.h>
#include <stdlib.h>
@ -214,6 +40,7 @@ struct SDL_semaphore {
};
/* Not defined by many operating systems, use configure to detect */
/*
#if !defined(HAVE_SEMUN)
union semun {
int val;
@ -221,6 +48,7 @@ union semun {
ushort *array;
};
#endif
*/
static struct sembuf op_trywait[2] = {
{ 0, -1, (IPC_NOWAIT|SEM_UNDO) } /* Decrement semaphore, no block */
@ -405,5 +233,3 @@ int SDL_SemPost(SDL_sem *sem)
}
return retval;
}
#endif /* SDL_USE_PTHREADS */

View file

@ -29,7 +29,7 @@
#include <sys/prctl.h>
#include "SDL_thread.h"
#include "SDL_systhread.h"
#include "../SDL_systhread.h"
static int sig_list[] = {

View file

@ -1,244 +0,0 @@
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2006 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
/* Linux thread management routines for SDL */
#include "SDL_thread.h"
#include "SDL_systhread.h"
#ifdef FORK_HACK
#include <unistd.h>
int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
{
SDL_SetError("Threads are not supported on this platform");
return(-1);
}
void SDL_SYS_SetupThread(void)
{
return;
}
Uint32 SDL_ThreadID(void)
{
return((Uint32)getpid());
}
void SDL_SYS_WaitThread(SDL_Thread *thread)
{
return;
}
void SDL_SYS_KillThread(SDL_Thread *thread)
{
return;
}
#else
#include <signal.h>
/* List of signals to mask in the subthreads */
static int sig_list[] = {
SIGHUP, SIGINT, SIGQUIT, SIGPIPE, SIGALRM, SIGTERM, SIGCHLD, SIGWINCH,
SIGVTALRM, SIGPROF, 0
};
#ifdef SDL_USE_PTHREADS
#include <pthread.h>
static void *RunThread(void *data)
{
SDL_RunThread(data);
pthread_exit((void*)0);
return((void *)0); /* Prevent compiler warning */
}
int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
{
pthread_attr_t type;
/* Set the thread attributes */
if ( pthread_attr_init(&type) != 0 ) {
SDL_SetError("Couldn't initialize pthread attributes");
return(-1);
}
pthread_attr_setdetachstate(&type, PTHREAD_CREATE_JOINABLE);
/* Create the thread and go! */
if ( pthread_create(&thread->handle, &type, RunThread, args) != 0 ) {
SDL_SetError("Not enough resources to create thread");
return(-1);
}
return(0);
}
void SDL_SYS_SetupThread(void)
{
int i;
sigset_t mask;
/* Mask asynchronous signals for this thread */
sigemptyset(&mask);
for ( i=0; sig_list[i]; ++i ) {
sigaddset(&mask, sig_list[i]);
}
pthread_sigmask(SIG_BLOCK, &mask, 0);
#ifdef PTHREAD_CANCEL_ASYNCHRONOUS
/* Allow ourselves to be asynchronously cancelled */
{ int oldstate;
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate);
}
#endif
}
/* WARNING: This may not work for systems with 64-bit pid_t */
Uint32 SDL_ThreadID(void)
{
return((Uint32)pthread_self());
}
void SDL_SYS_WaitThread(SDL_Thread *thread)
{
pthread_join(thread->handle, 0);
}
void SDL_SYS_KillThread(SDL_Thread *thread)
{
#ifdef PTHREAD_CANCEL_ASYNCHRONOUS
pthread_cancel(thread->handle);
#else
#ifdef __FreeBSD__
#warning For some reason, this doesnt actually kill a thread - FreeBSD 3.2
#endif
pthread_kill(thread->handle, SIGKILL);
#endif
}
#else /* Linux-specific clone() based implementation */
#include <errno.h>
#include <unistd.h>
#include <sys/wait.h>
/* Stack size for child thread */
#define STACKSIZE 16384*4 /* 16384 is too small */
#ifdef __GLIBC__
#include <sched.h>
#else
/* From <linux/sched.h> */
#define CLONE_VM 0x00000100 /* set if VM shared */
#define CLONE_FS 0x00000200 /* set if fs info shared */
#define CLONE_FILES 0x00000400 /* set if open files shared */
#define CLONE_SIGHAND 0x00000800 /* set if signal handlers shared */
#define CLONE_PID 0x00001000 /* set if pid shared */
/* The infamous "start_thread" function, courtesy Linus Torvalds */
extern int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg);
#endif
static int RunThread(void *data)
{
SDL_RunThread(data);
return(0);
}
int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
{
void *stack;
/* Allocate memory for thread stack */
stack = SDL_malloc(STACKSIZE);
if ( stack == (void *)0 ) {
SDL_OutOfMemory();
return(-1);
}
thread->data = stack;
/* Adjust the stack since it actually grows down */
stack = (void *) ((char *)stack + STACKSIZE);
/* Create the thread and go! */
thread->handle = clone(RunThread, stack,
(CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND), args);
if ( thread->handle < 0 ) {
SDL_free(thread->data);
SDL_SetError("Not enough resources to create thread");
return(-1);
}
return(0);
}
void SDL_SYS_SetupThread(void)
{
int i;
sigset_t mask;
/* Mask asynchronous signals for this thread */
sigemptyset(&mask);
for ( i=0; sig_list[i]; ++i ) {
sigaddset(&mask, sig_list[i]);
}
sigprocmask(SIG_BLOCK, &mask, 0);
}
/* WARNING: This may not work for systems with 64-bit pid_t */
Uint32 SDL_ThreadID(void)
{
return((Uint32)getpid());
}
void SDL_SYS_WaitThread(SDL_Thread *thread)
{
#ifdef __WCLONE
errno = 0;
while ( errno != ECHILD ) {
waitpid(thread->handle, 0, __WCLONE);
}
#else
/* Ack, ugly ugly hack --
wait() doesn't work, waitpid() doesn't work, and ignoring SIG_CHLD
doesn't work .. and the child thread is still a zombie, so kill()
doesn't work.
*/
char command[1024];
SDL_snprintf(command, SDL_arraysize(command),
"ps ax|fgrep -v fgrep|fgrep -v '<zombie>'|fgrep %d >/dev/null",
thread->handle);
while ( system(command) == 0 )
sleep(1);
#endif
SDL_free(thread->data);
}
void SDL_SYS_KillThread(SDL_Thread *thread)
{
kill(thread->handle, SIGKILL);
}
#endif /* SDL_USE_PTHREADS */
#endif /* FORK_HACK */

View file

@ -1,181 +0,0 @@
/* Taken with thanks from LinuxThreads 0.6 */
/* This is no longer necessary with glibc-2.1, which has its own clone() */
#ifdef linux
/* Look to see if glibc is available, and if so, what version */
#include <features.h>
#if (__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 1))
#define HAVE_CLONE
#endif /* glibc 2.1 or newer */
#endif /* linux */
#if defined(linux) && !defined(SDL_USE_PTHREADS) && !defined(HAVE_CLONE)
#if defined(__i386__)
/************************************************************************/
/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
Contributed by Richard Henderson (rth@tamu.edu)
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
/* clone() is even more special than fork() as it mucks with stacks
and invokes a function in the right context after its all over. */
#include <asm/errno.h>
#include <asm/unistd.h>
/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg); */
.text
.align 4
.globl __clone
.type __clone,@function
.weak clone
clone = __clone
__clone:
/* Sanity check arguments. */
movl $-EINVAL,%eax
movl 4(%esp),%ecx /* no NULL function pointers */
testl %ecx,%ecx
jz syscall_error
movl 8(%esp),%ecx /* no NULL stack pointers */
testl %ecx,%ecx
jz syscall_error
/* Insert the argument onto the new stack. */
subl $8,%ecx
movl 16(%esp),%eax
movl %eax,4(%ecx)
/* Save the function pointer as the zeroth argument. */
/* It will be popped off in the child in the ebx frobbing below. */
movl 4(%esp),%eax
movl %eax,0(%ecx)
/* Do the system call */
pushl %ebx
movl 16(%esp),%ebx
movl $__NR_clone,%eax
int $0x80
popl %ebx
test %eax,%eax
jl syscall_error
jz thread_start
ret
syscall_error:
negl %eax
pushl %eax
#ifdef __PIC__
call __errno_location@PLT
#else
call __errno_location
#endif
popl 0(%eax)
movl $-1, %eax
ret
thread_start:
subl %ebp,%ebp /* terminate the stack frame */
call *%ebx
pushl %eax
#ifdef __PIC__
call _exit@PLT
#else
call _exit
#endif
/************************************************************************/
#elif defined(sparc)
/************************************************************************/
/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
Contributed by Miguel de Icaza (miguel@nuclecu.unam.mx)
Based on code written for the Intel by Richard
Henderson (rth@tamu.edu)
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
/* clone() is even more special than fork() as it mucks with stacks
and invokes a function in the right context after its all over. */
#include <asm/errno.h>
#include <asm/unistd.h>
/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg); */
.text
.align 4
.globl __clone
.type __clone,@function
.weak clone
clone = __clone
__clone:
save %sp,-96,%sp
/* sanity check arguments */
tst %i0
be __clone_syscall_error
tst %i1
be __clone_syscall_error
nop
/* Do the system call */
mov %i1,%o1
mov %i2,%o0
set __NR_clone,%g1
ta 0x10
bcs __clone_syscall_error
tst %o1
bne __thread_start
nop
mov %o0,%i0
ret
restore
__clone_syscall_error:
call __errno_location
set EINVAL,%i0
st %i0,[%o0]
mov -1,%i0
ret
restore
__thread_start:
call %i0
mov %i3,%o0
call _exit,0
nop
/************************************************************************/
#else
#error "Unknown Linux architecture"
#endif
#endif /* Linux && ! SDL_USE_PTHREADS */

View file

@ -28,7 +28,7 @@
#include <os2.h>
#include "SDL_thread.h"
#include "SDL_systhread.h"
#include "../SDL_systhread.h"
typedef struct ThreadStartParms
{

View file

@ -7,9 +7,13 @@
#include <pth.h>
#include "SDL_thread.h"
#include "SDL_syscond_c.h"
#include "SDL_sysmutex_c.h"
struct SDL_cond
{
pth_cond_t condpth_p;
};
/* Create a condition variable */
SDL_cond * SDL_CreateCond(void)
{

View file

@ -1,9 +0,0 @@
#ifndef _SDL_SYSCOND_C_H_
#define _SDL_SYSCOND_C_H_
struct SDL_cond
{
pth_cond_t condpth_p;
};
#endif /* _SDL_SYSCOND_C_H_ */

View file

@ -27,10 +27,10 @@
*/
#include "SDL_thread.h"
#include "SDL_systhread.h"
#include "../SDL_systhread.h"
#include <signal.h>
#include <pth.h>
#include <signal.h>
/* List of signals to mask in the subthreads */
static int sig_list[] = {
@ -91,7 +91,7 @@ Uint32 SDL_ThreadID(void)
void SDL_SYS_WaitThread(SDL_Thread *thread)
{
pth_join(thread->handle, 0);
pth_join(thread->handle, NULL);
}
void SDL_SYS_KillThread(SDL_Thread *thread)

View file

@ -20,23 +20,6 @@
slouken@libsdl.org
*/
#ifdef linux
/* Look to see if glibc is available, and if so, what version */
#include <features.h>
#if (__GLIBC__ == 2) && (__GLIBC_MINOR__ == 0)
#warning Working around a bug in glibc 2.0 pthreads
#undef SDL_USE_PTHREADS
/* The bug is actually a problem where threads are suspended, but don't
wake up when the thread manager sends them a signal. This is a problem
with thread creation too, but it happens less often. :-/
We avoid this by using System V IPC for mutexes.
*/
#endif /* glibc 2.0 */
#endif /* linux */
#ifdef SDL_USE_PTHREADS
#include <sys/time.h>
#include <unistd.h>
#include <errno.h>
@ -45,11 +28,6 @@
#include "SDL_thread.h"
#include "SDL_sysmutex_c.h"
#if defined(PTHREAD_NO_RECURSIVE_MUTEX) && !defined(__bsdi__)
#error You need to use the generic condition variable implementation
#endif
struct SDL_cond
{
pthread_cond_t cond;
@ -174,9 +152,3 @@ int SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex)
}
return retval;
}
#else /* Use semaphore implementation */
#include "generic/SDL_syscond.c"
#endif /* SDL_USE_PTHREADS */

View file

@ -20,31 +20,18 @@
slouken@libsdl.org
*/
#ifdef linux
/* Look to see if glibc is available, and if so, what version */
#include <features.h>
#if (__GLIBC__ == 2) && (__GLIBC_MINOR__ == 0)
#warning Working around a bug in glibc 2.0 pthreads
#undef SDL_USE_PTHREADS
/* The bug is actually a problem where threads are suspended, but don't
wake up when the thread manager sends them a signal. This is a problem
with thread creation too, but it happens less often. :-/
We avoid this by using System V IPC for mutexes.
*/
#endif /* glibc 2.0 */
#endif /* linux */
#ifdef SDL_USE_PTHREADS
#include <pthread.h>
#include "SDL_thread.h"
#if !SDL_THREAD_PTHREAD_RECURSIVE_MUTEX && \
!SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP
#define FAKE_RECURSIVE_MUTEX
#endif
struct SDL_mutex {
pthread_mutex_t id;
#ifdef PTHREAD_NO_RECURSIVE_MUTEX
#if FAKE_RECURSIVE_MUTEX
int recursive;
pthread_t owner;
#endif
@ -59,13 +46,13 @@ SDL_mutex *SDL_CreateMutex (void)
mutex = (SDL_mutex *)SDL_calloc(1, sizeof(*mutex));
if ( mutex ) {
pthread_mutexattr_init(&attr);
#if defined(PTHREAD_RECURSIVE_MUTEX)
#if SDL_THREAD_PTHREAD_RECURSIVE_MUTEX
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
#elif defined(PTHREAD_RECURSIVE_MUTEX_NP)
#elif SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP
pthread_mutexattr_setkind_np(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
#else
/* No extra attributes necessary */
#endif /* PTHREAD_RECURSIVE_MUTEX */
#endif
if ( pthread_mutex_init(&mutex->id, &attr) != 0 ) {
SDL_SetError("pthread_mutex_init() failed");
SDL_free(mutex);
@ -89,7 +76,7 @@ void SDL_DestroyMutex(SDL_mutex *mutex)
int SDL_mutexP(SDL_mutex *mutex)
{
int retval;
#ifdef PTHREAD_NO_RECURSIVE_MUTEX
#if FAKE_RECURSIVE_MUTEX
pthread_t this_thread;
#endif
@ -99,7 +86,7 @@ int SDL_mutexP(SDL_mutex *mutex)
}
retval = 0;
#ifdef PTHREAD_NO_RECURSIVE_MUTEX
#if FAKE_RECURSIVE_MUTEX
this_thread = pthread_self();
if ( mutex->owner == this_thread ) {
++mutex->recursive;
@ -135,7 +122,7 @@ int SDL_mutexV(SDL_mutex *mutex)
}
retval = 0;
#ifdef PTHREAD_NO_RECURSIVE_MUTEX
#if FAKE_RECURSIVE_MUTEX
/* We can only unlock the mutex if we own it */
if ( pthread_self() == mutex->owner ) {
if ( mutex->recursive ) {
@ -159,13 +146,7 @@ int SDL_mutexV(SDL_mutex *mutex)
SDL_SetError("pthread_mutex_unlock() failed");
retval = -1;
}
#endif /* PTHREAD_NO_RECURSIVE_MUTEX */
#endif /* FAKE_RECURSIVE_MUTEX */
return retval;
}
#else /* Use semaphore implementation */
#include "generic/SDL_sysmutex.c"
#endif /* SDL_USE_PTHREADS */

View file

@ -23,16 +23,8 @@
#ifndef _SDL_mutex_c_h
#define _SDL_mutex_c_h
#ifdef SDL_USE_PTHREADS
/* Recursive mutexes aren't widespread among pthread implementations yet */
#if 0
#define PTHREAD_NO_RECURSIVE_MUTEX
#endif
struct SDL_mutex {
pthread_mutex_t id;
};
#endif /* SDL_USE_PTHREADS */
#endif /* _SDL_mutex_c_h */

View file

@ -0,0 +1,174 @@
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2006 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
#include <pthread.h>
#include <semaphore.h>
#include "SDL_thread.h"
#include "SDL_timer.h"
/* Wrapper around POSIX 1003.1b semaphores */
#if MACOSX
#define USE_NAMED_SEMAPHORES 1
#endif /* MACOSX */
struct SDL_semaphore {
sem_t *sem;
#if !USE_NAMED_SEMAPHORES
sem_t sem_data;
#endif
};
/* Create a semaphore, initialized with value */
SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
{
SDL_sem *sem = (SDL_sem *) SDL_malloc(sizeof(SDL_sem));
if ( sem ) {
#if USE_NAMED_SEMAPHORES
static int semnum = 0;
char name[32];
SDL_snprintf(name, SDL_arraysize(name), "/SDL_sem-%d-%4.4d", getpid(), semnum++);
sem->sem = sem_open(name, O_CREAT, 0600, initial_value);
if ( sem->sem == (sem_t *)SEM_FAILED ) {
SDL_SetError("sem_open(%s) failed", name);
SDL_free(sem);
sem = NULL;
} else {
sem_unlink(name);
}
#else
if ( sem_init(&sem->sem_data, 0, initial_value) < 0 ) {
SDL_SetError("sem_init() failed");
SDL_free(sem);
sem = NULL;
} else {
sem->sem = &sem->sem_data;
}
#endif /* USE_NAMED_SEMAPHORES */
} else {
SDL_OutOfMemory();
}
return sem;
}
void SDL_DestroySemaphore(SDL_sem *sem)
{
if ( sem ) {
#if USE_NAMED_SEMAPHORES
sem_close(sem->sem);
#else
sem_destroy(sem->sem);
#endif
SDL_free(sem);
}
}
int SDL_SemTryWait(SDL_sem *sem)
{
int retval;
if ( ! sem ) {
SDL_SetError("Passed a NULL semaphore");
return -1;
}
retval = SDL_MUTEX_TIMEDOUT;
if ( sem_trywait(sem->sem) == 0 ) {
retval = 0;
}
return retval;
}
int SDL_SemWait(SDL_sem *sem)
{
int retval;
if ( ! sem ) {
SDL_SetError("Passed a NULL semaphore");
return -1;
}
retval = sem_wait(sem->sem);
if ( retval < 0 ) {
SDL_SetError("sem_wait() failed");
}
return retval;
}
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
{
int retval;
if ( ! sem ) {
SDL_SetError("Passed a NULL semaphore");
return -1;
}
/* Try the easy cases first */
if ( timeout == 0 ) {
return SDL_SemTryWait(sem);
}
if ( timeout == SDL_MUTEX_MAXWAIT ) {
return SDL_SemWait(sem);
}
/* Ack! We have to busy wait... */
timeout += SDL_GetTicks();
do {
retval = SDL_SemTryWait(sem);
if ( retval == 0 ) {
break;
}
SDL_Delay(1);
} while ( SDL_GetTicks() < timeout );
return retval;
}
Uint32 SDL_SemValue(SDL_sem *sem)
{
int ret = 0;
if ( sem ) {
sem_getvalue(sem->sem, &ret);
if ( ret < 0 ) {
ret = 0;
}
}
return (Uint32)ret;
}
int SDL_SemPost(SDL_sem *sem)
{
int retval;
if ( ! sem ) {
SDL_SetError("Passed a NULL semaphore");
return -1;
}
retval = sem_post(sem->sem);
if ( retval < 0 ) {
SDL_SetError("sem_post() failed");
}
return retval;
}

View file

@ -0,0 +1,104 @@
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2006 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
#include <pthread.h>
#include <signal.h>
#include "SDL_thread.h"
#include "../SDL_thread_c.h"
#include "../SDL_systhread.h"
/* List of signals to mask in the subthreads */
static int sig_list[] = {
SIGHUP, SIGINT, SIGQUIT, SIGPIPE, SIGALRM, SIGTERM, SIGCHLD, SIGWINCH,
SIGVTALRM, SIGPROF, 0
};
static void *RunThread(void *data)
{
SDL_RunThread(data);
pthread_exit((void*)0);
return((void *)0); /* Prevent compiler warning */
}
int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
{
pthread_attr_t type;
/* Set the thread attributes */
if ( pthread_attr_init(&type) != 0 ) {
SDL_SetError("Couldn't initialize pthread attributes");
return(-1);
}
pthread_attr_setdetachstate(&type, PTHREAD_CREATE_JOINABLE);
/* Create the thread and go! */
if ( pthread_create(&thread->handle, &type, RunThread, args) != 0 ) {
SDL_SetError("Not enough resources to create thread");
return(-1);
}
return(0);
}
void SDL_SYS_SetupThread(void)
{
int i;
sigset_t mask;
/* Mask asynchronous signals for this thread */
sigemptyset(&mask);
for ( i=0; sig_list[i]; ++i ) {
sigaddset(&mask, sig_list[i]);
}
pthread_sigmask(SIG_BLOCK, &mask, 0);
#ifdef PTHREAD_CANCEL_ASYNCHRONOUS
/* Allow ourselves to be asynchronously cancelled */
{ int oldstate;
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate);
}
#endif
}
/* WARNING: This may not work for systems with 64-bit pid_t */
Uint32 SDL_ThreadID(void)
{
return((Uint32)pthread_self());
}
void SDL_SYS_WaitThread(SDL_Thread *thread)
{
pthread_join(thread->handle, 0);
}
void SDL_SYS_KillThread(SDL_Thread *thread)
{
#ifdef PTHREAD_CANCEL_ASYNCHRONOUS
pthread_cancel(thread->handle);
#else
#ifdef __FreeBSD__
#warning For some reason, this doesnt actually kill a thread - FreeBSD 3.2
#endif
pthread_kill(thread->handle, SIGKILL);
#endif
}

View file

@ -20,16 +20,6 @@
slouken@libsdl.org
*/
#ifdef SDL_USE_PTHREADS
#include <pthread.h>
typedef pthread_t SYS_ThreadHandle;
#else
#include <sys/types.h>
typedef pid_t SYS_ThreadHandle;
#endif /* SDL_USE_PTHREADS */

View file

@ -22,7 +22,7 @@
/* RISC OS implementations uses pthreads based on linux code */
#ifdef DISABLE_THREADS
#if SDL_THREADS_DISABLED
#include "../generic/SDL_syscond.c"
#else
#include <sys/time.h>

View file

@ -22,17 +22,17 @@
/* RISC OS implementations uses pthreads based on linux code */
#ifdef DISABLE_THREADS
#include "SDL_thread.h"
#if SDL_THREADS_DISABLED
#include "../generic/SDL_sysmutex.c"
#else
#include <pthread.h>
#include "SDL_thread.h"
struct SDL_mutex {
pthread_mutex_t id;
#ifdef PTHREAD_NO_RECURSIVE_MUTEX
#if SDL_THREAD_PTHREAD_NO_RECURSIVE_MUTEX
int recursive;
pthread_t owner;
#endif
@ -47,11 +47,11 @@ SDL_mutex *SDL_CreateMutex (void)
mutex = (SDL_mutex *)SDL_calloc(1, sizeof(*mutex));
if ( mutex ) {
pthread_mutexattr_init(&attr);
#ifdef PTHREAD_NO_RECURSIVE_MUTEX
#if SDL_THREAD_PTHREAD_NO_RECURSIVE_MUTEX
/* No extra attributes necessary */
#else
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
#endif /* PTHREAD_NO_RECURSIVE_MUTEX */
#endif /* SDL_THREAD_PTHREAD_NO_RECURSIVE_MUTEX */
if ( pthread_mutex_init(&mutex->id, &attr) != 0 ) {
SDL_SetError("pthread_mutex_init() failed");
SDL_free(mutex);
@ -75,7 +75,7 @@ void SDL_DestroyMutex(SDL_mutex *mutex)
int SDL_mutexP(SDL_mutex *mutex)
{
int retval;
#ifdef PTHREAD_NO_RECURSIVE_MUTEX
#if SDL_THREAD_PTHREAD_NO_RECURSIVE_MUTEX
pthread_t this_thread;
#endif
@ -85,7 +85,7 @@ int SDL_mutexP(SDL_mutex *mutex)
}
retval = 0;
#ifdef PTHREAD_NO_RECURSIVE_MUTEX
#if SDL_THREAD_PTHREAD_NO_RECURSIVE_MUTEX
this_thread = pthread_self();
if ( mutex->owner == this_thread ) {
++mutex->recursive;
@ -121,7 +121,7 @@ int SDL_mutexV(SDL_mutex *mutex)
}
retval = 0;
#ifdef PTHREAD_NO_RECURSIVE_MUTEX
#if SDL_THREAD_PTHREAD_NO_RECURSIVE_MUTEX
/* We can only unlock the mutex if we own it */
if ( pthread_self() == mutex->owner ) {
if ( mutex->recursive ) {
@ -145,7 +145,7 @@ int SDL_mutexV(SDL_mutex *mutex)
SDL_SetError("pthread_mutex_unlock() failed");
retval = -1;
}
#endif /* PTHREAD_NO_RECURSIVE_MUTEX */
#endif /* SDL_THREAD_PTHREAD_NO_RECURSIVE_MUTEX */
return retval;
}

View file

@ -23,7 +23,7 @@
#ifndef _SDL_mutex_c_h
#define _SDL_mutex_c_h
#ifndef DISABLE_THREADS
#if !SDL_THREADS_DISABLED
struct SDL_mutex {
pthread_mutex_t id;
};

View file

@ -27,7 +27,7 @@
#include "SDL_thread.h"
#include "SDL_systhread_c.h"
#ifdef DISABLE_THREADS
#if !SDL_THREADS_DISABLED
SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
{
@ -196,4 +196,4 @@ int SDL_SemPost(SDL_sem *sem)
return retval;
}
#endif /* DISABLE_THREADS */
#endif /* !SDL_THREADS_DISABLED */

View file

@ -23,9 +23,9 @@
/* RISC OS version based on pthreads linux source */
#include "SDL_thread.h"
#include "SDL_systhread.h"
#include "../SDL_systhread.h"
#ifdef DISABLE_THREADS
#if SDL_THREADS_DISABLED
int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
{

View file

@ -20,7 +20,7 @@
slouken@libsdl.org
*/
#ifdef DISABLE_THREADS
#if SDL_THREADS_DISABLED
typedef int SYS_ThreadHandle;

View file

@ -25,7 +25,8 @@
#include "SDL_windows.h"
#include "SDL_thread.h"
#include "SDL_systhread.h"
#include "../SDL_thread_c.h"
#include "../SDL_systhread.h"
typedef struct ThreadStartParms
{