/////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// #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 #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__