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:
parent
1507846225
commit
d3805eef09
453 changed files with 3534 additions and 6707 deletions
|
@ -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`)
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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[] = {
|
||||
|
|
|
@ -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 */
|
|
@ -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 */
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
@ -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 */
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -22,7 +22,3 @@
|
|||
|
||||
/* Stub until we implement threads on this platform */
|
||||
typedef int SYS_ThreadHandle;
|
||||
|
||||
#ifndef DISABLE_THREADS
|
||||
#define DISABLE_THREADS
|
||||
#endif
|
||||
|
|
|
@ -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 */
|
|
@ -29,7 +29,7 @@
|
|||
#include <sys/prctl.h>
|
||||
|
||||
#include "SDL_thread.h"
|
||||
#include "SDL_systhread.h"
|
||||
#include "../SDL_systhread.h"
|
||||
|
||||
|
||||
static int sig_list[] = {
|
||||
|
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -28,7 +28,7 @@
|
|||
#include <os2.h>
|
||||
|
||||
#include "SDL_thread.h"
|
||||
#include "SDL_systhread.h"
|
||||
#include "../SDL_systhread.h"
|
||||
|
||||
typedef struct ThreadStartParms
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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_ */
|
|
@ -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)
|
||||
|
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
174
src/thread/pthread/SDL_syssem.c
Normal file
174
src/thread/pthread/SDL_syssem.c
Normal 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;
|
||||
}
|
104
src/thread/pthread/SDL_systhread.c
Normal file
104
src/thread/pthread/SDL_systhread.c
Normal 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
|
||||
}
|
|
@ -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 */
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
slouken@libsdl.org
|
||||
*/
|
||||
|
||||
#ifdef DISABLE_THREADS
|
||||
#if SDL_THREADS_DISABLED
|
||||
|
||||
typedef int SYS_ThreadHandle;
|
||||
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue