openmohaa/code/gamespy/common/gsPlatformThread.h

201 lines
5.8 KiB
C

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
#ifndef __GSPLATFORMTHREAD_H__
#define __GSPLATFORMTHREAD_H__
#include "gsPlatform.h"
#ifdef __cplusplus
extern "C" {
#endif
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Thread types
#if defined(_WIN32)
typedef CRITICAL_SECTION GSICriticalSection;
typedef HANDLE GSISemaphoreID;
typedef HANDLE GSIThreadID;
typedef DWORD (WINAPI *GSThreadFunc)(void *arg);
#elif defined(_PS2)
typedef int GSIThreadID;
typedef int GSISemaphoreID;
typedef struct
{
// A critical section is a re-entrant semaphore
GSISemaphoreID mSemaphore;
GSIThreadID mOwnerThread;
gsi_u32 mEntryCount; // track re-entry
gsi_u32 mPad; // make 16bytes
} GSICriticalSection;
typedef void (*GSThreadFunc)(void *arg);
#elif defined(_NITRO)
typedef OSMutex GSICriticalSection;
typedef struct
{
OSMutex mLock;
gsi_i32 mValue;
gsi_i32 mMax;
} GSISemaphoreID;
typedef struct
{
OSThread mThread;
void * mStack;
} GSIThreadID;
typedef void (*GSThreadFunc)(void *arg);
#elif defined(_REVOLUTION)
typedef OSMutex GSICriticalSection;
typedef OSSemaphore GSISemaphoreID;
typedef struct
{
OSThread mThread;
void * mStack;
} GSIThreadID;
typedef void *(*GSThreadFunc)(void *arg);
#elif defined(_PSP)
// Todo: Test PSP thread code, then remove this define
#define GSI_NO_THREADS
typedef int GSIThreadID;
typedef int GSISemaphoreID;
typedef struct
{
// A critical section is a re-entrant semaphore
GSISemaphoreID mSemaphore;
GSIThreadID mOwnerThread;
gsi_u32 mEntryCount; // track re-entry
gsi_u32 mPad; // make 16bytes
} GSICriticalSection;
typedef void (*GSThreadFunc)(void *arg);
#elif defined(_PS3)
// Todo: Test PS3 ppu thread code, then remove this define
#define GSI_NO_THREADS
typedef int GSIThreadID;
typedef int GSISemaphoreID;
typedef struct
{
// A critical section is a re-entrant semaphore
GSISemaphoreID mSemaphore;
GSIThreadID mOwnerThread;
gsi_u32 mEntryCount; // track re-entry
gsi_u32 mPad; // make 16bytes
} GSICriticalSection;
typedef void (*GSThreadFunc)(void *arg);
#elif defined(_UNIX) // Linux, Mac OS X, openbsd, etc.
#if defined(__OpenBSD__)
#include <pthread.h>
#endif
typedef pthread_mutex_t GSICriticalSection;
typedef struct
{
pthread_mutex_t mLock;
gsi_i32 mValue;
gsi_i32 mMax;
} GSISemaphoreID;
typedef struct
{
pthread_t thread;
pthread_attr_t attr;
} GSIThreadID;
typedef void (*GSThreadFunc)(void *arg);
#else
#define GSI_NO_THREADS
#endif
#if defined(WIN32)
#define GSI_INFINITE INFINITE
#else
#define GSI_INFINITE (gsi_u32)(-1)
#endif
#if !defined(GSI_NO_THREADS)
// The increment/read operations must not be preempted
#if defined(_WIN32)
#define gsiInterlockedIncrement(a) InterlockedIncrement((long*)a)
#define gsiInterlockedDecrement(a) InterlockedDecrement((long*)a)
#elif defined(_PS2)
gsi_u32 gsiInterlockedIncrement(gsi_u32* num);
gsi_u32 gsiInterlockedDecrement(gsi_u32* num);
#elif defined(_PS3)
// TODO - threading in PS3 uses pthreads, just like Linux
#elif defined(_NITRO)
gsi_u32 gsiInterlockedIncrement(gsi_u32* num);
gsi_u32 gsiInterlockedDecrement(gsi_u32* num);
#elif defined(_REVOLUTION)
gsi_u32 gsiInterlockedIncrement(gsi_u32* num);
gsi_u32 gsiInterlockedDecrement(gsi_u32* num);
#elif defined(_UNIX)
gsi_u32 gsiInterlockedIncrement(gsi_u32* num);
gsi_u32 gsiInterlockedDecrement(gsi_u32* num);
#endif
#else
// Don't worry about concurrancy when GSI_NO_THREADS is defined
#define gsiInterlockedIncrement(a) (++(*a))
#define gsiInterlockedDecrement(a) (--(*a))
#endif
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
#if !defined(GSI_NO_THREADS)
int gsiStartThread(GSThreadFunc aThreadFunc, gsi_u32 theStackSize, void *arg, GSIThreadID* theThreadIdOut);
void gsiCancelThread(GSIThreadID theThreadID);
void gsiExitThread(GSIThreadID theThreadID);
void gsiCleanupThread(GSIThreadID theThreadID);
// Thread Synchronization - Startup/Shutdown
gsi_u32 gsiHasThreadShutdown(GSIThreadID theThreadID);
// Thread Synchronization - Critical Section
void gsiInitializeCriticalSection(GSICriticalSection *theCrit);
void gsiEnterCriticalSection(GSICriticalSection *theCrit);
void gsiLeaveCriticalSection(GSICriticalSection *theCrit);
void gsiDeleteCriticalSection(GSICriticalSection *theCrit);
// Thread Synchronization - Semaphore
GSISemaphoreID gsiCreateSemaphore(gsi_i32 theInitialCount, gsi_i32 theMaxCount, char* theName);
gsi_u32 gsiWaitForSemaphore(GSISemaphoreID theSemaphore, gsi_u32 theTimeoutMs);
void gsiReleaseSemaphore(GSISemaphoreID theSemaphore, gsi_i32 theReleaseCount);
void gsiCloseSemaphore(GSISemaphoreID theSemaphore);
#else
// NO THREADS - stub everything to unused
#define gsiStartThread(a, b, c, d) (-1) // must return something
#define gsiCancelThread(a)
#define gsiExitThread(a)
#define gsiCleanupThread(a)
#define gsiHasThreadShutdown(a) (1) // must return something
#define gsiInitializeCriticalSection(a)
#define gsiEnterCriticalSection(a)
#define gsiLeaveCriticalSection(a)
#define gsiDeleteCriticalSection(a)
#define gsiCreateSemaphore(a,b,c) (-1)
#define gsiWaitForSemaphore(a,b) (0)
#define gsiReleaseSemaphore(a,b)
#define gsiCloseSemaphore(a)
#endif // GSI_NO_THREADS
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
#ifdef __cplusplus
}
#endif
#endif // __GSPLATFORMTHREAD_H__