00001
#ifndef RAGE_THREADS_H
00002
#define RAGE_THREADS_H
00003
00004
struct ThreadSlot;
00005
class RageTimer;
00006 class RageThread
00007 {
00008 ThreadSlot *
m_pSlot;
00009 CString name;
00010
00011
static bool m_bSystemSupportsTLS;
00012
00013
public:
00014
RageThread();
00015
~RageThread();
00016
00017 void SetName(
const CString &n ) {
name = n; }
00018
void Create(
int (*fn)(
void *),
void *data );
00019
00020
00021
00022
static void HaltAllThreads(
bool Kill=
false );
00023
00024
00025
static void ResumeAllThreads();
00026
00027
static uint64_t
GetCurrentThreadID();
00028
00029
static const char *
GetCurThreadName();
00030
static const char *GetThreadNameByID( uint64_t iID );
00031
static bool EnumThreadIDs(
int n, uint64_t &iID );
00032
int Wait();
00033 bool IsCreated()
const {
return m_pSlot != NULL; }
00034
00035
00036
00037
00038 static bool GetSupportsTLS() {
return m_bSystemSupportsTLS; }
00039
00040 static void SetSupportsTLS(
bool b ) {
m_bSystemSupportsTLS = b; }
00041 };
00042
00043
namespace Checkpoints
00044 {
00045
void LogCheckpoints(
bool yes=
true );
00046
void SetCheckpoint(
const char *file,
int line,
const char *message );
00047
void GetLogs(
char *pBuf,
int iSize,
const char *delim );
00048 };
00049
00050 #define CHECKPOINT (Checkpoints::SetCheckpoint(__FILE__, __LINE__, NULL))
00051 #define CHECKPOINT_M(m) (Checkpoints::SetCheckpoint(__FILE__, __LINE__, m))
00052
00053
00054
00055
00056
00057
00058
class MutexImpl;
00059 class RageMutex
00060 {
00061
public:
00062 CString GetName()
const {
return m_sName; }
00063 void SetName(
const CString &s ) {
m_sName = s; }
00064
virtual void Lock();
00065
virtual bool TryLock();
00066
virtual void Unlock();
00067
virtual bool IsLockedByThisThread() const;
00068
00069
RageMutex( CString name );
00070 virtual ~
RageMutex();
00071
00072 protected:
00073 MutexImpl *m_pMutex;
00074 CString m_sName;
00075
00076 int m_UniqueID;
00077
00078 uint64_t m_LockedBy;
00079 int m_LockCnt;
00080
00081
void MarkLockedMutex();
00082 };
00083
00084
00085
00086 class
LockMutex
00087 {
00088 RageMutex &mutex;
00089
00090 const char *file;
00091 int line;
00092 float locked_at;
00093 bool locked;
00094
00095
public:
00096 LockMutex(RageMutex &mut,
const char *file,
int line);
00097 LockMutex(RageMutex &mut): mutex(mut), file(NULL), line(-1), locked_at(-1), locked(true) { mutex.
Lock(); }
00098 ~LockMutex();
00099 LockMutex(LockMutex &cpy): mutex(cpy.mutex), file(NULL), line(-1), locked_at(cpy.locked_at), locked(true) { mutex.
Lock(); }
00100
00101
00102
00103
void Unlock();
00104 };
00105
00106
00107
00108
00109
00110
00111
#if 0
00112
#ifdef DEBUG
00113
00114
00115
00116
#define LockMutL2(m, l) LockMutex LocalLock ## l (m, __FUNCTION__, __LINE__)
00117
#else
00118
#define LockMutL2(m, l) LockMutex LocalLock ## l (m)
00119
#endif
00120
00121
#define LockMutL(m, l) LockMutL2(m, l)
00122
#define LockMut(m) LockMutL(m, __LINE__)
00123
#endif
00124
00125
00126
00127
00128
#if _MSC_VER < 1300
00129 #define LockMut(m) LockMutex LocalLock(m, __FILE__, __LINE__)
00130
#else
00131
#define LockMut(m) LockMutex LocalLock(m, __FUNCTION__, __LINE__)
00132
#endif
00133
00134
class EventImpl;
00135 class RageEvent:
public RageMutex
00136 {
00137
public:
00138
RageEvent(
CString name );
00139 ~
RageEvent();
00140
00141
00142
00143
00144
00145
00146
00147
bool Wait(
RageTimer *pTimeout = NULL );
00148
void Signal();
00149
void Broadcast();
00150
00151
private:
00152 EventImpl *m_pEvent;
00153 };
00154
00155
class SemaImpl;
00156 class RageSemaphore
00157 {
00158
public:
00159
RageSemaphore(
CString sName,
int iInitialValue = 0 );
00160 ~
RageSemaphore();
00161
00162 CString GetName()
const {
return m_sName; }
00163
int GetValue() const;
00164
void Post();
00165
void Wait(
bool bFailOnTimeout=true );
00166
bool TryWait();
00167
00168 private:
00169 SemaImpl *m_pSema;
00170 CString m_sName;
00171 };
00172
00173 #endif
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198