mirror of
https://github.com/libretro/libretro-wolfenstein3d.git
synced 2024-11-26 18:20:33 +00:00
Add initial SDL threading ports
This commit is contained in:
parent
9ce6f95a13
commit
2a80b7b11f
194
sdl/include/LRSDL_thread.h
Normal file
194
sdl/include/LRSDL_thread.h
Normal file
@ -0,0 +1,194 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2011 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef _LRSDL_thread_h
|
||||
#define _LRSDL_thread_h
|
||||
|
||||
/**
|
||||
* \file LRSDL_thread.h
|
||||
*
|
||||
* Header for the SDL thread management routines.
|
||||
*/
|
||||
|
||||
#include "LRSDL_stdinc.h"
|
||||
#include "LRSDL_error.h"
|
||||
|
||||
/* Thread synchronization primitives */
|
||||
#include "LRSDL_mutex.h"
|
||||
|
||||
#include "begin_code.h"
|
||||
/* Set up for C function definitions, even when using C++ */
|
||||
#ifdef __cplusplus
|
||||
/* *INDENT-OFF* */
|
||||
extern "C" {
|
||||
/* *INDENT-ON* */
|
||||
#endif
|
||||
|
||||
/* The SDL thread structure, defined in SDL_thread.c */
|
||||
struct LRSDL_Thread;
|
||||
typedef struct LRSDL_Thread LRSDL_Thread;
|
||||
|
||||
/* The SDL thread ID */
|
||||
typedef unsigned long LRSDL_threadID;
|
||||
|
||||
/* The SDL thread priority
|
||||
*
|
||||
* Note: On many systems you require special privileges to set high priority.
|
||||
*/
|
||||
typedef enum {
|
||||
SDL_THREAD_PRIORITY_LOW,
|
||||
SDL_THREAD_PRIORITY_NORMAL,
|
||||
SDL_THREAD_PRIORITY_HIGH
|
||||
} LRSDL_ThreadPriority;
|
||||
|
||||
/* The function passed to SDL_CreateThread()
|
||||
It is passed a void* user context parameter and returns an int.
|
||||
*/
|
||||
typedef int (SDLCALL * LRSDL_ThreadFunction) (void *data);
|
||||
|
||||
#if defined(__WIN32__) && !defined(HAVE_LIBC)
|
||||
/**
|
||||
* \file LRSDL_thread.h
|
||||
*
|
||||
* We compile SDL into a DLL. This means, that it's the DLL which
|
||||
* creates a new thread for the calling process with the SDL_CreateThread()
|
||||
* API. There is a problem with this, that only the RTL of the SDL.DLL will
|
||||
* be initialized for those threads, and not the RTL of the calling
|
||||
* application!
|
||||
*
|
||||
* To solve this, we make a little hack here.
|
||||
*
|
||||
* We'll always use the caller's _beginthread() and _endthread() APIs to
|
||||
* start a new thread. This way, if it's the SDL.DLL which uses this API,
|
||||
* then the RTL of SDL.DLL will be used to create the new thread, and if it's
|
||||
* the application, then the RTL of the application will be used.
|
||||
*
|
||||
* So, in short:
|
||||
* Always use the _beginthread() and _endthread() of the calling runtime
|
||||
* library!
|
||||
*/
|
||||
#define SDL_PASSED_BEGINTHREAD_ENDTHREAD
|
||||
#ifndef _WIN32_WCE
|
||||
#include <process.h> /* This has _beginthread() and _endthread() defined! */
|
||||
#endif
|
||||
|
||||
typedef uintptr_t(__cdecl * pfnSDL_CurrentBeginThread) (void *, unsigned,
|
||||
unsigned (__stdcall *
|
||||
func) (void
|
||||
*),
|
||||
void *arg, unsigned,
|
||||
unsigned *threadID);
|
||||
typedef void (__cdecl * pfnSDL_CurrentEndThread) (unsigned code);
|
||||
|
||||
/**
|
||||
* Create a thread.
|
||||
*/
|
||||
extern DECLSPEC LRSDL_Thread *SDLCALL
|
||||
LRSDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data,
|
||||
pfnSDL_CurrentBeginThread pfnBeginThread,
|
||||
pfnSDL_CurrentEndThread pfnEndThread);
|
||||
|
||||
#if defined(_WIN32_WCE)
|
||||
|
||||
/**
|
||||
* Create a thread.
|
||||
*/
|
||||
#define LRSDL_CreateThread(fn, name, data) LRSDL_CreateThread(fn, name, data, NULL, NULL)
|
||||
|
||||
#else
|
||||
|
||||
/**
|
||||
* Create a thread.
|
||||
*/
|
||||
#define LRSDL_CreateThread(fn, name, data) LRSDL_CreateThread(fn, name, data, _beginthreadex, _endthreadex)
|
||||
|
||||
#endif
|
||||
#else
|
||||
|
||||
/**
|
||||
* Create a thread.
|
||||
*
|
||||
* Thread naming is a little complicated: Most systems have very small
|
||||
* limits for the string length (BeOS has 32 bytes, Linux currently has 16,
|
||||
* Visual C++ 6.0 has nine!), and possibly other arbitrary rules. You'll
|
||||
* have to see what happens with your system's debugger. The name should be
|
||||
* UTF-8 (but using the naming limits of C identifiers is a better bet).
|
||||
* There are no requirements for thread naming conventions, so long as the
|
||||
* string is null-terminated UTF-8, but these guidelines are helpful in
|
||||
* choosing a name:
|
||||
*
|
||||
* http://stackoverflow.com/questions/149932/naming-conventions-for-threads
|
||||
*
|
||||
* If a system imposes requirements, SDL will try to munge the string for
|
||||
* it (truncate, etc), but the original string contents will be available
|
||||
* from SDL_GetThreadName().
|
||||
*/
|
||||
extern DECLSPEC LRSDL_Thread *SDLCALL
|
||||
LRSDL_CreateThread(LRSDL_ThreadFunction fn, const char *name, void *data);
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Get the thread name, as it was specified in LRSDL_CreateThread().
|
||||
* This function returns a pointer to a UTF-8 string that names the
|
||||
* specified thread, or NULL if it doesn't have a name. This is internal
|
||||
* memory, not to be free()'d by the caller, and remains valid until the
|
||||
* specified thread is cleaned up by LRSDL_WaitThread().
|
||||
*/
|
||||
extern DECLSPEC const char *SDLCALL LRSDL_GetThreadName(LRSDL_Thread *thread);
|
||||
|
||||
/**
|
||||
* Get the thread identifier for the current thread.
|
||||
*/
|
||||
extern DECLSPEC LRSDL_threadID SDLCALL LRSDL_ThreadID(void);
|
||||
|
||||
/**
|
||||
* Get the thread identifier for the specified thread.
|
||||
*
|
||||
* Equivalent to LRSDL_ThreadID() if the specified thread is NULL.
|
||||
*/
|
||||
extern DECLSPEC LRSDL_threadID SDLCALL LRSDL_GetThreadID(LRSDL_Thread * thread);
|
||||
|
||||
/**
|
||||
* Set the priority for the current thread
|
||||
*/
|
||||
extern DECLSPEC int SDLCALL LRSDL_SetThreadPriority(LRSDL_ThreadPriority priority);
|
||||
|
||||
/**
|
||||
* Wait for a thread to finish.
|
||||
*
|
||||
* The return code for the thread function is placed in the area
|
||||
* pointed to by \c status, if \c status is not NULL.
|
||||
*/
|
||||
extern DECLSPEC void SDLCALL LRSDL_WaitThread(LRSDL_Thread * thread, int *status);
|
||||
|
||||
|
||||
/* Ends C function definitions when using C++ */
|
||||
#ifdef __cplusplus
|
||||
/* *INDENT-OFF* */
|
||||
}
|
||||
/* *INDENT-ON* */
|
||||
#endif
|
||||
#include "close_code.h"
|
||||
|
||||
#endif /* _SDL_thread_h */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
223
sdl/thread/SDL_syscond.c
Normal file
223
sdl/thread/SDL_syscond.c
Normal file
@ -0,0 +1,223 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2011 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#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"
|
||||
#include <rthreads/rthreads.h>
|
||||
#include <rthreads/rsemaphore.h>
|
||||
|
||||
struct SDL_cond
|
||||
{
|
||||
slock_t *lock;
|
||||
int waiting;
|
||||
int signals;
|
||||
ssem_t *wait_sem;
|
||||
ssem_t *wait_done;
|
||||
};
|
||||
|
||||
/* Create a condition variable */
|
||||
SDL_cond *LRSDL_CreateCond(void)
|
||||
{
|
||||
SDL_cond *cond;
|
||||
|
||||
cond = (SDL_cond *) SDL_malloc(sizeof(SDL_cond));
|
||||
if (cond)
|
||||
{
|
||||
cond->lock = slock_new();
|
||||
cond->wait_sem = ssem_new(0);
|
||||
cond->wait_done = ssem_new(0);
|
||||
cond->waiting = 0;
|
||||
cond->signals = 0;
|
||||
|
||||
if (!cond->lock || !cond->wait_sem || !cond->wait_done) {
|
||||
LRSDL_DestroyCond(cond);
|
||||
cond = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
LRSDL_OutOfMemory();
|
||||
return (cond);
|
||||
}
|
||||
|
||||
/* Destroy a condition variable */
|
||||
void LRSDL_DestroyCond(SDL_cond * cond)
|
||||
{
|
||||
if (cond)
|
||||
{
|
||||
if (cond->wait_sem)
|
||||
ssem_free(cond->wait_sem);
|
||||
if (cond->wait_done)
|
||||
ssem_free(cond->wait_done);
|
||||
if (cond->lock)
|
||||
LRSDL_DestroyMutex(cond->lock);
|
||||
LRSDL_free(cond);
|
||||
}
|
||||
}
|
||||
|
||||
/* Restart one of the threads that are waiting on the condition variable */
|
||||
int LRSDL_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.
|
||||
*/
|
||||
slock_lock(cond->lock);
|
||||
if (cond->waiting > cond->signals)
|
||||
{
|
||||
++cond->signals;
|
||||
ssem_signal(cond->wait_sem);
|
||||
slock_unlock(cond->lock);
|
||||
ssem_wait(cond->wait_done);
|
||||
}
|
||||
else
|
||||
slock_unlock(cond->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Restart all threads that are waiting on the condition variable */
|
||||
int LRSDL_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.
|
||||
*/
|
||||
slock_lock(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)
|
||||
ssem_signal(cond->wait_sem);
|
||||
|
||||
/* Now all released threads are blocked here, waiting for us.
|
||||
Collect them all (and win fabulous prizes!) :-)
|
||||
*/
|
||||
slock_unlock(cond->lock);
|
||||
for (i = 0; i < num_waiting; ++i)
|
||||
ssem_wait(cond->wait_done);
|
||||
}
|
||||
else
|
||||
slock_unlock(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, lock);
|
||||
}
|
||||
SDL_UnlockMutex(lock);
|
||||
|
||||
Thread B:
|
||||
SDL_LockMutex(lock);
|
||||
...
|
||||
condition = true;
|
||||
...
|
||||
SDL_CondSignal(cond);
|
||||
SDL_UnlockMutex(lock);
|
||||
*/
|
||||
int LRSDL_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.
|
||||
*/
|
||||
slock_lock(cond->lock);
|
||||
++cond->waiting;
|
||||
slock_unlock(cond->lock);
|
||||
|
||||
/* Unlock the mutex, as is required by condition variable semantics */
|
||||
slock_unlock(mutex);
|
||||
|
||||
/* Wait for a signal */
|
||||
if (ms == SDL_MUTEX_MAXWAIT)
|
||||
retval = ssem_wait(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
|
||||
*/
|
||||
slock_lock(cond->lock);
|
||||
if (cond->signals > 0) {
|
||||
/* If we timed out, we need to eat a condition signal */
|
||||
if (retval > 0) {
|
||||
ssem_wait(cond->wait_sem);
|
||||
}
|
||||
/* We always notify the signal thread that we are done */
|
||||
ssem_signal(cond->wait_done);
|
||||
|
||||
/* Signal handshake complete */
|
||||
--cond->signals;
|
||||
}
|
||||
--cond->waiting;
|
||||
slock_unlock(cond->lock);
|
||||
|
||||
/* Lock the mutex, as is required by condition variable semantics */
|
||||
slock_lock(mutex);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Wait on the condition variable forever */
|
||||
int
|
||||
SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex)
|
||||
{
|
||||
return scond_wait_timeout((scond_t*)cond, (slock_t*)mutex, SDL_MUTEX_MAXWAIT);
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
139
sdl/thread/SDL_sysmutex.c
Normal file
139
sdl/thread/SDL_sysmutex.c
Normal file
@ -0,0 +1,139 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2011 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_config.h"
|
||||
|
||||
/* An implementation of mutexes using semaphores */
|
||||
|
||||
#include "SDL_thread.h"
|
||||
#include "SDL_systhread_c.h"
|
||||
|
||||
#include <rthreads/rsemaphore.h>
|
||||
|
||||
struct SDL_mutex
|
||||
{
|
||||
int recursive;
|
||||
SDL_threadID owner;
|
||||
ssem_t *sem;
|
||||
};
|
||||
|
||||
/* 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 semaphore, with initial value 1 */
|
||||
mutex->sem = ssem_new(1);
|
||||
mutex->recursive = 0;
|
||||
mutex->owner = 0;
|
||||
if (!mutex->sem)
|
||||
{
|
||||
SDL_free(mutex);
|
||||
mutex = NULL;
|
||||
}
|
||||
} else {
|
||||
SDL_OutOfMemory();
|
||||
}
|
||||
return mutex;
|
||||
}
|
||||
|
||||
/* Free the mutex */
|
||||
void
|
||||
SDL_DestroyMutex(SDL_mutex * mutex)
|
||||
{
|
||||
if (mutex)
|
||||
{
|
||||
if (mutex->sem)
|
||||
ssem_free(mutex->sem);
|
||||
SDL_free(mutex);
|
||||
}
|
||||
}
|
||||
|
||||
/* Lock the semaphore */
|
||||
int
|
||||
SDL_mutexP(SDL_mutex * mutex)
|
||||
{
|
||||
#if SDL_THREADS_DISABLED
|
||||
return 0;
|
||||
#else
|
||||
SDL_threadID 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.
|
||||
*/
|
||||
ssem_wait(mutex->sem);
|
||||
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;
|
||||
ssem_signal(mutex->sem);
|
||||
}
|
||||
return 0;
|
||||
#endif /* SDL_THREADS_DISABLED */
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
22
sdl/thread/SDL_sysmutex_c.h
Normal file
22
sdl/thread/SDL_sysmutex_c.h
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2011 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_config.h"
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
227
sdl/thread/SDL_syssem.c
Normal file
227
sdl/thread/SDL_syssem.c
Normal file
@ -0,0 +1,227 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2011 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#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"
|
||||
|
||||
#include <rthreads/rthreads.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
|
||||
|
||||
struct SDL_semaphore
|
||||
{
|
||||
Uint32 count;
|
||||
Uint32 waiters_count;
|
||||
slock_t *count_lock;
|
||||
scond_t *count_nonzero;
|
||||
};
|
||||
|
||||
SDL_sem *
|
||||
SDL_CreateSemaphore(Uint32 initial_value)
|
||||
{
|
||||
SDL_sem *sem;
|
||||
|
||||
sem = (SDL_sem *) SDL_malloc(sizeof(*sem));
|
||||
if (!sem) {
|
||||
SDL_OutOfMemory();
|
||||
return NULL;
|
||||
}
|
||||
sem->count = initial_value;
|
||||
sem->waiters_count = 0;
|
||||
|
||||
sem->count_lock = slock_new();
|
||||
sem->count_nonzero = scond_new();
|
||||
|
||||
if (!sem->count_lock || !sem->count_nonzero)
|
||||
{
|
||||
ssem_free(sem);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return sem;
|
||||
}
|
||||
|
||||
/* WARNING:
|
||||
You cannot call this function when another thread is using the semaphore.
|
||||
*/
|
||||
void
|
||||
SDL_DestroySemaphore(SDL_sem * sem)
|
||||
{
|
||||
if (sem) {
|
||||
sem->count = 0xFFFFFFFF;
|
||||
while (sem->waiters_count > 0) {
|
||||
scond_signal(sem->count_nonzero);
|
||||
SDL_Delay(10);
|
||||
}
|
||||
SDL_DestroyCond(sem->count_nonzero);
|
||||
if (sem->count_lock) {
|
||||
SDL_mutexP(sem->count_lock);
|
||||
SDL_mutexV(sem->count_lock);
|
||||
slock_free(sem->count_lock);
|
||||
}
|
||||
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;
|
||||
slock_lock(sem->count_lock);
|
||||
if (sem->count > 0) {
|
||||
--sem->count;
|
||||
retval = 0;
|
||||
}
|
||||
slock_unlock(sem->count_lock);
|
||||
|
||||
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);
|
||||
|
||||
slock_lock(sem->count_lock);
|
||||
++sem->waiters_count;
|
||||
retval = 0;
|
||||
while ((sem->count == 0) && (retval != SDL_MUTEX_TIMEDOUT))
|
||||
{
|
||||
retval = scond_wait_timeout(sem->count_nonzero,
|
||||
sem->count_lock, timeout);
|
||||
}
|
||||
--sem->waiters_count;
|
||||
if (retval == 0)
|
||||
--sem->count;
|
||||
slock_unlock(sem->count_lock);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int
|
||||
SDL_SemWait(SDL_sem * sem)
|
||||
{
|
||||
return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
|
||||
}
|
||||
|
||||
Uint32
|
||||
SDL_SemValue(SDL_sem * sem)
|
||||
{
|
||||
Uint32 value;
|
||||
|
||||
value = 0;
|
||||
if (sem) {
|
||||
slock_lock(sem->count_lock);
|
||||
value = sem->count;
|
||||
slock_unlock(sem->count_lock);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
int
|
||||
SDL_SemPost(SDL_sem * sem)
|
||||
{
|
||||
if (!sem) {
|
||||
SDL_SetError("Passed a NULL semaphore");
|
||||
return -1;
|
||||
}
|
||||
|
||||
slock_lock(sem->count_lock);
|
||||
if (sem->waiters_count > 0)
|
||||
scond_signal(sem->count_nonzero);
|
||||
++sem->count;
|
||||
slock_unlock(sem->count_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* SDL_THREADS_DISABLED */
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
59
sdl/thread/SDL_systhread.c
Normal file
59
sdl/thread/SDL_systhread.c
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2011 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_config.h"
|
||||
|
||||
/* Thread management routines for SDL */
|
||||
|
||||
#include "SDL_thread.h"
|
||||
#include "../SDL_systhread.h"
|
||||
|
||||
int
|
||||
SDL_SYS_CreateThread(SDL_Thread * thread, void *args)
|
||||
{
|
||||
SDL_SetError("Threads are not supported on this platform");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
void
|
||||
SDL_SYS_SetupThread(const char *name)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_threadID
|
||||
SDL_ThreadID(void)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
SDL_SYS_WaitThread(SDL_Thread * thread)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
26
sdl/thread/SDL_systhread_c.h
Normal file
26
sdl/thread/SDL_systhread_c.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2011 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_config.h"
|
||||
|
||||
/* Stub until we implement threads on this platform */
|
||||
typedef int SYS_ThreadHandle;
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
@ -1897,9 +1897,7 @@ DrawCtlScreen (void)
|
||||
y = CTL_Y + 29;
|
||||
VWB_DrawPic (x, y, C_SELECTEDPIC);
|
||||
|
||||
//
|
||||
// PICK FIRST AVAILABLE SPOT
|
||||
//
|
||||
/* PICK FIRST AVAILABLE SPOT */
|
||||
if (CtlItems.curpos < 0 || !CtlMenu[CtlItems.curpos].active)
|
||||
{
|
||||
for (i = 0; i < CtlItems.amount; i++)
|
||||
@ -2584,10 +2582,9 @@ PrintCustKeybd (int i)
|
||||
void
|
||||
DrawCustKeybd (int hilight)
|
||||
{
|
||||
int i, color;
|
||||
int i;
|
||||
int color = TEXTCOLOR;
|
||||
|
||||
|
||||
color = TEXTCOLOR;
|
||||
if (hilight)
|
||||
color = HIGHLIGHT;
|
||||
SETFONTCOLOR (color, BKGDCOLOR);
|
||||
|
@ -10,7 +10,7 @@
|
||||
=============================================================================
|
||||
*/
|
||||
|
||||
#define sc_Question 0x35
|
||||
#define SC_QUESTION 0x35
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
|
10
wl_state.c
10
wl_state.c
@ -88,11 +88,11 @@ void SpawnNewObj (unsigned tilex, unsigned tiley, statetype *state)
|
||||
else
|
||||
newobj->ticcount = 0;
|
||||
|
||||
newobj->tilex = (short) tilex;
|
||||
newobj->tiley = (short) tiley;
|
||||
newobj->x = ((int32_t)tilex<<TILESHIFT)+TILEGLOBAL/2;
|
||||
newobj->y = ((int32_t)tiley<<TILESHIFT)+TILEGLOBAL/2;
|
||||
newobj->dir = nodir;
|
||||
newobj->tilex = (int16_t) tilex;
|
||||
newobj->tiley = (int16_t) tiley;
|
||||
newobj->x = ((int32_t)tilex<<TILESHIFT)+TILEGLOBAL/2;
|
||||
newobj->y = ((int32_t)tiley<<TILESHIFT)+TILEGLOBAL/2;
|
||||
newobj->dir = nodir;
|
||||
|
||||
actorat[tilex][tiley] = newobj;
|
||||
newobj->areanumber =
|
||||
|
Loading…
Reference in New Issue
Block a user