diff options
Diffstat (limited to 'src/libs/threadlib.h')
-rw-r--r-- | src/libs/threadlib.h | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/src/libs/threadlib.h b/src/libs/threadlib.h new file mode 100644 index 0000000..6586d7f --- /dev/null +++ b/src/libs/threadlib.h @@ -0,0 +1,186 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* By Serge van den Boom, 2002-09-12 + */ + +#ifndef LIBS_THREADLIB_H_ +#define LIBS_THREADLIB_H_ + +#define NAMED_SYNCHRO /* Should synchronizable objects have names? */ +#define TRACK_CONTENTION /* Should we report when a thread sleeps on synchronize? */ + +/* TRACK_CONTENTION implies NAMED_SYNCHRO. */ +#ifdef TRACK_CONTENTION +# ifndef NAMED_SYNCHRO +# define NAMED_SYNCHRO +# endif +#endif /* TRACK_CONTENTION */ + +#ifdef DEBUG +# ifndef DEBUG_THREADS +# define DEBUG_THREADS +# endif +#endif /* DEBUG */ + +#ifdef DEBUG_THREADS +//# ifndef PROFILE_THREADS +//# define PROFILE_THREADS +//# endif +#endif /* DEBUG_THREADS */ + +#include <sys/types.h> +#include "libs/timelib.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +#if defined (PROFILE_THREADS) || defined (DEBUG_THREADS) +#define THREAD_NAMES +#endif + +void InitThreadSystem (void); +void UnInitThreadSystem (void); + +typedef int (*ThreadFunction) (void *); + +typedef void *Thread; +typedef void *Mutex; +typedef void *Semaphore; +typedef void *RecursiveMutex; +typedef void *CondVar; + +/* Local data associated with each thread */ +typedef struct _threadLocal { + Semaphore flushSem; +} ThreadLocal; + +/* The classes of synchronization objects */ + +enum +{ + SYNC_CLASS_TOPLEVEL = (1 << 0), /* Exposed to the game logic */ + SYNC_CLASS_AUDIO = (1 << 1), /* Involves the audio system */ + SYNC_CLASS_VIDEO = (1 << 2), /* Involves the video system. Very noisy because of FlushGraphics(). */ + SYNC_CLASS_RESOURCE = (1 << 3) /* Involves system resources (_MemoryLock) */ +}; + +/* Note. NEVER call CreateThread from the main thread, or deadlocks + are guaranteed. Use StartThread instead (which doesn't wait around + for the main thread to actually create the thread and return + it). */ + +#ifdef NAMED_SYNCHRO +/* Logical OR of all classes we want to track. */ +#define TRACK_CONTENTION_CLASSES (SYNC_CLASS_TOPLEVEL) + +/* Prototypes with the "name" field */ + +Thread CreateThread_Core (ThreadFunction func, void *data, SDWORD stackSize, const char *name); +void StartThread_Core (ThreadFunction func, void *data, SDWORD stackSize, const char *name); +Semaphore CreateSemaphore_Core (DWORD initial, const char *name, DWORD syncClass); +Mutex CreateMutex_Core (const char *name, DWORD syncClass); +RecursiveMutex CreateRecursiveMutex_Core (const char *name, DWORD syncClass); +CondVar CreateCondVar_Core (const char *name, DWORD syncClass); + +/* Preprocessor directives to forward to the appropriate routines */ + +#define CreateThread(func, data, stackSize, name) \ + CreateThread_Core ((func), (data), (stackSize), (name)) +#define StartThread(func, data, stackSize, name) \ + StartThread_Core ((func), (data), (stackSize), (name)) +#define CreateSemaphore(initial, name, syncClass) \ + CreateSemaphore_Core ((initial), (name), (syncClass)) +#define CreateMutex(name, syncClass) \ + CreateMutex_Core ((name), (syncClass)) +#define CreateRecursiveMutex(name, syncClass) \ + CreateRecursiveMutex_Core((name), (syncClass)) +#define CreateCondVar(name, syncClass) \ + CreateCondVar_Core ((name), (syncClass)) + +#else + +/* Prototypes without the "name" field. */ +Thread CreateThread_Core (ThreadFunction func, void *data, SDWORD stackSize); +void StartThread_Core (ThreadFunction func, void *data, SDWORD stackSize); +Semaphore CreateSemaphore_Core (DWORD initial); +Mutex CreateMutex_Core (void); +RecursiveMutex CreateRecursiveMutex_Core (void); +CondVar CreateCondVar_Core (void); + + +/* Preprocessor directives to forward to the appropriate routines. + The "name" field is stripped away in preprocessing. */ + +#define CreateThread(func, data, stackSize, name) \ + CreateThread_Core ((func), (data), (stackSize)) +#define StartThread(func, data, stackSize, name) \ + StartThread_Core ((func), (data), (stackSize)) +#define CreateSemaphore(initial, name, syncClass) \ + CreateSemaphore_Core ((initial)) +#define CreateMutex(name, syncClass) \ + CreateMutex_Core () +#define CreateRecursiveMutex(name, syncClass) \ + CreateRecursiveMutex_Core() +#define CreateCondVar(name, syncClass) \ + CreateCondVar_Core () + +#endif + +ThreadLocal *CreateThreadLocal (void); +void DestroyThreadLocal (ThreadLocal *tl); +ThreadLocal *GetMyThreadLocal (void); + +void HibernateThread (TimePeriod timePeriod); +void HibernateThreadUntil (TimeCount wakeTime); +void SleepThread (TimePeriod timePeriod); +void SleepThreadUntil (TimeCount wakeTime); +void DestroyThread (Thread); +void TaskSwitch (void); +void WaitThread (Thread thread, int *status); + +void FinishThread (Thread); +void ProcessThreadLifecycles (void); + +#ifdef PROFILE_THREADS +void PrintThreadsStats (void); +#endif /* PROFILE_THREADS */ + + +void DestroySemaphore (Semaphore sem); +void SetSemaphore (Semaphore sem); +void ClearSemaphore (Semaphore sem); + +void DestroyMutex (Mutex sem); +void LockMutex (Mutex sem); +void UnlockMutex (Mutex sem); + +void DestroyRecursiveMutex (RecursiveMutex m); +void LockRecursiveMutex (RecursiveMutex m); +void UnlockRecursiveMutex (RecursiveMutex m); +int GetRecursiveMutexDepth (RecursiveMutex m); + +void DestroyCondVar (CondVar); +void WaitCondVar (CondVar); +void SignalCondVar (CondVar); +void BroadcastCondVar (CondVar); + +#if defined(__cplusplus) +} +#endif + +#endif /* LIBS_THREADLIB_H_ */ |