forked from len0rd/rockbox
sdl: remove non-rockbox drivers
We never use any of these other drivers, so having them around just takes up space. Change-Id: Iced812162df1fef3fd55522b7e700acb6c3bcd41
This commit is contained in:
parent
ef373c03b9
commit
6039eb05ba
530 changed files with 0 additions and 138647 deletions
|
@ -1,142 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 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_config.h"
|
||||
|
||||
/* Semaphores in the BeOS environment */
|
||||
|
||||
#include <be/kernel/OS.h>
|
||||
|
||||
#include "SDL_thread.h"
|
||||
|
||||
|
||||
struct SDL_semaphore {
|
||||
sem_id id;
|
||||
};
|
||||
|
||||
/* Create a counting semaphore */
|
||||
SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
|
||||
{
|
||||
SDL_sem *sem;
|
||||
|
||||
sem = (SDL_sem *)SDL_malloc(sizeof(*sem));
|
||||
if ( sem ) {
|
||||
sem->id = create_sem(initial_value, "SDL semaphore");
|
||||
if ( sem->id < B_NO_ERROR ) {
|
||||
SDL_SetError("create_sem() failed");
|
||||
SDL_free(sem);
|
||||
sem = NULL;
|
||||
}
|
||||
} else {
|
||||
SDL_OutOfMemory();
|
||||
}
|
||||
return(sem);
|
||||
}
|
||||
|
||||
/* Free the semaphore */
|
||||
void SDL_DestroySemaphore(SDL_sem *sem)
|
||||
{
|
||||
if ( sem ) {
|
||||
if ( sem->id >= B_NO_ERROR ) {
|
||||
delete_sem(sem->id);
|
||||
}
|
||||
SDL_free(sem);
|
||||
}
|
||||
}
|
||||
|
||||
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
|
||||
{
|
||||
int32 val;
|
||||
int retval;
|
||||
|
||||
if ( ! sem ) {
|
||||
SDL_SetError("Passed a NULL semaphore");
|
||||
return -1;
|
||||
}
|
||||
|
||||
tryagain:
|
||||
if ( timeout == SDL_MUTEX_MAXWAIT ) {
|
||||
val = acquire_sem(sem->id);
|
||||
} else {
|
||||
timeout *= 1000; /* BeOS uses a timeout in microseconds */
|
||||
val = acquire_sem_etc(sem->id, 1, B_RELATIVE_TIMEOUT, timeout);
|
||||
}
|
||||
switch (val) {
|
||||
case B_INTERRUPTED:
|
||||
goto tryagain;
|
||||
case B_NO_ERROR:
|
||||
retval = 0;
|
||||
break;
|
||||
case B_TIMED_OUT:
|
||||
retval = SDL_MUTEX_TIMEDOUT;
|
||||
break;
|
||||
case B_WOULD_BLOCK:
|
||||
retval = SDL_MUTEX_TIMEDOUT;
|
||||
break;
|
||||
default:
|
||||
SDL_SetError("acquire_sem() failed");
|
||||
retval = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int SDL_SemTryWait(SDL_sem *sem)
|
||||
{
|
||||
return SDL_SemWaitTimeout(sem, 0);
|
||||
}
|
||||
|
||||
int SDL_SemWait(SDL_sem *sem)
|
||||
{
|
||||
return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
|
||||
}
|
||||
|
||||
/* Returns the current count of the semaphore */
|
||||
Uint32 SDL_SemValue(SDL_sem *sem)
|
||||
{
|
||||
int32 count;
|
||||
Uint32 value;
|
||||
|
||||
value = 0;
|
||||
if ( sem ) {
|
||||
get_sem_count(sem->id, &count);
|
||||
if ( count > 0 ) {
|
||||
value = (Uint32)count;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/* Atomically increases the semaphore's count (not blocking) */
|
||||
int SDL_SemPost(SDL_sem *sem)
|
||||
{
|
||||
if ( ! sem ) {
|
||||
SDL_SetError("Passed a NULL semaphore");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( release_sem(sem->id) != B_NO_ERROR ) {
|
||||
SDL_SetError("release_sem() failed");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -1,96 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 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_config.h"
|
||||
|
||||
/* BeOS thread management routines for SDL */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <be/kernel/OS.h>
|
||||
|
||||
#include "SDL_mutex.h"
|
||||
#include "SDL_thread.h"
|
||||
#include "../SDL_thread_c.h"
|
||||
#include "../SDL_systhread.h"
|
||||
|
||||
|
||||
static int sig_list[] = {
|
||||
SIGHUP, SIGINT, SIGQUIT, SIGPIPE, SIGALRM, SIGTERM, SIGWINCH, 0
|
||||
};
|
||||
|
||||
void SDL_MaskSignals(sigset_t *omask)
|
||||
{
|
||||
sigset_t mask;
|
||||
int i;
|
||||
|
||||
sigemptyset(&mask);
|
||||
for ( i=0; sig_list[i]; ++i ) {
|
||||
sigaddset(&mask, sig_list[i]);
|
||||
}
|
||||
sigprocmask(SIG_BLOCK, &mask, omask);
|
||||
}
|
||||
void SDL_UnmaskSignals(sigset_t *omask)
|
||||
{
|
||||
sigprocmask(SIG_SETMASK, omask, NULL);
|
||||
}
|
||||
|
||||
static int32 RunThread(void *data)
|
||||
{
|
||||
SDL_RunThread(data);
|
||||
return(0);
|
||||
}
|
||||
|
||||
int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
|
||||
{
|
||||
/* Create the thread and go! */
|
||||
thread->handle=spawn_thread(RunThread, "SDL", B_NORMAL_PRIORITY, args);
|
||||
if ( (thread->handle == B_NO_MORE_THREADS) ||
|
||||
(thread->handle == B_NO_MEMORY) ) {
|
||||
SDL_SetError("Not enough resources to create thread");
|
||||
return(-1);
|
||||
}
|
||||
resume_thread(thread->handle);
|
||||
return(0);
|
||||
}
|
||||
|
||||
void SDL_SYS_SetupThread(void)
|
||||
{
|
||||
/* Mask asynchronous signals for this thread */
|
||||
SDL_MaskSignals(NULL);
|
||||
}
|
||||
|
||||
Uint32 SDL_ThreadID(void)
|
||||
{
|
||||
return((Uint32)find_thread(NULL));
|
||||
}
|
||||
|
||||
void SDL_SYS_WaitThread(SDL_Thread *thread)
|
||||
{
|
||||
status_t the_status;
|
||||
|
||||
wait_for_thread(thread->handle, &the_status);
|
||||
}
|
||||
|
||||
void SDL_SYS_KillThread(SDL_Thread *thread)
|
||||
{
|
||||
kill_thread(thread->handle);
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 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_config.h"
|
||||
|
||||
#include <signal.h>
|
||||
#include <be/kernel/OS.h>
|
||||
|
||||
typedef thread_id SYS_ThreadHandle;
|
||||
|
||||
/* Functions needed to work with system threads in other portions of SDL */
|
||||
extern void SDL_MaskSignals(sigset_t *omask);
|
||||
extern void SDL_UnmaskSignals(sigset_t *omask);
|
|
@ -1,215 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 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_config.h"
|
||||
|
||||
/* An implementation of condition variables using semaphores and mutexes */
|
||||
/*
|
||||
This implementation borrows heavily from the BeOS condition variable
|
||||
implementation, written by Christopher Tate and Owen Smith. Thanks!
|
||||
*/
|
||||
|
||||
#include "SDL_thread.h"
|
||||
|
||||
struct SDL_cond
|
||||
{
|
||||
SDL_mutex *lock;
|
||||
int waiting;
|
||||
int signals;
|
||||
SDL_sem *wait_sem;
|
||||
SDL_sem *wait_done;
|
||||
};
|
||||
|
||||
/* Create a condition variable */
|
||||
SDL_cond * SDL_CreateCond(void)
|
||||
{
|
||||
SDL_cond *cond;
|
||||
|
||||
cond = (SDL_cond *) SDL_malloc(sizeof(SDL_cond));
|
||||
if ( cond ) {
|
||||
cond->lock = SDL_CreateMutex();
|
||||
cond->wait_sem = SDL_CreateSemaphore(0);
|
||||
cond->wait_done = SDL_CreateSemaphore(0);
|
||||
cond->waiting = cond->signals = 0;
|
||||
if ( ! cond->lock || ! cond->wait_sem || ! cond->wait_done ) {
|
||||
SDL_DestroyCond(cond);
|
||||
cond = NULL;
|
||||
}
|
||||
} else {
|
||||
SDL_OutOfMemory();
|
||||
}
|
||||
return(cond);
|
||||
}
|
||||
|
||||
/* Destroy a condition variable */
|
||||
void SDL_DestroyCond(SDL_cond *cond)
|
||||
{
|
||||
if ( cond ) {
|
||||
if ( cond->wait_sem ) {
|
||||
SDL_DestroySemaphore(cond->wait_sem);
|
||||
}
|
||||
if ( cond->wait_done ) {
|
||||
SDL_DestroySemaphore(cond->wait_done);
|
||||
}
|
||||
if ( cond->lock ) {
|
||||
SDL_DestroyMutex(cond->lock);
|
||||
}
|
||||
SDL_free(cond);
|
||||
}
|
||||
}
|
||||
|
||||
/* Restart one of the threads that are waiting on the condition variable */
|
||||
int SDL_CondSignal(SDL_cond *cond)
|
||||
{
|
||||
if ( ! cond ) {
|
||||
SDL_SetError("Passed a NULL condition variable");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* If there are waiting threads not already signalled, then
|
||||
signal the condition and wait for the thread to respond.
|
||||
*/
|
||||
SDL_LockMutex(cond->lock);
|
||||
if ( cond->waiting > cond->signals ) {
|
||||
++cond->signals;
|
||||
SDL_SemPost(cond->wait_sem);
|
||||
SDL_UnlockMutex(cond->lock);
|
||||
SDL_SemWait(cond->wait_done);
|
||||
} else {
|
||||
SDL_UnlockMutex(cond->lock);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Restart all threads that are waiting on the condition variable */
|
||||
int SDL_CondBroadcast(SDL_cond *cond)
|
||||
{
|
||||
if ( ! cond ) {
|
||||
SDL_SetError("Passed a NULL condition variable");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* If there are waiting threads not already signalled, then
|
||||
signal the condition and wait for the thread to respond.
|
||||
*/
|
||||
SDL_LockMutex(cond->lock);
|
||||
if ( cond->waiting > cond->signals ) {
|
||||
int i, num_waiting;
|
||||
|
||||
num_waiting = (cond->waiting - cond->signals);
|
||||
cond->signals = cond->waiting;
|
||||
for ( i=0; i<num_waiting; ++i ) {
|
||||
SDL_SemPost(cond->wait_sem);
|
||||
}
|
||||
/* Now all released threads are blocked here, waiting for us.
|
||||
Collect them all (and win fabulous prizes!) :-)
|
||||
*/
|
||||
SDL_UnlockMutex(cond->lock);
|
||||
for ( i=0; i<num_waiting; ++i ) {
|
||||
SDL_SemWait(cond->wait_done);
|
||||
}
|
||||
} else {
|
||||
SDL_UnlockMutex(cond->lock);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Wait on the condition variable for at most 'ms' milliseconds.
|
||||
The mutex must be locked before entering this function!
|
||||
The mutex is unlocked during the wait, and locked again after the wait.
|
||||
|
||||
Typical use:
|
||||
|
||||
Thread A:
|
||||
SDL_LockMutex(lock);
|
||||
while ( ! condition ) {
|
||||
SDL_CondWait(cond);
|
||||
}
|
||||
SDL_UnlockMutex(lock);
|
||||
|
||||
Thread B:
|
||||
SDL_LockMutex(lock);
|
||||
...
|
||||
condition = true;
|
||||
...
|
||||
SDL_UnlockMutex(lock);
|
||||
*/
|
||||
int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if ( ! cond ) {
|
||||
SDL_SetError("Passed a NULL condition variable");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Obtain the protection mutex, and increment the number of waiters.
|
||||
This allows the signal mechanism to only perform a signal if there
|
||||
are waiting threads.
|
||||
*/
|
||||
SDL_LockMutex(cond->lock);
|
||||
++cond->waiting;
|
||||
SDL_UnlockMutex(cond->lock);
|
||||
|
||||
/* Unlock the mutex, as is required by condition variable semantics */
|
||||
SDL_UnlockMutex(mutex);
|
||||
|
||||
/* Wait for a signal */
|
||||
if ( ms == SDL_MUTEX_MAXWAIT ) {
|
||||
retval = SDL_SemWait(cond->wait_sem);
|
||||
} else {
|
||||
retval = SDL_SemWaitTimeout(cond->wait_sem, ms);
|
||||
}
|
||||
|
||||
/* Let the signaler know we have completed the wait, otherwise
|
||||
the signaler can race ahead and get the condition semaphore
|
||||
if we are stopped between the mutex unlock and semaphore wait,
|
||||
giving a deadlock. See the following URL for details:
|
||||
http://www-classic.be.com/aboutbe/benewsletter/volume_III/Issue40.html
|
||||
*/
|
||||
SDL_LockMutex(cond->lock);
|
||||
if ( cond->signals > 0 ) {
|
||||
/* If we timed out, we need to eat a condition signal */
|
||||
if ( retval > 0 ) {
|
||||
SDL_SemWait(cond->wait_sem);
|
||||
}
|
||||
/* We always notify the signal thread that we are done */
|
||||
SDL_SemPost(cond->wait_done);
|
||||
|
||||
/* Signal handshake complete */
|
||||
--cond->signals;
|
||||
}
|
||||
--cond->waiting;
|
||||
SDL_UnlockMutex(cond->lock);
|
||||
|
||||
/* Lock the mutex, as is required by condition variable semantics */
|
||||
SDL_LockMutex(mutex);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Wait on the condition variable forever */
|
||||
int SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex)
|
||||
{
|
||||
return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT);
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 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_config.h"
|
||||
|
|
@ -1,122 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 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_config.h"
|
||||
|
||||
/* An implementation of mutexes using semaphores */
|
||||
|
||||
#include "SDL_thread.h"
|
||||
#include "SDL_systhread_c.h"
|
||||
|
||||
#include <arch/spinlock.h>
|
||||
|
||||
struct SDL_mutex {
|
||||
int recursive;
|
||||
Uint32 owner;
|
||||
spinlock_t mutex;
|
||||
};
|
||||
|
||||
/* Create a mutex */
|
||||
SDL_mutex *SDL_CreateMutex(void)
|
||||
{
|
||||
SDL_mutex *mutex;
|
||||
|
||||
/* Allocate mutex memory */
|
||||
mutex = (SDL_mutex *)SDL_malloc(sizeof(*mutex));
|
||||
if ( mutex ) {
|
||||
spinlock_init(&mutex->mutex);
|
||||
mutex->recursive = 0;
|
||||
mutex->owner = 0;
|
||||
} else {
|
||||
SDL_OutOfMemory();
|
||||
}
|
||||
return mutex;
|
||||
}
|
||||
|
||||
/* Free the mutex */
|
||||
void SDL_DestroyMutex(SDL_mutex *mutex)
|
||||
{
|
||||
if ( mutex ) {
|
||||
SDL_free(mutex);
|
||||
}
|
||||
}
|
||||
|
||||
/* Lock the semaphore */
|
||||
int SDL_mutexP(SDL_mutex *mutex)
|
||||
{
|
||||
#if SDL_THREADS_DISABLED
|
||||
return SDL_arraysize(return ),0;
|
||||
#else
|
||||
Uint32 this_thread;
|
||||
|
||||
if ( mutex == NULL ) {
|
||||
SDL_SetError("Passed a NULL mutex");
|
||||
return -1;
|
||||
}
|
||||
|
||||
this_thread = SDL_ThreadID();
|
||||
if ( mutex->owner == this_thread ) {
|
||||
++mutex->recursive;
|
||||
} else {
|
||||
/* The order of operations is important.
|
||||
We set the locking thread id after we obtain the lock
|
||||
so unlocks from other threads will fail.
|
||||
*/
|
||||
spinlock_lock(&mutex->mutex);
|
||||
mutex->owner = this_thread;
|
||||
mutex->recursive = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
#endif /* SDL_THREADS_DISABLED */
|
||||
}
|
||||
|
||||
/* Unlock the mutex */
|
||||
int SDL_mutexV(SDL_mutex *mutex)
|
||||
{
|
||||
#if SDL_THREADS_DISABLED
|
||||
return 0;
|
||||
#else
|
||||
if ( mutex == NULL ) {
|
||||
SDL_SetError("Passed a NULL mutex");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* If we don't own the mutex, we can't unlock it */
|
||||
if ( SDL_ThreadID() != mutex->owner ) {
|
||||
SDL_SetError("mutex not owned by this thread");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( mutex->recursive ) {
|
||||
--mutex->recursive;
|
||||
} else {
|
||||
/* The order of operations is important.
|
||||
First reset the owner so another thread doesn't lock
|
||||
the mutex and set the ownership before we reset it,
|
||||
then release the lock semaphore.
|
||||
*/
|
||||
mutex->owner = 0;
|
||||
spinlock_unlock(&mutex->mutex);
|
||||
}
|
||||
return 0;
|
||||
#endif /* SDL_THREADS_DISABLED */
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 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_config.h"
|
||||
|
|
@ -1,173 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 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 <errno.h>
|
||||
|
||||
#include "SDL_config.h"
|
||||
|
||||
/* An implementation of semaphores using mutexes and condition variables */
|
||||
|
||||
#include "SDL_timer.h"
|
||||
#include "SDL_thread.h"
|
||||
#include "SDL_systhread_c.h"
|
||||
|
||||
|
||||
#if SDL_THREADS_DISABLED
|
||||
|
||||
SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
|
||||
{
|
||||
SDL_SetError("SDL not configured with thread support");
|
||||
return (SDL_sem *)0;
|
||||
}
|
||||
|
||||
void SDL_DestroySemaphore(SDL_sem *sem)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int SDL_SemTryWait(SDL_sem *sem)
|
||||
{
|
||||
SDL_SetError("SDL not configured with thread support");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
|
||||
{
|
||||
SDL_SetError("SDL not configured with thread support");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int SDL_SemWait(SDL_sem *sem)
|
||||
{
|
||||
SDL_SetError("SDL not configured with thread support");
|
||||
return -1;
|
||||
}
|
||||
|
||||
Uint32 SDL_SemValue(SDL_sem *sem)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SDL_SemPost(SDL_sem *sem)
|
||||
{
|
||||
SDL_SetError("SDL not configured with thread support");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <kos/sem.h>
|
||||
|
||||
struct SDL_semaphore
|
||||
{
|
||||
semaphore_t sem;
|
||||
};
|
||||
|
||||
SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
|
||||
{
|
||||
return (SDL_sem *)sem_create(initial_value);
|
||||
}
|
||||
|
||||
/* WARNING:
|
||||
You cannot call this function when another thread is using the semaphore.
|
||||
*/
|
||||
void SDL_DestroySemaphore(SDL_sem *sem)
|
||||
{
|
||||
if ( ! sem ) {
|
||||
SDL_SetError("Passed a NULL semaphore");
|
||||
return;
|
||||
}
|
||||
|
||||
sem_destroy(&sem->sem);
|
||||
}
|
||||
|
||||
int SDL_SemTryWait(SDL_sem *sem)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if ( ! sem ) {
|
||||
SDL_SetError("Passed a NULL semaphore");
|
||||
return -1;
|
||||
}
|
||||
|
||||
retval = sem_trywait(&sem->sem);
|
||||
if (retval==0) return 0;
|
||||
else return SDL_MUTEX_TIMEDOUT;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if ( ! sem ) {
|
||||
SDL_SetError("Passed a NULL semaphore");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* A timeout of 0 is an easy case */
|
||||
if ( timeout == 0 ) {
|
||||
return SDL_SemTryWait(sem);
|
||||
}
|
||||
|
||||
retval = sem_wait_timed(&sem->sem,timeout);
|
||||
if (retval==-1) retval= SDL_MUTEX_TIMEDOUT;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int SDL_SemWait(SDL_sem *sem)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if ( ! sem ) {
|
||||
SDL_SetError("Passed a NULL semaphore");
|
||||
return -1;
|
||||
}
|
||||
|
||||
while ( ((retval = sem_wait(&sem->sem)) == -1) && (errno == EINTR) ) {}
|
||||
return retval;
|
||||
}
|
||||
|
||||
Uint32 SDL_SemValue(SDL_sem *sem)
|
||||
{
|
||||
if ( ! sem ) {
|
||||
SDL_SetError("Passed a NULL semaphore");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return sem_count(&sem->sem);
|
||||
}
|
||||
|
||||
int SDL_SemPost(SDL_sem *sem)
|
||||
{
|
||||
if ( ! sem ) {
|
||||
SDL_SetError("Passed a NULL semaphore");
|
||||
return -1;
|
||||
}
|
||||
|
||||
sem_signal(&sem->sem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* SDL_THREADS_DISABLED */
|
|
@ -1,23 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 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_config.h"
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 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_config.h"
|
||||
|
||||
/* Thread management routines for SDL */
|
||||
|
||||
#include "SDL_thread.h"
|
||||
#include "../SDL_thread_c.h"
|
||||
#include "../SDL_systhread.h"
|
||||
|
||||
#include <kos/thread.h>
|
||||
|
||||
int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
|
||||
{
|
||||
thread->handle = thd_create(SDL_RunThread,args);
|
||||
if (thread->handle == NULL) {
|
||||
SDL_SetError("Not enough resources to create thread");
|
||||
return(-1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
void SDL_SYS_SetupThread(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Uint32 SDL_ThreadID(void)
|
||||
{
|
||||
return (Uint32)thd_get_current();
|
||||
}
|
||||
|
||||
void SDL_SYS_WaitThread(SDL_Thread *thread)
|
||||
{
|
||||
thd_wait(thread->handle);
|
||||
}
|
||||
|
||||
void SDL_SYS_KillThread(SDL_Thread *thread)
|
||||
{
|
||||
thd_destroy(thread->handle);
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 Sam Lantinga
|
||||
|
||||
This 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.
|
||||
|
||||
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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Sam Lantinga
|
||||
slouken@libsdl.org
|
||||
*/
|
||||
#include "SDL_config.h"
|
||||
|
||||
typedef struct kthread* SYS_ThreadHandle;
|
|
@ -1,219 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 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_config.h"
|
||||
|
||||
#include "SDL_thread.h"
|
||||
#include "SDL_timer.h"
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/sem.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "SDL_error.h"
|
||||
#include "SDL_thread.h"
|
||||
|
||||
|
||||
struct SDL_semaphore {
|
||||
int id;
|
||||
};
|
||||
|
||||
/* Not defined by many operating systems, use configure to detect */
|
||||
/*
|
||||
#if !defined(HAVE_SEMUN)
|
||||
union semun {
|
||||
int val;
|
||||
struct semid_ds *buf;
|
||||
ushort *array;
|
||||
};
|
||||
#endif
|
||||
*/
|
||||
|
||||
static struct sembuf op_trywait[2] = {
|
||||
{ 0, -1, (IPC_NOWAIT|SEM_UNDO) } /* Decrement semaphore, no block */
|
||||
};
|
||||
static struct sembuf op_wait[2] = {
|
||||
{ 0, -1, SEM_UNDO } /* Decrement semaphore */
|
||||
};
|
||||
static struct sembuf op_post[1] = {
|
||||
{ 0, 1, (IPC_NOWAIT|SEM_UNDO) } /* Increment semaphore */
|
||||
};
|
||||
|
||||
/* Create a blockable semaphore */
|
||||
SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
|
||||
{
|
||||
extern int _creating_thread_lock; /* SDL_threads.c */
|
||||
SDL_sem *sem;
|
||||
union semun init;
|
||||
|
||||
sem = (SDL_sem *)SDL_malloc(sizeof(*sem));
|
||||
if ( sem == NULL ) {
|
||||
SDL_OutOfMemory();
|
||||
return(NULL);
|
||||
}
|
||||
sem->id = semget(IPC_PRIVATE, 1, (0600|IPC_CREAT));
|
||||
if ( sem->id < 0 ) {
|
||||
SDL_SetError("Couldn't create semaphore");
|
||||
SDL_free(sem);
|
||||
return(NULL);
|
||||
}
|
||||
init.val = initial_value; /* Initialize semaphore */
|
||||
semctl(sem->id, 0, SETVAL, init);
|
||||
return(sem);
|
||||
}
|
||||
|
||||
void SDL_DestroySemaphore(SDL_sem *sem)
|
||||
{
|
||||
if ( sem ) {
|
||||
#ifdef __IRIX__
|
||||
semctl(sem->id, 0, IPC_RMID);
|
||||
#else
|
||||
union semun dummy;
|
||||
dummy.val = 0;
|
||||
semctl(sem->id, 0, IPC_RMID, dummy);
|
||||
#endif
|
||||
SDL_free(sem);
|
||||
}
|
||||
}
|
||||
|
||||
int SDL_SemTryWait(SDL_sem *sem)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if ( ! sem ) {
|
||||
SDL_SetError("Passed a NULL semaphore");
|
||||
return -1;
|
||||
}
|
||||
|
||||
retval = 0;
|
||||
tryagain:
|
||||
if ( semop(sem->id, op_trywait, 1) < 0 ) {
|
||||
if ( errno == EINTR ) {
|
||||
goto tryagain;
|
||||
}
|
||||
retval = SDL_MUTEX_TIMEDOUT;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
int SDL_SemWait(SDL_sem *sem)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if ( ! sem ) {
|
||||
SDL_SetError("Passed a NULL semaphore");
|
||||
return -1;
|
||||
}
|
||||
|
||||
retval = 0;
|
||||
tryagain:
|
||||
if ( semop(sem->id, op_wait, 1) < 0 ) {
|
||||
if ( errno == EINTR ) {
|
||||
goto tryagain;
|
||||
}
|
||||
SDL_SetError("Semaphore operation error");
|
||||
retval = -1;
|
||||
}
|
||||
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 semval;
|
||||
Uint32 value;
|
||||
|
||||
value = 0;
|
||||
if ( sem ) {
|
||||
tryagain:
|
||||
#ifdef __IRIX__
|
||||
semval = semctl(sem->id, 0, GETVAL);
|
||||
#else
|
||||
{
|
||||
union semun arg;
|
||||
arg.val = 0;
|
||||
semval = semctl(sem->id, 0, GETVAL, arg);
|
||||
}
|
||||
#endif
|
||||
if ( semval < 0 ) {
|
||||
if ( errno == EINTR ) {
|
||||
goto tryagain;
|
||||
}
|
||||
} else {
|
||||
value = (Uint32)semval;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
int SDL_SemPost(SDL_sem *sem)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if ( ! sem ) {
|
||||
SDL_SetError("Passed a NULL semaphore");
|
||||
return -1;
|
||||
}
|
||||
|
||||
retval = 0;
|
||||
tryagain:
|
||||
if ( semop(sem->id, op_post, 1) < 0 ) {
|
||||
if ( errno == EINTR ) {
|
||||
goto tryagain;
|
||||
}
|
||||
SDL_SetError("Semaphore operation error");
|
||||
retval = -1;
|
||||
}
|
||||
return retval;
|
||||
}
|
|
@ -1,85 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 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_config.h"
|
||||
|
||||
/* IRIX thread management routines for SDL */
|
||||
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/prctl.h>
|
||||
|
||||
#include "SDL_thread.h"
|
||||
#include "../SDL_systhread.h"
|
||||
|
||||
|
||||
static int sig_list[] = {
|
||||
SIGHUP, SIGINT, SIGQUIT, SIGPIPE, SIGALRM, SIGTERM, SIGCLD, SIGWINCH,
|
||||
SIGVTALRM, SIGPROF, 0
|
||||
};
|
||||
|
||||
|
||||
int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
|
||||
{
|
||||
/* Create the thread and go! */
|
||||
if ( sproc(SDL_RunThread, PR_SALL, 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]);
|
||||
}
|
||||
sigprocmask(SIG_BLOCK, &mask, NULL);
|
||||
}
|
||||
|
||||
/* WARNING: This may not work for systems with 64-bit pid_t */
|
||||
Uint32 SDL_ThreadID(void)
|
||||
{
|
||||
return((Uint32)getpid());
|
||||
}
|
||||
|
||||
/* WARNING: This may not work for systems with 64-bit pid_t */
|
||||
void SDL_WaitThread(SDL_Thread *thread, int *status)
|
||||
{
|
||||
errno = 0;
|
||||
while ( errno != ECHILD ) {
|
||||
waitpid(thread->handle, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* WARNING: This may not work for systems with 64-bit pid_t */
|
||||
void SDL_KillThread(SDL_Thread *thread)
|
||||
{
|
||||
kill(thread->handle, SIGKILL);
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 Sam Lantinga
|
||||
|
||||
This 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.
|
||||
|
||||
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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Sam Lantinga
|
||||
slouken@libsdl.org
|
||||
*/
|
||||
#include "SDL_config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
typedef pid_t SYS_ThreadHandle;
|
||||
|
|
@ -1,215 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 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_config.h"
|
||||
|
||||
/* An implementation of condition variables using semaphores and mutexes */
|
||||
/*
|
||||
This implementation borrows heavily from the BeOS condition variable
|
||||
implementation, written by Christopher Tate and Owen Smith. Thanks!
|
||||
*/
|
||||
|
||||
#include "SDL_thread.h"
|
||||
|
||||
struct SDL_cond
|
||||
{
|
||||
SDL_mutex *lock;
|
||||
int waiting;
|
||||
int signals;
|
||||
SDL_sem *wait_sem;
|
||||
SDL_sem *wait_done;
|
||||
};
|
||||
|
||||
/* Create a condition variable */
|
||||
DECLSPEC SDL_cond * SDLCALL SDL_CreateCond(void)
|
||||
{
|
||||
SDL_cond *cond;
|
||||
|
||||
cond = (SDL_cond *) SDL_malloc(sizeof(SDL_cond));
|
||||
if ( cond ) {
|
||||
cond->lock = SDL_CreateMutex();
|
||||
cond->wait_sem = SDL_CreateSemaphore(0);
|
||||
cond->wait_done = SDL_CreateSemaphore(0);
|
||||
cond->waiting = cond->signals = 0;
|
||||
if ( ! cond->lock || ! cond->wait_sem || ! cond->wait_done ) {
|
||||
SDL_DestroyCond(cond);
|
||||
cond = NULL;
|
||||
}
|
||||
} else {
|
||||
SDL_OutOfMemory();
|
||||
}
|
||||
return(cond);
|
||||
}
|
||||
|
||||
/* Destroy a condition variable */
|
||||
DECLSPEC void SDLCALL SDL_DestroyCond(SDL_cond *cond)
|
||||
{
|
||||
if ( cond ) {
|
||||
if ( cond->wait_sem ) {
|
||||
SDL_DestroySemaphore(cond->wait_sem);
|
||||
}
|
||||
if ( cond->wait_done ) {
|
||||
SDL_DestroySemaphore(cond->wait_done);
|
||||
}
|
||||
if ( cond->lock ) {
|
||||
SDL_DestroyMutex(cond->lock);
|
||||
}
|
||||
SDL_free(cond);
|
||||
}
|
||||
}
|
||||
|
||||
/* Restart one of the threads that are waiting on the condition variable */
|
||||
DECLSPEC int SDLCALL SDL_CondSignal(SDL_cond *cond)
|
||||
{
|
||||
if ( ! cond ) {
|
||||
SDL_SetError("Passed a NULL condition variable");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* If there are waiting threads not already signalled, then
|
||||
signal the condition and wait for the thread to respond.
|
||||
*/
|
||||
SDL_LockMutex(cond->lock);
|
||||
if ( cond->waiting > cond->signals ) {
|
||||
++cond->signals;
|
||||
SDL_SemPost(cond->wait_sem);
|
||||
SDL_UnlockMutex(cond->lock);
|
||||
SDL_SemWait(cond->wait_done);
|
||||
} else {
|
||||
SDL_UnlockMutex(cond->lock);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Restart all threads that are waiting on the condition variable */
|
||||
DECLSPEC int SDLCALL SDL_CondBroadcast(SDL_cond *cond)
|
||||
{
|
||||
if ( ! cond ) {
|
||||
SDL_SetError("Passed a NULL condition variable");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* If there are waiting threads not already signalled, then
|
||||
signal the condition and wait for the thread to respond.
|
||||
*/
|
||||
SDL_LockMutex(cond->lock);
|
||||
if ( cond->waiting > cond->signals ) {
|
||||
int i, num_waiting;
|
||||
|
||||
num_waiting = (cond->waiting - cond->signals);
|
||||
cond->signals = cond->waiting;
|
||||
for ( i=0; i<num_waiting; ++i ) {
|
||||
SDL_SemPost(cond->wait_sem);
|
||||
}
|
||||
/* Now all released threads are blocked here, waiting for us.
|
||||
Collect them all (and win fabulous prizes!) :-)
|
||||
*/
|
||||
SDL_UnlockMutex(cond->lock);
|
||||
for ( i=0; i<num_waiting; ++i ) {
|
||||
SDL_SemWait(cond->wait_done);
|
||||
}
|
||||
} else {
|
||||
SDL_UnlockMutex(cond->lock);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Wait on the condition variable for at most 'ms' milliseconds.
|
||||
The mutex must be locked before entering this function!
|
||||
The mutex is unlocked during the wait, and locked again after the wait.
|
||||
|
||||
Typical use:
|
||||
|
||||
Thread A:
|
||||
SDL_LockMutex(lock);
|
||||
while ( ! condition ) {
|
||||
SDL_CondWait(cond);
|
||||
}
|
||||
SDL_UnlockMutex(lock);
|
||||
|
||||
Thread B:
|
||||
SDL_LockMutex(lock);
|
||||
...
|
||||
condition = true;
|
||||
...
|
||||
SDL_UnlockMutex(lock);
|
||||
*/
|
||||
DECLSPEC int SDLCALL SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if ( ! cond ) {
|
||||
SDL_SetError("Passed a NULL condition variable");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Obtain the protection mutex, and increment the number of waiters.
|
||||
This allows the signal mechanism to only perform a signal if there
|
||||
are waiting threads.
|
||||
*/
|
||||
SDL_LockMutex(cond->lock);
|
||||
++cond->waiting;
|
||||
SDL_UnlockMutex(cond->lock);
|
||||
|
||||
/* Unlock the mutex, as is required by condition variable semantics */
|
||||
SDL_UnlockMutex(mutex);
|
||||
|
||||
/* Wait for a signal */
|
||||
if ( ms == SDL_MUTEX_MAXWAIT ) {
|
||||
retval = SDL_SemWait(cond->wait_sem);
|
||||
} else {
|
||||
retval = SDL_SemWaitTimeout(cond->wait_sem, ms);
|
||||
}
|
||||
|
||||
/* Let the signaler know we have completed the wait, otherwise
|
||||
the signaler can race ahead and get the condition semaphore
|
||||
if we are stopped between the mutex unlock and semaphore wait,
|
||||
giving a deadlock. See the following URL for details:
|
||||
http://www-classic.be.com/aboutbe/benewsletter/volume_III/Issue40.html
|
||||
*/
|
||||
SDL_LockMutex(cond->lock);
|
||||
if ( cond->signals > 0 ) {
|
||||
/* If we timed out, we need to eat a condition signal */
|
||||
if ( retval > 0 ) {
|
||||
SDL_SemWait(cond->wait_sem);
|
||||
}
|
||||
/* We always notify the signal thread that we are done */
|
||||
SDL_SemPost(cond->wait_done);
|
||||
|
||||
/* Signal handshake complete */
|
||||
--cond->signals;
|
||||
}
|
||||
--cond->waiting;
|
||||
SDL_UnlockMutex(cond->lock);
|
||||
|
||||
/* Lock the mutex, as is required by condition variable semantics */
|
||||
SDL_LockMutex(mutex);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Wait on the condition variable forever */
|
||||
DECLSPEC int SDLCALL SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex)
|
||||
{
|
||||
return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT);
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 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_config.h"
|
||||
|
|
@ -1,108 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 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_config.h"
|
||||
|
||||
/* Mutex functions using the OS/2 API */
|
||||
|
||||
#define INCL_DOSERRORS
|
||||
#define INCL_DOSSEMAPHORES
|
||||
#include <os2.h>
|
||||
|
||||
#include "SDL_mutex.h"
|
||||
|
||||
|
||||
struct SDL_mutex {
|
||||
HMTX hmtxID;
|
||||
};
|
||||
|
||||
/* Create a mutex */
|
||||
DECLSPEC SDL_mutex * SDLCALL SDL_CreateMutex(void)
|
||||
{
|
||||
SDL_mutex *mutex;
|
||||
APIRET ulrc;
|
||||
|
||||
/* Allocate mutex memory */
|
||||
mutex = (SDL_mutex *)SDL_malloc(sizeof(*mutex));
|
||||
if (mutex)
|
||||
{
|
||||
/* Create the mutex, with initial value signaled */
|
||||
ulrc = DosCreateMutexSem(NULL, // Create unnamed semaphore
|
||||
&(mutex->hmtxID), // Pointer to handle
|
||||
0L, // Flags: create it private (not shared)
|
||||
FALSE); // Initial value: unowned
|
||||
if (ulrc!=NO_ERROR)
|
||||
{
|
||||
SDL_SetError("Couldn't create mutex");
|
||||
SDL_free(mutex);
|
||||
mutex = NULL;
|
||||
}
|
||||
} else {
|
||||
SDL_OutOfMemory();
|
||||
}
|
||||
return(mutex);
|
||||
}
|
||||
|
||||
/* Free the mutex */
|
||||
DECLSPEC void SDLCALL SDL_DestroyMutex(SDL_mutex *mutex)
|
||||
{
|
||||
if ( mutex )
|
||||
{
|
||||
if ( mutex->hmtxID )
|
||||
{
|
||||
DosCloseMutexSem(mutex->hmtxID);
|
||||
mutex->hmtxID = 0;
|
||||
}
|
||||
SDL_free(mutex);
|
||||
}
|
||||
}
|
||||
|
||||
/* Lock the mutex */
|
||||
DECLSPEC int SDLCALL SDL_mutexP(SDL_mutex *mutex)
|
||||
{
|
||||
if ( mutex == NULL )
|
||||
{
|
||||
SDL_SetError("Passed a NULL mutex");
|
||||
return -1;
|
||||
}
|
||||
if ( DosRequestMutexSem(mutex->hmtxID, SEM_INDEFINITE_WAIT) != NO_ERROR )
|
||||
{
|
||||
SDL_SetError("Couldn't wait on mutex");
|
||||
return -1;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Unlock the mutex */
|
||||
DECLSPEC int SDLCALL SDL_mutexV(SDL_mutex *mutex)
|
||||
{
|
||||
if ( mutex == NULL )
|
||||
{
|
||||
SDL_SetError("Passed a NULL mutex");
|
||||
return -1;
|
||||
}
|
||||
if ( DosReleaseMutexSem(mutex->hmtxID) != NO_ERROR )
|
||||
{
|
||||
SDL_SetError("Couldn't release mutex");
|
||||
return -1;
|
||||
}
|
||||
return(0);
|
||||
}
|
|
@ -1,192 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 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_config.h"
|
||||
|
||||
/* Semaphore functions using the OS/2 API */
|
||||
|
||||
#define INCL_DOS
|
||||
#define INCL_DOSERRORS
|
||||
#define INCL_DOSSEMAPHORES
|
||||
#include <os2.h>
|
||||
|
||||
#include "SDL_thread.h"
|
||||
#include "SDL_timer.h"
|
||||
|
||||
|
||||
struct SDL_semaphore {
|
||||
HMTX id;
|
||||
HEV changed;
|
||||
Uint32 value;
|
||||
};
|
||||
|
||||
|
||||
/* Create a semaphore */
|
||||
DECLSPEC SDL_sem * SDLCALL SDL_CreateSemaphore(Uint32 initial_value)
|
||||
{
|
||||
SDL_sem *sem;
|
||||
ULONG ulrc;
|
||||
|
||||
/* Allocate sem memory */
|
||||
sem = (SDL_sem *)SDL_malloc(sizeof(*sem));
|
||||
if ( sem ) {
|
||||
/* Create the mutex semaphore */
|
||||
ulrc = DosCreateMutexSem(NULL,&(sem->id),0,TRUE);
|
||||
if ( ulrc ) {
|
||||
SDL_SetError("Couldn't create semaphore");
|
||||
SDL_free(sem);
|
||||
sem = NULL;
|
||||
} else
|
||||
{
|
||||
DosCreateEventSem(NULL, &(sem->changed), 0, FALSE);
|
||||
sem->value = initial_value;
|
||||
DosReleaseMutexSem(sem->id);
|
||||
}
|
||||
} else {
|
||||
SDL_OutOfMemory();
|
||||
}
|
||||
return(sem);
|
||||
}
|
||||
|
||||
/* Free the semaphore */
|
||||
DECLSPEC void SDLCALL SDL_DestroySemaphore(SDL_sem *sem)
|
||||
{
|
||||
if ( sem ) {
|
||||
if ( sem->id ) {
|
||||
DosCloseEventSem(sem->changed);
|
||||
DosCloseMutexSem(sem->id);
|
||||
sem->id = 0;
|
||||
}
|
||||
SDL_free(sem);
|
||||
}
|
||||
}
|
||||
|
||||
DECLSPEC int SDLCALL SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
|
||||
{
|
||||
ULONG ulrc;
|
||||
|
||||
if ( ! sem ) {
|
||||
SDL_SetError("Passed a NULL sem");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( timeout == SDL_MUTEX_MAXWAIT ) {
|
||||
while (1) {
|
||||
ulrc = DosRequestMutexSem(sem->id, SEM_INDEFINITE_WAIT);
|
||||
if (ulrc) {
|
||||
/* if error waiting mutex */
|
||||
SDL_SetError("DosRequestMutexSem() failed");
|
||||
return -1;
|
||||
} else if (sem->value) {
|
||||
sem->value--;
|
||||
DosReleaseMutexSem(sem->id);
|
||||
return 0;
|
||||
} else {
|
||||
ULONG ulPostCount;
|
||||
DosResetEventSem(sem->changed, &ulPostCount);
|
||||
DosReleaseMutexSem(sem->id);
|
||||
/* continue waiting until somebody posts the semaphore */
|
||||
DosWaitEventSem(sem->changed, SEM_INDEFINITE_WAIT);
|
||||
}
|
||||
}
|
||||
} else
|
||||
if ( timeout == 0 )
|
||||
{
|
||||
ulrc = DosRequestMutexSem(sem->id, SEM_INDEFINITE_WAIT);
|
||||
if (ulrc==NO_ERROR)
|
||||
{
|
||||
if (sem->value)
|
||||
{
|
||||
sem->value--;
|
||||
DosReleaseMutexSem(sem->id);
|
||||
return 0;
|
||||
} else
|
||||
{
|
||||
DosReleaseMutexSem(sem->id);
|
||||
return SDL_MUTEX_TIMEDOUT;
|
||||
}
|
||||
} else
|
||||
{
|
||||
SDL_SetError("DosRequestMutexSem() failed");
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
ulrc = DosRequestMutexSem(sem->id, SEM_INDEFINITE_WAIT);
|
||||
if (ulrc) {
|
||||
/* if error waiting mutex */
|
||||
SDL_SetError("DosRequestMutexSem() failed");
|
||||
return -1;
|
||||
} else
|
||||
if (sem->value) {
|
||||
sem->value--;
|
||||
DosReleaseMutexSem(sem->id);
|
||||
return 0;
|
||||
} else {
|
||||
ULONG ulPostCount;
|
||||
DosResetEventSem(sem->changed, &ulPostCount);
|
||||
DosReleaseMutexSem(sem->id);
|
||||
/* continue waiting until somebody posts the semaphore */
|
||||
ulrc = DosWaitEventSem(sem->changed, timeout);
|
||||
if (ulrc==NO_ERROR)
|
||||
return 0;
|
||||
else
|
||||
return SDL_MUTEX_TIMEDOUT;
|
||||
}
|
||||
}
|
||||
/* never reached */
|
||||
return -1;
|
||||
}
|
||||
|
||||
DECLSPEC int SDLCALL SDL_SemTryWait(SDL_sem *sem)
|
||||
{
|
||||
return SDL_SemWaitTimeout(sem, 0);
|
||||
}
|
||||
|
||||
DECLSPEC int SDLCALL SDL_SemWait(SDL_sem *sem)
|
||||
{
|
||||
return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
|
||||
}
|
||||
|
||||
/* Returns the current count of the semaphore */
|
||||
DECLSPEC Uint32 SDLCALL SDL_SemValue(SDL_sem *sem)
|
||||
{
|
||||
if ( ! sem ) {
|
||||
SDL_SetError("Passed a NULL sem");
|
||||
return 0;
|
||||
}
|
||||
return sem->value;
|
||||
}
|
||||
|
||||
DECLSPEC int SDLCALL SDL_SemPost(SDL_sem *sem)
|
||||
{
|
||||
if ( ! sem ) {
|
||||
SDL_SetError("Passed a NULL sem");
|
||||
return -1;
|
||||
}
|
||||
if ( DosRequestMutexSem(sem->id,SEM_INDEFINITE_WAIT) ) {
|
||||
SDL_SetError("DosRequestMutexSem() failed");
|
||||
return -1;
|
||||
}
|
||||
sem->value++;
|
||||
DosPostEventSem(sem->changed);
|
||||
DosReleaseMutexSem(sem->id);
|
||||
return 0;
|
||||
}
|
|
@ -1,108 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 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_config.h"
|
||||
|
||||
/* OS/2 thread management routines for SDL */
|
||||
|
||||
#include <process.h>
|
||||
#define INCL_DOSERRORS
|
||||
#define INCL_DOSPROCESS
|
||||
#include <os2.h>
|
||||
|
||||
#include "SDL_thread.h"
|
||||
#include "../SDL_systhread.h"
|
||||
#include "../SDL_thread_c.h"
|
||||
|
||||
typedef struct ThreadStartParms
|
||||
{
|
||||
void *args;
|
||||
pfnSDL_CurrentEndThread pfnCurrentEndThread;
|
||||
} tThreadStartParms, *pThreadStartParms;
|
||||
|
||||
static void threadfunc(void *pparm)
|
||||
{
|
||||
pThreadStartParms pThreadParms = pparm;
|
||||
pfnSDL_CurrentEndThread pfnCurrentEndThread = NULL;
|
||||
|
||||
// Call the thread function!
|
||||
SDL_RunThread(pThreadParms->args);
|
||||
|
||||
// Get the current endthread we have to use!
|
||||
if (pThreadParms)
|
||||
{
|
||||
pfnCurrentEndThread = pThreadParms->pfnCurrentEndThread;
|
||||
SDL_free(pThreadParms);
|
||||
}
|
||||
// Call endthread!
|
||||
if (pfnCurrentEndThread)
|
||||
(*pfnCurrentEndThread)();
|
||||
}
|
||||
|
||||
int SDL_SYS_CreateThread(SDL_Thread *thread, void *args, pfnSDL_CurrentBeginThread pfnBeginThread, pfnSDL_CurrentEndThread pfnEndThread)
|
||||
{
|
||||
pThreadStartParms pThreadParms = SDL_malloc(sizeof(tThreadStartParms));
|
||||
if (!pThreadParms)
|
||||
{
|
||||
SDL_SetError("Not enough memory to create thread");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
// Save the function which we will have to call to clear the RTL of calling app!
|
||||
pThreadParms->pfnCurrentEndThread = pfnEndThread;
|
||||
// Also save the real parameters we have to pass to thread function
|
||||
pThreadParms->args = args;
|
||||
// Start the thread using the runtime library of calling app!
|
||||
thread->threadid = thread->handle = (*pfnBeginThread)(threadfunc, NULL, 512*1024, pThreadParms);
|
||||
if ((int)thread->threadid <= 0)
|
||||
{
|
||||
SDL_SetError("Not enough resources to create thread");
|
||||
return(-1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
void SDL_SYS_SetupThread(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DECLSPEC Uint32 SDLCALL SDL_ThreadID(void)
|
||||
{
|
||||
PTIB tib;
|
||||
DosGetInfoBlocks(&tib, NULL);
|
||||
return((Uint32) (tib->tib_ptib2->tib2_ultid));
|
||||
}
|
||||
|
||||
void SDL_SYS_WaitThread(SDL_Thread *thread)
|
||||
{
|
||||
TID tid = thread->handle;
|
||||
DosWaitThread(&tid, DCWW_WAIT);
|
||||
}
|
||||
|
||||
/* WARNING: This function is really a last resort.
|
||||
* Threads should be signaled and then exit by themselves.
|
||||
* TerminateThread() doesn't perform stack and DLL cleanup.
|
||||
*/
|
||||
void SDL_SYS_KillThread(SDL_Thread *thread)
|
||||
{
|
||||
DosKillThread(thread->handle);
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 Sam Lantinga
|
||||
|
||||
This 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.
|
||||
|
||||
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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Sam Lantinga
|
||||
slouken@libsdl.org
|
||||
*/
|
||||
#include "SDL_config.h"
|
||||
|
||||
#define INCL_DOSPROCESS
|
||||
#include <os2.h>
|
||||
|
||||
typedef TID SYS_ThreadHandle;
|
||||
|
|
@ -1,164 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 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_config.h"
|
||||
|
||||
/*
|
||||
* GNU pth conditions variables
|
||||
*
|
||||
* Patrice Mandin
|
||||
*/
|
||||
|
||||
#include <pth.h>
|
||||
|
||||
#include "SDL_thread.h"
|
||||
#include "SDL_sysmutex_c.h"
|
||||
|
||||
struct SDL_cond
|
||||
{
|
||||
pth_cond_t condpth_p;
|
||||
};
|
||||
|
||||
/* Create a condition variable */
|
||||
SDL_cond * SDL_CreateCond(void)
|
||||
{
|
||||
SDL_cond *cond;
|
||||
|
||||
cond = (SDL_cond *) SDL_malloc(sizeof(SDL_cond));
|
||||
if ( cond ) {
|
||||
if ( pth_cond_init(&(cond->condpth_p)) < 0 ) {
|
||||
SDL_SetError("pthread_cond_init() failed");
|
||||
SDL_free(cond);
|
||||
cond = NULL;
|
||||
}
|
||||
} else {
|
||||
SDL_OutOfMemory();
|
||||
}
|
||||
return(cond);
|
||||
}
|
||||
|
||||
/* Destroy a condition variable */
|
||||
void SDL_DestroyCond(SDL_cond *cond)
|
||||
{
|
||||
if ( cond ) {
|
||||
SDL_free(cond);
|
||||
}
|
||||
}
|
||||
|
||||
/* Restart one of the threads that are waiting on the condition variable */
|
||||
int SDL_CondSignal(SDL_cond *cond)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if ( ! cond ) {
|
||||
SDL_SetError("Passed a NULL condition variable");
|
||||
return -1;
|
||||
}
|
||||
|
||||
retval = 0;
|
||||
if ( pth_cond_notify(&(cond->condpth_p), FALSE) != 0 ) {
|
||||
SDL_SetError("pth_cond_notify() failed");
|
||||
retval = -1;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Restart all threads that are waiting on the condition variable */
|
||||
int SDL_CondBroadcast(SDL_cond *cond)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if ( ! cond ) {
|
||||
SDL_SetError("Passed a NULL condition variable");
|
||||
return -1;
|
||||
}
|
||||
|
||||
retval = 0;
|
||||
if ( pth_cond_notify(&(cond->condpth_p), TRUE) != 0 ) {
|
||||
SDL_SetError("pth_cond_notify() failed");
|
||||
retval = -1;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Wait on the condition variable for at most 'ms' milliseconds.
|
||||
The mutex must be locked before entering this function!
|
||||
The mutex is unlocked during the wait, and locked again after the wait.
|
||||
|
||||
Typical use:
|
||||
|
||||
Thread A:
|
||||
SDL_LockMutex(lock);
|
||||
while ( ! condition ) {
|
||||
SDL_CondWait(cond);
|
||||
}
|
||||
SDL_UnlockMutex(lock);
|
||||
|
||||
Thread B:
|
||||
SDL_LockMutex(lock);
|
||||
...
|
||||
condition = true;
|
||||
...
|
||||
SDL_UnlockMutex(lock);
|
||||
*/
|
||||
int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
|
||||
{
|
||||
int retval;
|
||||
pth_event_t ev;
|
||||
int sec;
|
||||
|
||||
if ( ! cond ) {
|
||||
SDL_SetError("Passed a NULL condition variable");
|
||||
return -1;
|
||||
}
|
||||
|
||||
retval = 0;
|
||||
|
||||
sec = ms/1000;
|
||||
ev = pth_event(PTH_EVENT_TIME, pth_timeout(sec,(ms-sec*1000)*1000));
|
||||
|
||||
if ( pth_cond_await(&(cond->condpth_p), &(mutex->mutexpth_p), ev) != 0 ) {
|
||||
SDL_SetError("pth_cond_await() failed");
|
||||
retval = -1;
|
||||
}
|
||||
|
||||
pth_event_free(ev, PTH_FREE_ALL);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Wait on the condition variable forever */
|
||||
int SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if ( ! cond ) {
|
||||
SDL_SetError("Passed a NULL condition variable");
|
||||
return -1;
|
||||
}
|
||||
|
||||
retval = 0;
|
||||
if ( pth_cond_await(&(cond->condpth_p), &(mutex->mutexpth_p), NULL) != 0 ) {
|
||||
SDL_SetError("pth_cond_await() failed");
|
||||
retval = -1;
|
||||
}
|
||||
return retval;
|
||||
}
|
|
@ -1,87 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 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_config.h"
|
||||
|
||||
/*
|
||||
* GNU pth mutexes
|
||||
*
|
||||
* Patrice Mandin
|
||||
*/
|
||||
|
||||
#include <pth.h>
|
||||
|
||||
#include "SDL_mutex.h"
|
||||
#include "SDL_sysmutex_c.h"
|
||||
|
||||
/* Create a mutex */
|
||||
SDL_mutex *SDL_CreateMutex(void)
|
||||
{
|
||||
SDL_mutex *mutex;
|
||||
|
||||
/* Allocate mutex memory */
|
||||
mutex = (SDL_mutex *)SDL_malloc(sizeof(*mutex));
|
||||
if ( mutex ) {
|
||||
/* Create the mutex, with initial value signaled */
|
||||
if (!pth_mutex_init(&(mutex->mutexpth_p))) {
|
||||
SDL_SetError("Couldn't create mutex");
|
||||
SDL_free(mutex);
|
||||
mutex = NULL;
|
||||
}
|
||||
} else {
|
||||
SDL_OutOfMemory();
|
||||
}
|
||||
return(mutex);
|
||||
}
|
||||
|
||||
/* Free the mutex */
|
||||
void SDL_DestroyMutex(SDL_mutex *mutex)
|
||||
{
|
||||
if ( mutex ) {
|
||||
SDL_free(mutex);
|
||||
}
|
||||
}
|
||||
|
||||
/* Lock the mutex */
|
||||
int SDL_mutexP(SDL_mutex *mutex)
|
||||
{
|
||||
if ( mutex == NULL ) {
|
||||
SDL_SetError("Passed a NULL mutex");
|
||||
return -1;
|
||||
}
|
||||
|
||||
pth_mutex_acquire(&(mutex->mutexpth_p), FALSE, NULL);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Unlock the mutex */
|
||||
int SDL_mutexV(SDL_mutex *mutex)
|
||||
{
|
||||
if ( mutex == NULL ) {
|
||||
SDL_SetError("Passed a NULL mutex");
|
||||
return -1;
|
||||
}
|
||||
|
||||
pth_mutex_release(&(mutex->mutexpth_p));
|
||||
|
||||
return(0);
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 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_config.h"
|
||||
|
||||
#ifndef _SDL_SYSMUTEX_C_H_
|
||||
#define _SDL_SYSMUTEX_C_H_
|
||||
|
||||
struct SDL_mutex {
|
||||
pth_mutex_t mutexpth_p;
|
||||
};
|
||||
|
||||
#endif /* _SDL_SYSMUTEX_C_H_ */
|
|
@ -1,103 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 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_config.h"
|
||||
|
||||
/*
|
||||
* GNU pth threads
|
||||
*
|
||||
* Patrice Mandin
|
||||
*/
|
||||
|
||||
#include <pth.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);
|
||||
pth_exit((void*)0);
|
||||
return((void *)0); /* Prevent compiler warning */
|
||||
}
|
||||
|
||||
int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
|
||||
{
|
||||
pth_attr_t type;
|
||||
|
||||
/* Create a new attribute */
|
||||
type = pth_attr_new();
|
||||
if ( type == NULL ) {
|
||||
SDL_SetError("Couldn't initialize pth attributes");
|
||||
return(-1);
|
||||
}
|
||||
pth_attr_set(type, PTH_ATTR_JOINABLE, TRUE);
|
||||
|
||||
/* Create the thread and go! */
|
||||
thread->handle = pth_spawn(type, RunThread, args);
|
||||
if ( thread->handle == NULL ) {
|
||||
SDL_SetError("Not enough resources to create thread");
|
||||
return(-1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
void SDL_SYS_SetupThread(void)
|
||||
{
|
||||
int i;
|
||||
sigset_t mask;
|
||||
int oldstate;
|
||||
|
||||
/* Mask asynchronous signals for this thread */
|
||||
sigemptyset(&mask);
|
||||
for ( i=0; sig_list[i]; ++i ) {
|
||||
sigaddset(&mask, sig_list[i]);
|
||||
}
|
||||
pth_sigmask(SIG_BLOCK, &mask, 0);
|
||||
|
||||
/* Allow ourselves to be asynchronously cancelled */
|
||||
pth_cancel_state(PTH_CANCEL_ASYNCHRONOUS, &oldstate);
|
||||
}
|
||||
|
||||
/* WARNING: This may not work for systems with 64-bit pid_t */
|
||||
Uint32 SDL_ThreadID(void)
|
||||
{
|
||||
return((Uint32)pth_self());
|
||||
}
|
||||
|
||||
void SDL_SYS_WaitThread(SDL_Thread *thread)
|
||||
{
|
||||
pth_join(thread->handle, NULL);
|
||||
}
|
||||
|
||||
void SDL_SYS_KillThread(SDL_Thread *thread)
|
||||
{
|
||||
pth_cancel(thread->handle);
|
||||
pth_join(thread->handle, NULL);
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 Sam Lantinga
|
||||
|
||||
This 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.
|
||||
|
||||
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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Sam Lantinga
|
||||
slouken@libsdl.org
|
||||
*/
|
||||
#include "SDL_config.h"
|
||||
|
||||
#ifndef _SDL_SYSTHREAD_C_H_
|
||||
#define _SDL_SYSTHREAD_C_H_
|
||||
|
||||
#include <pth.h>
|
||||
|
||||
typedef pth_t SYS_ThreadHandle;
|
||||
|
||||
#endif /* _SDL_SYSTHREAD_C_H_ */
|
|
@ -1,155 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 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_config.h"
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "SDL_thread.h"
|
||||
#include "SDL_sysmutex_c.h"
|
||||
|
||||
struct SDL_cond
|
||||
{
|
||||
pthread_cond_t cond;
|
||||
};
|
||||
|
||||
/* Create a condition variable */
|
||||
SDL_cond * SDL_CreateCond(void)
|
||||
{
|
||||
SDL_cond *cond;
|
||||
|
||||
cond = (SDL_cond *) SDL_malloc(sizeof(SDL_cond));
|
||||
if ( cond ) {
|
||||
if ( pthread_cond_init(&cond->cond, NULL) < 0 ) {
|
||||
SDL_SetError("pthread_cond_init() failed");
|
||||
SDL_free(cond);
|
||||
cond = NULL;
|
||||
}
|
||||
}
|
||||
return(cond);
|
||||
}
|
||||
|
||||
/* Destroy a condition variable */
|
||||
void SDL_DestroyCond(SDL_cond *cond)
|
||||
{
|
||||
if ( cond ) {
|
||||
pthread_cond_destroy(&cond->cond);
|
||||
SDL_free(cond);
|
||||
}
|
||||
}
|
||||
|
||||
/* Restart one of the threads that are waiting on the condition variable */
|
||||
int SDL_CondSignal(SDL_cond *cond)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if ( ! cond ) {
|
||||
SDL_SetError("Passed a NULL condition variable");
|
||||
return -1;
|
||||
}
|
||||
|
||||
retval = 0;
|
||||
if ( pthread_cond_signal(&cond->cond) != 0 ) {
|
||||
SDL_SetError("pthread_cond_signal() failed");
|
||||
retval = -1;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Restart all threads that are waiting on the condition variable */
|
||||
int SDL_CondBroadcast(SDL_cond *cond)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if ( ! cond ) {
|
||||
SDL_SetError("Passed a NULL condition variable");
|
||||
return -1;
|
||||
}
|
||||
|
||||
retval = 0;
|
||||
if ( pthread_cond_broadcast(&cond->cond) != 0 ) {
|
||||
SDL_SetError("pthread_cond_broadcast() failed");
|
||||
retval = -1;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
|
||||
{
|
||||
int retval;
|
||||
struct timeval delta;
|
||||
struct timespec abstime;
|
||||
|
||||
if ( ! cond ) {
|
||||
SDL_SetError("Passed a NULL condition variable");
|
||||
return -1;
|
||||
}
|
||||
|
||||
gettimeofday(&delta, NULL);
|
||||
|
||||
abstime.tv_sec = delta.tv_sec + (ms/1000);
|
||||
abstime.tv_nsec = (delta.tv_usec + (ms%1000) * 1000) * 1000;
|
||||
if ( abstime.tv_nsec > 1000000000 ) {
|
||||
abstime.tv_sec += 1;
|
||||
abstime.tv_nsec -= 1000000000;
|
||||
}
|
||||
|
||||
tryagain:
|
||||
retval = pthread_cond_timedwait(&cond->cond, &mutex->id, &abstime);
|
||||
switch (retval) {
|
||||
case EINTR:
|
||||
goto tryagain;
|
||||
break;
|
||||
case ETIMEDOUT:
|
||||
retval = SDL_MUTEX_TIMEDOUT;
|
||||
break;
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
SDL_SetError("pthread_cond_timedwait() failed");
|
||||
retval = -1;
|
||||
break;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Wait on the condition variable, unlocking the provided mutex.
|
||||
The mutex must be locked before entering this function!
|
||||
*/
|
||||
int SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if ( ! cond ) {
|
||||
SDL_SetError("Passed a NULL condition variable");
|
||||
return -1;
|
||||
}
|
||||
|
||||
retval = 0;
|
||||
if ( pthread_cond_wait(&cond->cond, &mutex->id) != 0 ) {
|
||||
SDL_SetError("pthread_cond_wait() failed");
|
||||
retval = -1;
|
||||
}
|
||||
return retval;
|
||||
}
|
|
@ -1,153 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 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_config.h"
|
||||
|
||||
#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;
|
||||
#if FAKE_RECURSIVE_MUTEX
|
||||
int recursive;
|
||||
pthread_t owner;
|
||||
#endif
|
||||
};
|
||||
|
||||
SDL_mutex *SDL_CreateMutex (void)
|
||||
{
|
||||
SDL_mutex *mutex;
|
||||
pthread_mutexattr_t attr;
|
||||
|
||||
/* Allocate the structure */
|
||||
mutex = (SDL_mutex *)SDL_calloc(1, sizeof(*mutex));
|
||||
if ( mutex ) {
|
||||
pthread_mutexattr_init(&attr);
|
||||
#if SDL_THREAD_PTHREAD_RECURSIVE_MUTEX
|
||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
|
||||
#elif SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP
|
||||
pthread_mutexattr_setkind_np(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
|
||||
#else
|
||||
/* No extra attributes necessary */
|
||||
#endif
|
||||
if ( pthread_mutex_init(&mutex->id, &attr) != 0 ) {
|
||||
SDL_SetError("pthread_mutex_init() failed");
|
||||
SDL_free(mutex);
|
||||
mutex = NULL;
|
||||
}
|
||||
} else {
|
||||
SDL_OutOfMemory();
|
||||
}
|
||||
return(mutex);
|
||||
}
|
||||
|
||||
void SDL_DestroyMutex(SDL_mutex *mutex)
|
||||
{
|
||||
if ( mutex ) {
|
||||
pthread_mutex_destroy(&mutex->id);
|
||||
SDL_free(mutex);
|
||||
}
|
||||
}
|
||||
|
||||
/* Lock the mutex */
|
||||
int SDL_mutexP(SDL_mutex *mutex)
|
||||
{
|
||||
int retval;
|
||||
#if FAKE_RECURSIVE_MUTEX
|
||||
pthread_t this_thread;
|
||||
#endif
|
||||
|
||||
if ( mutex == NULL ) {
|
||||
SDL_SetError("Passed a NULL mutex");
|
||||
return -1;
|
||||
}
|
||||
|
||||
retval = 0;
|
||||
#if FAKE_RECURSIVE_MUTEX
|
||||
this_thread = pthread_self();
|
||||
if ( mutex->owner == this_thread ) {
|
||||
++mutex->recursive;
|
||||
} else {
|
||||
/* The order of operations is important.
|
||||
We set the locking thread id after we obtain the lock
|
||||
so unlocks from other threads will fail.
|
||||
*/
|
||||
if ( pthread_mutex_lock(&mutex->id) == 0 ) {
|
||||
mutex->owner = this_thread;
|
||||
mutex->recursive = 0;
|
||||
} else {
|
||||
SDL_SetError("pthread_mutex_lock() failed");
|
||||
retval = -1;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if ( pthread_mutex_lock(&mutex->id) < 0 ) {
|
||||
SDL_SetError("pthread_mutex_lock() failed");
|
||||
retval = -1;
|
||||
}
|
||||
#endif
|
||||
return retval;
|
||||
}
|
||||
|
||||
int SDL_mutexV(SDL_mutex *mutex)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if ( mutex == NULL ) {
|
||||
SDL_SetError("Passed a NULL mutex");
|
||||
return -1;
|
||||
}
|
||||
|
||||
retval = 0;
|
||||
#if FAKE_RECURSIVE_MUTEX
|
||||
/* We can only unlock the mutex if we own it */
|
||||
if ( pthread_self() == mutex->owner ) {
|
||||
if ( mutex->recursive ) {
|
||||
--mutex->recursive;
|
||||
} else {
|
||||
/* The order of operations is important.
|
||||
First reset the owner so another thread doesn't lock
|
||||
the mutex and set the ownership before we reset it,
|
||||
then release the lock semaphore.
|
||||
*/
|
||||
mutex->owner = 0;
|
||||
pthread_mutex_unlock(&mutex->id);
|
||||
}
|
||||
} else {
|
||||
SDL_SetError("mutex not owned by this thread");
|
||||
retval = -1;
|
||||
}
|
||||
|
||||
#else
|
||||
if ( pthread_mutex_unlock(&mutex->id) < 0 ) {
|
||||
SDL_SetError("pthread_mutex_unlock() failed");
|
||||
retval = -1;
|
||||
}
|
||||
#endif /* FAKE_RECURSIVE_MUTEX */
|
||||
|
||||
return retval;
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 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_config.h"
|
||||
|
||||
#ifndef _SDL_mutex_c_h
|
||||
#define _SDL_mutex_c_h
|
||||
|
||||
struct SDL_mutex {
|
||||
pthread_mutex_t id;
|
||||
};
|
||||
|
||||
#endif /* _SDL_mutex_c_h */
|
|
@ -1,190 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 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_config.h"
|
||||
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <errno.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "SDL_thread.h"
|
||||
#include "SDL_timer.h"
|
||||
|
||||
/* Wrapper around POSIX 1003.1b semaphores */
|
||||
|
||||
#ifdef __MACOSX__
|
||||
/* Mac OS X doesn't support sem_getvalue() as of version 10.4 */
|
||||
#include "../generic/SDL_syssem.c"
|
||||
#else
|
||||
|
||||
struct SDL_semaphore {
|
||||
sem_t sem;
|
||||
};
|
||||
|
||||
/* 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, 0, initial_value) < 0 ) {
|
||||
SDL_SetError("sem_init() failed");
|
||||
SDL_free(sem);
|
||||
sem = NULL;
|
||||
}
|
||||
} 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;
|
||||
}
|
||||
|
||||
while ( ((retval = sem_wait(&sem->sem)) == -1) && (errno == EINTR) ) {}
|
||||
if ( retval < 0 ) {
|
||||
SDL_SetError("sem_wait() failed");
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
|
||||
{
|
||||
int retval;
|
||||
#ifdef HAVE_SEM_TIMEDWAIT
|
||||
struct timeval now;
|
||||
struct timespec ts_timeout;
|
||||
#else
|
||||
Uint32 end;
|
||||
#endif
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
#ifdef HAVE_SEM_TIMEDWAIT
|
||||
/* Setup the timeout. sem_timedwait doesn't wait for
|
||||
* a lapse of time, but until we reach a certain time.
|
||||
* This time is now plus the timeout.
|
||||
*/
|
||||
gettimeofday(&now, NULL);
|
||||
|
||||
/* Add our timeout to current time */
|
||||
now.tv_usec += (timeout % 1000) * 1000;
|
||||
now.tv_sec += timeout / 1000;
|
||||
|
||||
/* Wrap the second if needed */
|
||||
if ( now.tv_usec >= 1000000 ) {
|
||||
now.tv_usec -= 1000000;
|
||||
now.tv_sec ++;
|
||||
}
|
||||
|
||||
/* Convert to timespec */
|
||||
ts_timeout.tv_sec = now.tv_sec;
|
||||
ts_timeout.tv_nsec = now.tv_usec * 1000;
|
||||
|
||||
/* Wait. */
|
||||
do
|
||||
retval = sem_timedwait(&sem->sem, &ts_timeout);
|
||||
while (retval == -1 && errno == EINTR);
|
||||
|
||||
if (retval == -1)
|
||||
SDL_SetError(strerror(errno));
|
||||
#else
|
||||
end = SDL_GetTicks() + timeout;
|
||||
while ((retval = SDL_SemTryWait(sem)) == SDL_MUTEX_TIMEDOUT) {
|
||||
if ((SDL_GetTicks() - end) >= 0) {
|
||||
break;
|
||||
}
|
||||
SDL_Delay(0);
|
||||
}
|
||||
#endif /* HAVE_SEM_TIMEDWAIT */
|
||||
|
||||
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 /* __MACOSX__ */
|
|
@ -1,120 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 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_config.h"
|
||||
|
||||
#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
|
||||
};
|
||||
|
||||
#ifdef __RISCOS__
|
||||
/* RISC OS needs to know the main thread for
|
||||
* it's timer and event processing. */
|
||||
int riscos_using_threads = 0;
|
||||
Uint32 riscos_main_thread = 0; /* Thread running events */
|
||||
#endif
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
#ifdef __RISCOS__
|
||||
if (riscos_using_threads == 0) {
|
||||
riscos_using_threads = 1;
|
||||
riscos_main_thread = SDL_ThreadID();
|
||||
}
|
||||
#endif
|
||||
|
||||
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)((size_t)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
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 Sam Lantinga
|
||||
|
||||
This 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.
|
||||
|
||||
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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Sam Lantinga
|
||||
slouken@libsdl.org
|
||||
*/
|
||||
#include "SDL_config.h"
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
typedef pthread_t SYS_ThreadHandle;
|
|
@ -1,160 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 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_config.h"
|
||||
|
||||
/* RISC OS implementations uses pthreads based on linux code */
|
||||
|
||||
#if SDL_THREADS_DISABLED
|
||||
#include "../generic/SDL_syscond.c"
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "SDL_thread.h"
|
||||
#include "SDL_sysmutex_c.h"
|
||||
|
||||
struct SDL_cond
|
||||
{
|
||||
pthread_cond_t cond;
|
||||
};
|
||||
|
||||
/* Create a condition variable */
|
||||
SDL_cond * SDL_CreateCond(void)
|
||||
{
|
||||
SDL_cond *cond;
|
||||
|
||||
cond = (SDL_cond *) SDL_malloc(sizeof(SDL_cond));
|
||||
if ( cond ) {
|
||||
if ( pthread_cond_init(&cond->cond, NULL) < 0 ) {
|
||||
SDL_SetError("pthread_cond_init() failed");
|
||||
SDL_free(cond);
|
||||
cond = NULL;
|
||||
}
|
||||
}
|
||||
return(cond);
|
||||
}
|
||||
|
||||
/* Destroy a condition variable */
|
||||
void SDL_DestroyCond(SDL_cond *cond)
|
||||
{
|
||||
if ( cond ) {
|
||||
pthread_cond_destroy(&cond->cond);
|
||||
SDL_free(cond);
|
||||
}
|
||||
}
|
||||
|
||||
/* Restart one of the threads that are waiting on the condition variable */
|
||||
int SDL_CondSignal(SDL_cond *cond)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if ( ! cond ) {
|
||||
SDL_SetError("Passed a NULL condition variable");
|
||||
return -1;
|
||||
}
|
||||
|
||||
retval = 0;
|
||||
if ( pthread_cond_signal(&cond->cond) != 0 ) {
|
||||
SDL_SetError("pthread_cond_signal() failed");
|
||||
retval = -1;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Restart all threads that are waiting on the condition variable */
|
||||
int SDL_CondBroadcast(SDL_cond *cond)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if ( ! cond ) {
|
||||
SDL_SetError("Passed a NULL condition variable");
|
||||
return -1;
|
||||
}
|
||||
|
||||
retval = 0;
|
||||
if ( pthread_cond_broadcast(&cond->cond) != 0 ) {
|
||||
SDL_SetError("pthread_cond_broadcast() failed");
|
||||
retval = -1;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
|
||||
{
|
||||
int retval;
|
||||
struct timeval delta;
|
||||
struct timespec abstime;
|
||||
|
||||
if ( ! cond ) {
|
||||
SDL_SetError("Passed a NULL condition variable");
|
||||
return -1;
|
||||
}
|
||||
|
||||
gettimeofday(&delta, NULL);
|
||||
|
||||
abstime.tv_sec = delta.tv_sec + (ms/1000);
|
||||
abstime.tv_nsec = (delta.tv_usec + (ms%1000) * 1000) * 1000;
|
||||
if ( abstime.tv_nsec > 1000000000 ) {
|
||||
abstime.tv_sec += 1;
|
||||
abstime.tv_nsec -= 1000000000;
|
||||
}
|
||||
|
||||
tryagain:
|
||||
retval = pthread_cond_timedwait(&cond->cond, &mutex->id, &abstime);
|
||||
switch (retval) {
|
||||
case EINTR:
|
||||
goto tryagain;
|
||||
break;
|
||||
case ETIMEDOUT:
|
||||
retval = SDL_MUTEX_TIMEDOUT;
|
||||
break;
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
SDL_SetError("pthread_cond_timedwait() failed");
|
||||
retval = -1;
|
||||
break;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Wait on the condition variable, unlocking the provided mutex.
|
||||
The mutex must be locked before entering this function!
|
||||
*/
|
||||
int SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if ( ! cond ) {
|
||||
SDL_SetError("Passed a NULL condition variable");
|
||||
return -1;
|
||||
}
|
||||
|
||||
retval = 0;
|
||||
if ( pthread_cond_wait(&cond->cond, &mutex->id) != 0 ) {
|
||||
SDL_SetError("pthread_cond_wait() failed");
|
||||
retval = -1;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
#endif
|
|
@ -1,153 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 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_config.h"
|
||||
|
||||
/* RISC OS implementations uses pthreads based on linux code */
|
||||
|
||||
#include "SDL_thread.h"
|
||||
|
||||
#if SDL_THREADS_DISABLED
|
||||
#include "../generic/SDL_sysmutex.c"
|
||||
#else
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
struct SDL_mutex {
|
||||
pthread_mutex_t id;
|
||||
#if SDL_THREAD_PTHREAD_NO_RECURSIVE_MUTEX
|
||||
int recursive;
|
||||
pthread_t owner;
|
||||
#endif
|
||||
};
|
||||
|
||||
SDL_mutex *SDL_CreateMutex (void)
|
||||
{
|
||||
SDL_mutex *mutex;
|
||||
pthread_mutexattr_t attr;
|
||||
|
||||
/* Allocate the structure */
|
||||
mutex = (SDL_mutex *)SDL_calloc(1, sizeof(*mutex));
|
||||
if ( mutex ) {
|
||||
pthread_mutexattr_init(&attr);
|
||||
#if SDL_THREAD_PTHREAD_NO_RECURSIVE_MUTEX
|
||||
/* No extra attributes necessary */
|
||||
#else
|
||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
|
||||
#endif /* SDL_THREAD_PTHREAD_NO_RECURSIVE_MUTEX */
|
||||
if ( pthread_mutex_init(&mutex->id, &attr) != 0 ) {
|
||||
SDL_SetError("pthread_mutex_init() failed");
|
||||
SDL_free(mutex);
|
||||
mutex = NULL;
|
||||
}
|
||||
} else {
|
||||
SDL_OutOfMemory();
|
||||
}
|
||||
return(mutex);
|
||||
}
|
||||
|
||||
void SDL_DestroyMutex(SDL_mutex *mutex)
|
||||
{
|
||||
if ( mutex ) {
|
||||
pthread_mutex_destroy(&mutex->id);
|
||||
SDL_free(mutex);
|
||||
}
|
||||
}
|
||||
|
||||
/* Lock the mutex */
|
||||
int SDL_mutexP(SDL_mutex *mutex)
|
||||
{
|
||||
int retval;
|
||||
#if SDL_THREAD_PTHREAD_NO_RECURSIVE_MUTEX
|
||||
pthread_t this_thread;
|
||||
#endif
|
||||
|
||||
if ( mutex == NULL ) {
|
||||
SDL_SetError("Passed a NULL mutex");
|
||||
return -1;
|
||||
}
|
||||
|
||||
retval = 0;
|
||||
#if SDL_THREAD_PTHREAD_NO_RECURSIVE_MUTEX
|
||||
this_thread = pthread_self();
|
||||
if ( mutex->owner == this_thread ) {
|
||||
++mutex->recursive;
|
||||
} else {
|
||||
/* The order of operations is important.
|
||||
We set the locking thread id after we obtain the lock
|
||||
so unlocks from other threads will fail.
|
||||
*/
|
||||
if ( pthread_mutex_lock(&mutex->id) == 0 ) {
|
||||
mutex->owner = this_thread;
|
||||
mutex->recursive = 0;
|
||||
} else {
|
||||
SDL_SetError("pthread_mutex_lock() failed");
|
||||
retval = -1;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if ( pthread_mutex_lock(&mutex->id) < 0 ) {
|
||||
SDL_SetError("pthread_mutex_lock() failed");
|
||||
retval = -1;
|
||||
}
|
||||
#endif
|
||||
return retval;
|
||||
}
|
||||
|
||||
int SDL_mutexV(SDL_mutex *mutex)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if ( mutex == NULL ) {
|
||||
SDL_SetError("Passed a NULL mutex");
|
||||
return -1;
|
||||
}
|
||||
|
||||
retval = 0;
|
||||
#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 ) {
|
||||
--mutex->recursive;
|
||||
} else {
|
||||
/* The order of operations is important.
|
||||
First reset the owner so another thread doesn't lock
|
||||
the mutex and set the ownership before we reset it,
|
||||
then release the lock semaphore.
|
||||
*/
|
||||
mutex->owner = 0;
|
||||
pthread_mutex_unlock(&mutex->id);
|
||||
}
|
||||
} else {
|
||||
SDL_SetError("mutex not owned by this thread");
|
||||
retval = -1;
|
||||
}
|
||||
|
||||
#else
|
||||
if ( pthread_mutex_unlock(&mutex->id) < 0 ) {
|
||||
SDL_SetError("pthread_mutex_unlock() failed");
|
||||
retval = -1;
|
||||
}
|
||||
#endif /* SDL_THREAD_PTHREAD_NO_RECURSIVE_MUTEX */
|
||||
|
||||
return retval;
|
||||
}
|
||||
#endif
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 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_config.h"
|
||||
|
||||
#ifndef _SDL_mutex_c_h
|
||||
#define _SDL_mutex_c_h
|
||||
|
||||
#if !SDL_THREADS_DISABLED
|
||||
struct SDL_mutex {
|
||||
pthread_mutex_t id;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _SDL_mutex_c_h */
|
|
@ -1,203 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 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 <errno.h>
|
||||
|
||||
#include "SDL_config.h"
|
||||
|
||||
/* RISC OS semiphores based on linux code */
|
||||
|
||||
|
||||
#include "SDL_timer.h"
|
||||
#include "SDL_thread.h"
|
||||
#include "SDL_systhread_c.h"
|
||||
|
||||
#if !SDL_THREADS_DISABLED
|
||||
|
||||
SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
|
||||
{
|
||||
SDL_SetError("SDL not configured with thread support");
|
||||
return (SDL_sem *)0;
|
||||
}
|
||||
|
||||
void SDL_DestroySemaphore(SDL_sem *sem)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int SDL_SemTryWait(SDL_sem *sem)
|
||||
{
|
||||
SDL_SetError("SDL not configured with thread support");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
|
||||
{
|
||||
SDL_SetError("SDL not configured with thread support");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int SDL_SemWait(SDL_sem *sem)
|
||||
{
|
||||
SDL_SetError("SDL not configured with thread support");
|
||||
return -1;
|
||||
}
|
||||
|
||||
Uint32 SDL_SemValue(SDL_sem *sem)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SDL_SemPost(SDL_sem *sem)
|
||||
{
|
||||
SDL_SetError("SDL not configured with thread support");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
|
||||
#include <unistd.h> /* For getpid() */
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
while ( ((retval = sem_wait(sem->sem)) == -1) && (errno == EINTR) ) {}
|
||||
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 /* !SDL_THREADS_DISABLED */
|
|
@ -1,144 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 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_config.h"
|
||||
|
||||
/* RISC OS version based on pthreads linux source */
|
||||
|
||||
#include "SDL_thread.h"
|
||||
#include "../SDL_systhread.h"
|
||||
|
||||
#if SDL_THREADS_DISABLED
|
||||
|
||||
int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
|
||||
{
|
||||
SDL_SetError("Threads have not been compiled into this version of the library");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
void SDL_SYS_SetupThread(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Uint32 SDL_ThreadID(void)
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
int riscos_using_threads = 0;
|
||||
Uint32 riscos_main_thread = 0; /* Thread running events */
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (riscos_using_threads == 0)
|
||||
{
|
||||
riscos_using_threads = 1;
|
||||
riscos_main_thread = SDL_ThreadID();
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
pthread_kill(thread->handle, SIGKILL);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 Sam Lantinga
|
||||
|
||||
This 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.
|
||||
|
||||
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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Sam Lantinga
|
||||
slouken@libsdl.org
|
||||
*/
|
||||
#include "SDL_config.h"
|
||||
|
||||
#if SDL_THREADS_DISABLED
|
||||
|
||||
typedef int SYS_ThreadHandle;
|
||||
|
||||
#else
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
typedef pthread_t SYS_ThreadHandle;
|
||||
|
||||
#endif
|
|
@ -1,130 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 Sam Lantinga
|
||||
|
||||
This 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.
|
||||
|
||||
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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Sam Lantinga
|
||||
slouken@devolution.com
|
||||
*/
|
||||
|
||||
/*
|
||||
SDL_sysmutex.cpp
|
||||
|
||||
Epoc version by Markus Mertama (w@iki.fi)
|
||||
*/
|
||||
|
||||
|
||||
#ifdef SAVE_RCSID
|
||||
static char rcsid =
|
||||
"@(#) $Id: SDL_sysmutex.c,v 1.1.2.3 2000/06/22 15:25:23 hercules Exp $";
|
||||
#endif
|
||||
|
||||
/* Mutex functions using the Win32 API */
|
||||
|
||||
//#include <stdio.h>
|
||||
//#include <stdlib.h>
|
||||
|
||||
#include <e32std.h>
|
||||
|
||||
#include "epoc_sdl.h"
|
||||
|
||||
#include "SDL_error.h"
|
||||
#include "SDL_mutex.h"
|
||||
|
||||
|
||||
#ifdef EKA2 //???
|
||||
struct SDL_mutex
|
||||
{
|
||||
TInt handle;
|
||||
};
|
||||
#else
|
||||
struct _SDL_mutex
|
||||
{
|
||||
TInt handle;
|
||||
};
|
||||
#endif
|
||||
|
||||
extern TInt CreateUnique(TInt (*aFunc)(const TDesC& aName, TAny*, TAny*), TAny*, TAny*);
|
||||
|
||||
TInt NewMutex(const TDesC& aName, TAny* aPtr1, TAny*)
|
||||
{
|
||||
return ((RMutex*)aPtr1)->CreateGlobal(aName);
|
||||
}
|
||||
|
||||
void DeleteMutex(TAny* aMutex)
|
||||
{
|
||||
SDL_DestroyMutex ((SDL_mutex*) aMutex);
|
||||
}
|
||||
|
||||
/* Create a mutex */
|
||||
SDL_mutex *SDL_CreateMutex(void)
|
||||
{
|
||||
RMutex rmutex;
|
||||
|
||||
TInt status = CreateUnique(NewMutex, &rmutex, NULL);
|
||||
if(status != KErrNone)
|
||||
{
|
||||
SDL_SetError("Couldn't create mutex");
|
||||
}
|
||||
SDL_mutex* mutex = new /*(ELeave)*/ SDL_mutex;
|
||||
mutex->handle = rmutex.Handle();
|
||||
EpocSdlEnv::AppendCleanupItem(TSdlCleanupItem(DeleteMutex, mutex));
|
||||
return(mutex);
|
||||
}
|
||||
|
||||
/* Free the mutex */
|
||||
void SDL_DestroyMutex(SDL_mutex *mutex)
|
||||
{
|
||||
if ( mutex )
|
||||
{
|
||||
RMutex rmutex;
|
||||
rmutex.SetHandle(mutex->handle);
|
||||
if(rmutex.IsHeld())
|
||||
{
|
||||
rmutex.Signal();
|
||||
}
|
||||
rmutex.Close();
|
||||
EpocSdlEnv::RemoveCleanupItem(mutex);
|
||||
delete(mutex);
|
||||
mutex = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Lock the mutex */
|
||||
int SDL_mutexP(SDL_mutex *mutex)
|
||||
{
|
||||
if ( mutex == NULL ) {
|
||||
SDL_SetError("Passed a NULL mutex");
|
||||
return -1;
|
||||
}
|
||||
RMutex rmutex;
|
||||
rmutex.SetHandle(mutex->handle);
|
||||
rmutex.Wait();
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Unlock the mutex */
|
||||
int SDL_mutexV(SDL_mutex *mutex)
|
||||
{
|
||||
if ( mutex == NULL ) {
|
||||
SDL_SetError("Passed a NULL mutex");
|
||||
return -1;
|
||||
}
|
||||
RMutex rmutex;
|
||||
rmutex.SetHandle(mutex->handle);
|
||||
rmutex.Signal();
|
||||
return(0);
|
||||
}
|
|
@ -1,214 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 Sam Lantinga
|
||||
|
||||
This 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.
|
||||
|
||||
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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Sam Lantinga
|
||||
slouken@devolution.com
|
||||
*/
|
||||
|
||||
/*
|
||||
SDL_syssem.cpp
|
||||
|
||||
Epoc version by Markus Mertama (w@iki.fi)
|
||||
*/
|
||||
|
||||
#ifdef SAVE_RCSID
|
||||
static char rcsid =
|
||||
"@(#) $Id: SDL_syssem.c,v 1.1.2.4 2000/06/22 15:24:48 hercules Exp $";
|
||||
#endif
|
||||
|
||||
/* Semaphore functions using the Win32 API */
|
||||
|
||||
//#include <stdio.h>
|
||||
//#include <stdlib.h>
|
||||
#include <e32std.h>
|
||||
|
||||
#include "SDL_error.h"
|
||||
#include "SDL_thread.h"
|
||||
|
||||
|
||||
#define SDL_MUTEX_TIMEOUT -2
|
||||
|
||||
struct SDL_semaphore
|
||||
{
|
||||
TInt handle;
|
||||
TInt count;
|
||||
};
|
||||
|
||||
|
||||
extern TInt CreateUnique(TInt (*aFunc)(const TDesC& aName, TAny*, TAny*), TAny*, TAny*);
|
||||
#ifndef EKA2
|
||||
extern TInt NewThread(const TDesC& aName, TAny* aPtr1, TAny* aPtr2);
|
||||
#endif
|
||||
|
||||
TInt NewSema(const TDesC& aName, TAny* aPtr1, TAny* aPtr2)
|
||||
{
|
||||
TInt value = *((TInt*) aPtr2);
|
||||
return ((RSemaphore*)aPtr1)->CreateGlobal(aName, value);
|
||||
}
|
||||
|
||||
/* Create a semaphore */
|
||||
SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
|
||||
{
|
||||
RSemaphore s;
|
||||
TInt status = CreateUnique(NewSema, &s, &initial_value);
|
||||
if(status != KErrNone)
|
||||
{
|
||||
SDL_SetError("Couldn't create semaphore");
|
||||
}
|
||||
SDL_semaphore* sem = new /*(ELeave)*/ SDL_semaphore;
|
||||
sem->handle = s.Handle();
|
||||
sem->count = initial_value;
|
||||
return(sem);
|
||||
}
|
||||
|
||||
/* Free the semaphore */
|
||||
void SDL_DestroySemaphore(SDL_sem *sem)
|
||||
{
|
||||
if ( sem )
|
||||
{
|
||||
RSemaphore sema;
|
||||
sema.SetHandle(sem->handle);
|
||||
while(--sem->count)
|
||||
sema.Signal();
|
||||
sema.Close();
|
||||
delete sem;
|
||||
sem = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef EKA2
|
||||
|
||||
struct TInfo
|
||||
{
|
||||
TInfo(TInt aTime, TInt aHandle) :
|
||||
iTime(aTime), iHandle(aHandle), iVal(0) {}
|
||||
TInt iTime;
|
||||
TInt iHandle;
|
||||
TInt iVal;
|
||||
};
|
||||
|
||||
|
||||
|
||||
TBool ThreadRun(TAny* aInfo)
|
||||
{
|
||||
TInfo* info = STATIC_CAST(TInfo*, aInfo);
|
||||
User::After(info->iTime);
|
||||
RSemaphore sema;
|
||||
sema.SetHandle(info->iHandle);
|
||||
sema.Signal();
|
||||
info->iVal = SDL_MUTEX_TIMEOUT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
void _WaitAll(SDL_sem *sem)
|
||||
{
|
||||
//since SemTryWait may changed the counter.
|
||||
//this may not be atomic, but hopes it works.
|
||||
RSemaphore sema;
|
||||
sema.SetHandle(sem->handle);
|
||||
sema.Wait();
|
||||
while(sem->count < 0)
|
||||
{
|
||||
sema.Wait();
|
||||
}
|
||||
}
|
||||
|
||||
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
|
||||
{
|
||||
if ( ! sem ) {
|
||||
SDL_SetError("Passed a NULL sem");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( timeout == SDL_MUTEX_MAXWAIT )
|
||||
{
|
||||
_WaitAll(sem);
|
||||
return SDL_MUTEX_MAXWAIT;
|
||||
}
|
||||
|
||||
#ifdef EKA2
|
||||
|
||||
RSemaphore sema;
|
||||
sema.SetHandle(sem->handle);
|
||||
if(KErrNone == sema.Wait(timeout))
|
||||
return 0;
|
||||
return -1;
|
||||
#else
|
||||
RThread thread;
|
||||
|
||||
TInfo* info = new (ELeave)TInfo(timeout, sem->handle);
|
||||
|
||||
TInt status = CreateUnique(NewThread, &thread, info);
|
||||
|
||||
if(status != KErrNone)
|
||||
return status;
|
||||
|
||||
thread.Resume();
|
||||
|
||||
_WaitAll(sem);
|
||||
|
||||
if(thread.ExitType() == EExitPending)
|
||||
{
|
||||
thread.Kill(SDL_MUTEX_TIMEOUT);
|
||||
}
|
||||
|
||||
thread.Close();
|
||||
|
||||
return info->iVal;
|
||||
#endif
|
||||
}
|
||||
|
||||
int SDL_SemTryWait(SDL_sem *sem)
|
||||
{
|
||||
if(sem->count > 0)
|
||||
{
|
||||
sem->count--;
|
||||
}
|
||||
return SDL_MUTEX_TIMEOUT;
|
||||
}
|
||||
|
||||
int SDL_SemWait(SDL_sem *sem)
|
||||
{
|
||||
return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
|
||||
}
|
||||
|
||||
/* Returns the current count of the semaphore */
|
||||
Uint32 SDL_SemValue(SDL_sem *sem)
|
||||
{
|
||||
if ( ! sem ) {
|
||||
SDL_SetError("Passed a NULL sem");
|
||||
return 0;
|
||||
}
|
||||
return sem->count;
|
||||
}
|
||||
|
||||
int SDL_SemPost(SDL_sem *sem)
|
||||
{
|
||||
if ( ! sem ) {
|
||||
SDL_SetError("Passed a NULL sem");
|
||||
return -1;
|
||||
}
|
||||
sem->count++;
|
||||
RSemaphore sema;
|
||||
sema.SetHandle(sem->handle);
|
||||
sema.Signal();
|
||||
return 0;
|
||||
}
|
|
@ -1,146 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 Sam Lantinga
|
||||
|
||||
This 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.
|
||||
|
||||
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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Sam Lantinga
|
||||
slouken@devolution.com
|
||||
*/
|
||||
|
||||
/*
|
||||
SDL_systhread.cpp
|
||||
Epoc thread management routines for SDL
|
||||
|
||||
Epoc version by Markus Mertama (w@iki.fi)
|
||||
*/
|
||||
|
||||
#include "epoc_sdl.h"
|
||||
|
||||
//#include <stdlib.h>
|
||||
//#include <stdio.h>
|
||||
|
||||
|
||||
|
||||
extern "C" {
|
||||
#undef NULL
|
||||
#include "SDL_error.h"
|
||||
#include "SDL_thread.h"
|
||||
#include "SDL_systhread.h"
|
||||
#include "SDL_thread_c.h"
|
||||
}
|
||||
|
||||
#include <e32std.h>
|
||||
#include "epoc_sdl.h"
|
||||
|
||||
|
||||
static int object_count;
|
||||
|
||||
int RunThread(TAny* data)
|
||||
{
|
||||
CTrapCleanup* cleanup = CTrapCleanup::New();
|
||||
TRAPD(err, SDL_RunThread(data));
|
||||
EpocSdlEnv::CleanupItems();
|
||||
delete cleanup;
|
||||
return(err);
|
||||
}
|
||||
|
||||
|
||||
TInt NewThread(const TDesC& aName, TAny* aPtr1, TAny* aPtr2)
|
||||
{
|
||||
return ((RThread*)(aPtr1))->Create(aName,
|
||||
RunThread,
|
||||
KDefaultStackSize,
|
||||
NULL,
|
||||
aPtr2);
|
||||
}
|
||||
|
||||
int CreateUnique(TInt (*aFunc)(const TDesC& aName, TAny*, TAny*), TAny* aPtr1, TAny* aPtr2)
|
||||
{
|
||||
TBuf<16> name;
|
||||
TInt status = KErrNone;
|
||||
do
|
||||
{
|
||||
object_count++;
|
||||
name.Format(_L("SDL_%x"), object_count);
|
||||
status = aFunc(name, aPtr1, aPtr2);
|
||||
}
|
||||
while(status == KErrAlreadyExists);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
|
||||
{
|
||||
RThread rthread;
|
||||
|
||||
const TInt status = CreateUnique(NewThread, &rthread, args);
|
||||
if (status != KErrNone)
|
||||
{
|
||||
delete(((RThread*)(thread->handle)));
|
||||
thread->handle = NULL;
|
||||
SDL_SetError("Not enough resources to create thread");
|
||||
return(-1);
|
||||
}
|
||||
rthread.Resume();
|
||||
thread->handle = rthread.Handle();
|
||||
return(0);
|
||||
}
|
||||
|
||||
void SDL_SYS_SetupThread(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Uint32 SDL_ThreadID(void)
|
||||
{
|
||||
RThread current;
|
||||
const TThreadId id = current.Id();
|
||||
return id;
|
||||
}
|
||||
|
||||
void SDL_SYS_WaitThread(SDL_Thread *thread)
|
||||
{
|
||||
SDL_TRACE1("Close thread", thread);
|
||||
RThread t;
|
||||
const TInt err = t.Open(thread->threadid);
|
||||
if(err == KErrNone && t.ExitType() == EExitPending)
|
||||
{
|
||||
TRequestStatus status;
|
||||
t.Logon(status);
|
||||
User::WaitForRequest(status);
|
||||
}
|
||||
t.Close();
|
||||
|
||||
/* RUndertaker taker;
|
||||
taker.Create();
|
||||
TRequestStatus status;
|
||||
taker.Logon(status, thread->handle);
|
||||
User::WaitForRequest(status);
|
||||
taker.Close();*/
|
||||
SDL_TRACE1("Closed thread", thread);
|
||||
}
|
||||
|
||||
/* WARNING: This function is really a last resort.
|
||||
* Threads should be signaled and then exit by themselves.
|
||||
* TerminateThread() doesn't perform stack and DLL cleanup.
|
||||
*/
|
||||
void SDL_SYS_KillThread(SDL_Thread *thread)
|
||||
{
|
||||
RThread rthread;
|
||||
rthread.SetHandle(thread->handle);
|
||||
rthread.Kill(0);
|
||||
rthread.Close();
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 Sam Lantinga
|
||||
|
||||
This 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.
|
||||
|
||||
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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Sam Lantinga
|
||||
slouken@devolution.com
|
||||
*/
|
||||
|
||||
/*
|
||||
SDL_systhread_c.h
|
||||
|
||||
Epoc version by Markus Mertama (w@iki.fi)
|
||||
*/
|
||||
|
||||
typedef int SYS_ThreadHandle;
|
||||
|
|
@ -1,95 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 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_config.h"
|
||||
|
||||
/* Mutex functions using the Win32 API */
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
#include "SDL_mutex.h"
|
||||
|
||||
|
||||
struct SDL_mutex {
|
||||
HANDLE id;
|
||||
};
|
||||
|
||||
/* Create a mutex */
|
||||
SDL_mutex *SDL_CreateMutex(void)
|
||||
{
|
||||
SDL_mutex *mutex;
|
||||
|
||||
/* Allocate mutex memory */
|
||||
mutex = (SDL_mutex *)SDL_malloc(sizeof(*mutex));
|
||||
if ( mutex ) {
|
||||
/* Create the mutex, with initial value signaled */
|
||||
mutex->id = CreateMutex(NULL, FALSE, NULL);
|
||||
if ( ! mutex->id ) {
|
||||
SDL_SetError("Couldn't create mutex");
|
||||
SDL_free(mutex);
|
||||
mutex = NULL;
|
||||
}
|
||||
} else {
|
||||
SDL_OutOfMemory();
|
||||
}
|
||||
return(mutex);
|
||||
}
|
||||
|
||||
/* Free the mutex */
|
||||
void SDL_DestroyMutex(SDL_mutex *mutex)
|
||||
{
|
||||
if ( mutex ) {
|
||||
if ( mutex->id ) {
|
||||
CloseHandle(mutex->id);
|
||||
mutex->id = 0;
|
||||
}
|
||||
SDL_free(mutex);
|
||||
}
|
||||
}
|
||||
|
||||
/* Lock the mutex */
|
||||
int SDL_mutexP(SDL_mutex *mutex)
|
||||
{
|
||||
if ( mutex == NULL ) {
|
||||
SDL_SetError("Passed a NULL mutex");
|
||||
return -1;
|
||||
}
|
||||
if ( WaitForSingleObject(mutex->id, INFINITE) == WAIT_FAILED ) {
|
||||
SDL_SetError("Couldn't wait on mutex");
|
||||
return -1;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Unlock the mutex */
|
||||
int SDL_mutexV(SDL_mutex *mutex)
|
||||
{
|
||||
if ( mutex == NULL ) {
|
||||
SDL_SetError("Passed a NULL mutex");
|
||||
return -1;
|
||||
}
|
||||
if ( ReleaseMutex(mutex->id) == FALSE ) {
|
||||
SDL_SetError("Couldn't release mutex");
|
||||
return -1;
|
||||
}
|
||||
return(0);
|
||||
}
|
|
@ -1,164 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 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_config.h"
|
||||
|
||||
/* Semaphore functions using the Win32 API */
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
#include "SDL_thread.h"
|
||||
#if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
|
||||
#include "win_ce_semaphore.h"
|
||||
#endif
|
||||
|
||||
|
||||
struct SDL_semaphore {
|
||||
#if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
|
||||
SYNCHHANDLE id;
|
||||
#else
|
||||
HANDLE id;
|
||||
#endif
|
||||
volatile LONG count;
|
||||
};
|
||||
|
||||
|
||||
/* Create a semaphore */
|
||||
SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
|
||||
{
|
||||
SDL_sem *sem;
|
||||
|
||||
/* Allocate sem memory */
|
||||
sem = (SDL_sem *)SDL_malloc(sizeof(*sem));
|
||||
if ( sem ) {
|
||||
/* Create the semaphore, with max value 32K */
|
||||
#if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
|
||||
sem->id = CreateSemaphoreCE(NULL, initial_value, 32*1024, NULL);
|
||||
#else
|
||||
sem->id = CreateSemaphore(NULL, initial_value, 32*1024, NULL);
|
||||
#endif
|
||||
sem->count = (LONG) initial_value;
|
||||
if ( ! sem->id ) {
|
||||
SDL_SetError("Couldn't create semaphore");
|
||||
SDL_free(sem);
|
||||
sem = NULL;
|
||||
}
|
||||
} else {
|
||||
SDL_OutOfMemory();
|
||||
}
|
||||
return(sem);
|
||||
}
|
||||
|
||||
/* Free the semaphore */
|
||||
void SDL_DestroySemaphore(SDL_sem *sem)
|
||||
{
|
||||
if ( sem ) {
|
||||
if ( sem->id ) {
|
||||
#if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
|
||||
CloseSynchHandle(sem->id);
|
||||
#else
|
||||
CloseHandle(sem->id);
|
||||
#endif
|
||||
sem->id = 0;
|
||||
}
|
||||
SDL_free(sem);
|
||||
}
|
||||
}
|
||||
|
||||
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
|
||||
{
|
||||
int retval;
|
||||
DWORD dwMilliseconds;
|
||||
|
||||
if ( ! sem ) {
|
||||
SDL_SetError("Passed a NULL sem");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( timeout == SDL_MUTEX_MAXWAIT ) {
|
||||
dwMilliseconds = INFINITE;
|
||||
} else {
|
||||
dwMilliseconds = (DWORD)timeout;
|
||||
}
|
||||
#if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
|
||||
switch (WaitForSemaphoreCE(sem->id, dwMilliseconds)) {
|
||||
#else
|
||||
switch (WaitForSingleObject(sem->id, dwMilliseconds)) {
|
||||
#endif
|
||||
case WAIT_OBJECT_0:
|
||||
InterlockedDecrement(&sem->count);
|
||||
retval = 0;
|
||||
break;
|
||||
case WAIT_TIMEOUT:
|
||||
retval = SDL_MUTEX_TIMEDOUT;
|
||||
break;
|
||||
default:
|
||||
SDL_SetError("WaitForSingleObject() failed");
|
||||
retval = -1;
|
||||
break;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
int SDL_SemTryWait(SDL_sem *sem)
|
||||
{
|
||||
return SDL_SemWaitTimeout(sem, 0);
|
||||
}
|
||||
|
||||
int SDL_SemWait(SDL_sem *sem)
|
||||
{
|
||||
return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
|
||||
}
|
||||
|
||||
/* Returns the current count of the semaphore */
|
||||
Uint32 SDL_SemValue(SDL_sem *sem)
|
||||
{
|
||||
if ( ! sem ) {
|
||||
SDL_SetError("Passed a NULL sem");
|
||||
return 0;
|
||||
}
|
||||
return (Uint32) sem->count;
|
||||
}
|
||||
|
||||
int SDL_SemPost(SDL_sem *sem)
|
||||
{
|
||||
if ( ! sem ) {
|
||||
SDL_SetError("Passed a NULL sem");
|
||||
return -1;
|
||||
}
|
||||
/* Increase the counter in the first place, because
|
||||
* after a successful release the semaphore may
|
||||
* immediately get destroyed by another thread which
|
||||
* is waiting for this semaphore.
|
||||
*/
|
||||
InterlockedIncrement(&sem->count);
|
||||
#if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
|
||||
if ( ReleaseSemaphoreCE(sem->id, 1, NULL) == FALSE ) {
|
||||
#else
|
||||
if ( ReleaseSemaphore(sem->id, 1, NULL) == FALSE ) {
|
||||
#endif
|
||||
InterlockedDecrement(&sem->count); /* restore */
|
||||
SDL_SetError("ReleaseSemaphore() failed");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -1,162 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 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_config.h"
|
||||
|
||||
/* Win32 thread management routines for SDL */
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
#include "SDL_thread.h"
|
||||
#include "../SDL_thread_c.h"
|
||||
#include "../SDL_systhread.h"
|
||||
|
||||
#ifndef SDL_PASSED_BEGINTHREAD_ENDTHREAD
|
||||
#ifndef _WIN32_WCE
|
||||
/* We'll use the C library from this DLL */
|
||||
#include <process.h>
|
||||
#endif
|
||||
|
||||
#if defined(__WATCOMC__)
|
||||
/* This is for Watcom targets except OS2 */
|
||||
#if __WATCOMC__ < 1240
|
||||
#define __watcall
|
||||
#endif
|
||||
typedef unsigned long (__watcall *pfnSDL_CurrentBeginThread) (void *, unsigned,
|
||||
unsigned (__stdcall *func)(void *), void *arg,
|
||||
unsigned, unsigned *threadID);
|
||||
typedef void (__watcall *pfnSDL_CurrentEndThread)(unsigned code);
|
||||
#elif (defined(__MINGW32__) && (__GNUC__ < 4))
|
||||
typedef unsigned long (__cdecl *pfnSDL_CurrentBeginThread) (void *, unsigned,
|
||||
unsigned (__stdcall *func)(void *), void *arg,
|
||||
unsigned, unsigned *threadID);
|
||||
typedef void (__cdecl *pfnSDL_CurrentEndThread)(unsigned code);
|
||||
#else
|
||||
typedef uintptr_t (__cdecl *pfnSDL_CurrentBeginThread) (void *, unsigned,
|
||||
unsigned (__stdcall *func)(void *), void *arg,
|
||||
unsigned, unsigned *threadID);
|
||||
typedef void (__cdecl *pfnSDL_CurrentEndThread)(unsigned code);
|
||||
#endif
|
||||
#endif /* !SDL_PASSED_BEGINTHREAD_ENDTHREAD */
|
||||
|
||||
|
||||
typedef struct ThreadStartParms
|
||||
{
|
||||
void *args;
|
||||
pfnSDL_CurrentEndThread pfnCurrentEndThread;
|
||||
} tThreadStartParms, *pThreadStartParms;
|
||||
|
||||
static DWORD RunThread(void *data)
|
||||
{
|
||||
pThreadStartParms pThreadParms = (pThreadStartParms)data;
|
||||
pfnSDL_CurrentEndThread pfnCurrentEndThread = NULL;
|
||||
|
||||
// Call the thread function!
|
||||
SDL_RunThread(pThreadParms->args);
|
||||
|
||||
// Get the current endthread we have to use!
|
||||
if (pThreadParms)
|
||||
{
|
||||
pfnCurrentEndThread = pThreadParms->pfnCurrentEndThread;
|
||||
SDL_free(pThreadParms);
|
||||
}
|
||||
// Call endthread!
|
||||
if (pfnCurrentEndThread)
|
||||
(*pfnCurrentEndThread)(0);
|
||||
return(0);
|
||||
}
|
||||
|
||||
static DWORD WINAPI RunThreadViaCreateThread(LPVOID data)
|
||||
{
|
||||
return RunThread(data);
|
||||
}
|
||||
|
||||
static unsigned __stdcall RunThreadViaBeginThreadEx(void *data)
|
||||
{
|
||||
return (unsigned) RunThread(data);
|
||||
}
|
||||
|
||||
#ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD
|
||||
int SDL_SYS_CreateThread(SDL_Thread *thread, void *args, pfnSDL_CurrentBeginThread pfnBeginThread, pfnSDL_CurrentEndThread pfnEndThread)
|
||||
{
|
||||
#else
|
||||
int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
|
||||
{
|
||||
#ifdef _WIN32_WCE
|
||||
pfnSDL_CurrentBeginThread pfnBeginThread = NULL;
|
||||
pfnSDL_CurrentEndThread pfnEndThread = NULL;
|
||||
#else
|
||||
pfnSDL_CurrentBeginThread pfnBeginThread = _beginthreadex;
|
||||
pfnSDL_CurrentEndThread pfnEndThread = _endthreadex;
|
||||
#endif
|
||||
#endif /* SDL_PASSED_BEGINTHREAD_ENDTHREAD */
|
||||
pThreadStartParms pThreadParms = (pThreadStartParms)SDL_malloc(sizeof(tThreadStartParms));
|
||||
if (!pThreadParms) {
|
||||
SDL_OutOfMemory();
|
||||
return(-1);
|
||||
}
|
||||
|
||||
// Save the function which we will have to call to clear the RTL of calling app!
|
||||
pThreadParms->pfnCurrentEndThread = pfnEndThread;
|
||||
// Also save the real parameters we have to pass to thread function
|
||||
pThreadParms->args = args;
|
||||
|
||||
if (pfnBeginThread) {
|
||||
unsigned threadid = 0;
|
||||
thread->handle = (SYS_ThreadHandle)
|
||||
((size_t) pfnBeginThread(NULL, 0, RunThreadViaBeginThreadEx,
|
||||
pThreadParms, 0, &threadid));
|
||||
} else {
|
||||
DWORD threadid = 0;
|
||||
thread->handle = CreateThread(NULL, 0, RunThreadViaCreateThread, pThreadParms, 0, &threadid);
|
||||
}
|
||||
if (thread->handle == NULL) {
|
||||
SDL_SetError("Not enough resources to create thread");
|
||||
return(-1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
void SDL_SYS_SetupThread(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Uint32 SDL_ThreadID(void)
|
||||
{
|
||||
return((Uint32)GetCurrentThreadId());
|
||||
}
|
||||
|
||||
void SDL_SYS_WaitThread(SDL_Thread *thread)
|
||||
{
|
||||
WaitForSingleObject(thread->handle, INFINITE);
|
||||
CloseHandle(thread->handle);
|
||||
}
|
||||
|
||||
/* WARNING: This function is really a last resort.
|
||||
* Threads should be signaled and then exit by themselves.
|
||||
* TerminateThread() doesn't perform stack and DLL cleanup.
|
||||
*/
|
||||
void SDL_SYS_KillThread(SDL_Thread *thread)
|
||||
{
|
||||
TerminateThread(thread->handle, FALSE);
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2012 Sam Lantinga
|
||||
|
||||
This 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.
|
||||
|
||||
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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Sam Lantinga
|
||||
slouken@libsdl.org
|
||||
*/
|
||||
#include "SDL_config.h"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
typedef HANDLE SYS_ThreadHandle;
|
||||
|
|
@ -1,216 +0,0 @@
|
|||
/* win_ce_semaphore.c
|
||||
|
||||
Copyright (c) 1998, Johnson M. Hart
|
||||
(with corrections 2001 by Rainer Loritz)
|
||||
Permission is granted for any and all use providing that this
|
||||
copyright is properly acknowledged.
|
||||
There are no assurances of suitability for any use whatsoever.
|
||||
|
||||
WINDOWS CE: There is a collection of Windows CE functions to simulate
|
||||
semaphores using only a mutex and an event. As Windows CE events cannot
|
||||
be named, these simulated semaphores cannot be named either.
|
||||
|
||||
Implementation notes:
|
||||
1. All required internal data structures are allocated on the process's heap.
|
||||
2. Where appropriate, a new error code is returned (see the header
|
||||
file), or, if the error is a Win32 error, that code is unchanged.
|
||||
3. Notice the new handle type "SYNCHHANDLE" that has handles, counters,
|
||||
and other information. This structure will grow as new objects are added
|
||||
to this set; some members are specific to only one or two of the objects.
|
||||
4. Mutexes are used for critical sections. These could be replaced with
|
||||
CRITICAL_SECTION objects but then this would give up the time out
|
||||
capability.
|
||||
5. The implementation shows several interesting aspects of synchronization, some
|
||||
of which are specific to Win32 and some of which are general. These are pointed
|
||||
out in the comments as appropriate.
|
||||
6. The wait function emulates WaitForSingleObject only. An emulation of
|
||||
WaitForMultipleObjects is much harder to implement outside the kernel,
|
||||
and it is not clear how to handle a mixture of WCE semaphores and normal
|
||||
events and mutexes. */
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
#include "win_ce_semaphore.h"
|
||||
|
||||
static SYNCHHANDLE CleanUp (SYNCHHANDLE hSynch, DWORD Flags);
|
||||
|
||||
SYNCHHANDLE CreateSemaphoreCE (
|
||||
|
||||
LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, /* pointer to security attributes */
|
||||
LONG lInitialCount, /* initial count */
|
||||
LONG lMaximumCount, /* maximum count */
|
||||
LPCTSTR lpName )
|
||||
|
||||
/* Semaphore for use with Windows CE that does not support them directly.
|
||||
Requires a counter, a mutex to protect the counter, and an
|
||||
autoreset event.
|
||||
|
||||
Here are the rules that must always hold between the autoreset event
|
||||
and the mutex (any violation of these rules by the CE semaphore functions
|
||||
will, in all likelihood, result in a defect):
|
||||
1. No thread can set, pulse, or reset the event,
|
||||
nor can it access any part of the SYNCHHANDLE structure,
|
||||
without first gaining ownership of the mutex.
|
||||
BUT, a thread can wait on the event without owning the mutex
|
||||
(this is clearly necessary or else the event could never be set).
|
||||
2. The event is in a signaled state if and only if the current semaphore
|
||||
count ("CurCount") is greater than zero.
|
||||
3. The semaphore count is always >= 0 and <= the maximum count */
|
||||
|
||||
{
|
||||
SYNCHHANDLE hSynch = NULL, result = NULL;
|
||||
|
||||
__try
|
||||
{
|
||||
if (lInitialCount > lMaximumCount || lMaximumCount < 0 || lInitialCount < 0)
|
||||
{
|
||||
/* Bad parameters */
|
||||
SetLastError (SYNCH_ERROR);
|
||||
__leave;
|
||||
}
|
||||
|
||||
hSynch = HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY, SYNCH_HANDLE_SIZE);
|
||||
if (hSynch == NULL) __leave;
|
||||
|
||||
hSynch->MaxCount = lMaximumCount;
|
||||
hSynch->CurCount = lInitialCount;
|
||||
hSynch->lpName = lpName;
|
||||
|
||||
hSynch->hMutex = CreateMutex (lpSemaphoreAttributes, FALSE, NULL);
|
||||
|
||||
WaitForSingleObject (hSynch->hMutex, INFINITE);
|
||||
/* Create the event. It is initially signaled if and only if the
|
||||
initial count is > 0 */
|
||||
hSynch->hEvent = CreateEvent (lpSemaphoreAttributes, FALSE,
|
||||
lInitialCount > 0, NULL);
|
||||
ReleaseMutex (hSynch->hMutex);
|
||||
hSynch->hSemph = NULL;
|
||||
}
|
||||
__finally
|
||||
{
|
||||
/* Return with the handle, or, if there was any error, return
|
||||
a null after closing any open handles and freeing any allocated memory. */
|
||||
result=CleanUp(hSynch, 6 /* An event and a mutex, but no semaphore. */);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOL ReleaseSemaphoreCE (SYNCHHANDLE hSemCE, LONG cReleaseCount, LPLONG lpPreviousCount)
|
||||
/* Windows CE equivalent to ReleaseSemaphore. */
|
||||
{
|
||||
BOOL Result = TRUE;
|
||||
|
||||
/* Gain access to the object to assure that the release count
|
||||
would not cause the total count to exceed the maximum. */
|
||||
|
||||
__try
|
||||
{
|
||||
WaitForSingleObject (hSemCE->hMutex, INFINITE);
|
||||
/* reply only if asked to */
|
||||
if (lpPreviousCount!=NULL)
|
||||
*lpPreviousCount = hSemCE->CurCount;
|
||||
if (hSemCE->CurCount + cReleaseCount > hSemCE->MaxCount || cReleaseCount <= 0)
|
||||
{
|
||||
SetLastError (SYNCH_ERROR);
|
||||
Result = FALSE;
|
||||
__leave;
|
||||
}
|
||||
hSemCE->CurCount += cReleaseCount;
|
||||
|
||||
/* Set the autoreset event, releasing exactly one waiting thread, now or
|
||||
in the future. */
|
||||
|
||||
SetEvent (hSemCE->hEvent);
|
||||
}
|
||||
__finally
|
||||
{
|
||||
ReleaseMutex (hSemCE->hMutex);
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
DWORD WaitForSemaphoreCE (SYNCHHANDLE hSemCE, DWORD dwMilliseconds)
|
||||
/* Windows CE semaphore equivalent of WaitForSingleObject. */
|
||||
{
|
||||
DWORD WaitResult;
|
||||
|
||||
WaitResult = WaitForSingleObject (hSemCE->hMutex, dwMilliseconds);
|
||||
if (WaitResult != WAIT_OBJECT_0 && WaitResult != WAIT_ABANDONED_0) return WaitResult;
|
||||
while (hSemCE->CurCount <= 0)
|
||||
{
|
||||
|
||||
/* The count is 0, and the thread must wait on the event (which, by
|
||||
the rules, is currently reset) for semaphore resources to become
|
||||
available. First, of course, the mutex must be released so that another
|
||||
thread will be capable of setting the event. */
|
||||
|
||||
ReleaseMutex (hSemCE->hMutex);
|
||||
|
||||
/* Wait for the event to be signaled, indicating a semaphore state change.
|
||||
The event is autoreset and signaled with a SetEvent (not PulseEvent)
|
||||
so exactly one waiting thread (whether or not there is currently
|
||||
a waiting thread) is released as a result of the SetEvent. */
|
||||
|
||||
WaitResult = WaitForSingleObject (hSemCE->hEvent, dwMilliseconds);
|
||||
if (WaitResult != WAIT_OBJECT_0) return WaitResult;
|
||||
|
||||
/* This is where the properties of setting of an autoreset event is critical
|
||||
to assure that, even if the semaphore state changes between the
|
||||
preceding Wait and the next, and even if NO threads are waiting
|
||||
on the event at the time of the SetEvent, at least one thread
|
||||
will be released.
|
||||
Pulsing a manual reset event would appear to work, but it would have
|
||||
a defect which could appear if the semaphore state changed between
|
||||
the two waits. */
|
||||
|
||||
WaitResult = WaitForSingleObject (hSemCE->hMutex, dwMilliseconds);
|
||||
if (WaitResult != WAIT_OBJECT_0 && WaitResult != WAIT_ABANDONED_0) return WaitResult;
|
||||
|
||||
}
|
||||
/* The count is not zero and this thread owns the mutex. */
|
||||
|
||||
hSemCE->CurCount--;
|
||||
/* The event is now unsignaled, BUT, the semaphore count may not be
|
||||
zero, in which case the event should be signaled again
|
||||
before releasing the mutex. */
|
||||
|
||||
if (hSemCE->CurCount > 0) SetEvent (hSemCE->hEvent);
|
||||
ReleaseMutex (hSemCE->hMutex);
|
||||
return WaitResult;
|
||||
}
|
||||
|
||||
BOOL CloseSynchHandle (SYNCHHANDLE hSynch)
|
||||
/* Close a synchronization handle.
|
||||
Improvement: Test for a valid handle before dereferencing the handle. */
|
||||
{
|
||||
BOOL Result = TRUE;
|
||||
if (hSynch->hEvent != NULL) Result = Result && CloseHandle (hSynch->hEvent);
|
||||
if (hSynch->hMutex != NULL) Result = Result && CloseHandle (hSynch->hMutex);
|
||||
if (hSynch->hSemph != NULL) Result = Result && CloseHandle (hSynch->hSemph);
|
||||
HeapFree (GetProcessHeap (), 0, hSynch);
|
||||
return (Result);
|
||||
}
|
||||
|
||||
static SYNCHHANDLE CleanUp (SYNCHHANDLE hSynch, DWORD Flags)
|
||||
{ /* Prepare to return from a create of a synchronization handle.
|
||||
If there was any failure, free any allocated resources.
|
||||
"Flags" indicates which Win32 objects are required in the
|
||||
synchronization handle. */
|
||||
|
||||
BOOL ok = TRUE;
|
||||
|
||||
if (hSynch == NULL) return NULL;
|
||||
if ((Flags & 4) == 1 && (hSynch->hEvent == NULL)) ok = FALSE;
|
||||
if ((Flags & 2) == 1 && (hSynch->hMutex == NULL)) ok = FALSE;
|
||||
if ((Flags & 1) == 1 && (hSynch->hEvent == NULL)) ok = FALSE;
|
||||
if (!ok)
|
||||
{
|
||||
CloseSynchHandle (hSynch);
|
||||
return NULL;
|
||||
}
|
||||
/* Everything worked */
|
||||
return hSynch;
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
/* win_ce_semaphore.h - header file to go with win_ce_semaphore.c */
|
||||
|
||||
typedef struct _SYNCH_HANDLE_STRUCTURE {
|
||||
HANDLE hEvent;
|
||||
HANDLE hMutex;
|
||||
HANDLE hSemph;
|
||||
LONG MaxCount;
|
||||
volatile LONG CurCount;
|
||||
LPCTSTR lpName;
|
||||
} SYNCH_HANDLE_STRUCTURE, *SYNCHHANDLE;
|
||||
|
||||
#define SYNCH_HANDLE_SIZE sizeof (SYNCH_HANDLE_STRUCTURE)
|
||||
|
||||
/* Error codes - all must have bit 29 set */
|
||||
#define SYNCH_ERROR 0X20000000 /* EXERCISE - REFINE THE ERROR NUMBERS */
|
||||
|
||||
extern SYNCHHANDLE CreateSemaphoreCE (LPSECURITY_ATTRIBUTES, LONG, LONG, LPCTSTR);
|
||||
|
||||
extern BOOL ReleaseSemaphoreCE (SYNCHHANDLE, LONG, LPLONG);
|
||||
extern DWORD WaitForSemaphoreCE (SYNCHHANDLE, DWORD);
|
||||
|
||||
extern BOOL CloseSynchHandle (SYNCHHANDLE);
|
Loading…
Add table
Add a link
Reference in a new issue