summaryrefslogtreecommitdiff
path: root/src/libs/threadlib.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/threadlib.h')
-rw-r--r--src/libs/threadlib.h186
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_ */