Files
itgmania212121/stepmania/src/RageThreads.h
T

195 lines
5.8 KiB
C++
Raw Normal View History

2005-02-13 03:50:51 +00:00
/* RageThread - Thread, mutex, semaphore and event classes. */
#ifndef RAGE_THREADS_H
#define RAGE_THREADS_H
2004-06-11 19:24:05 +00:00
struct ThreadSlot;
2005-01-26 20:59:41 +00:00
class RageTimer;
2003-07-27 03:08:02 +00:00
class RageThread
{
public:
RageThread();
RageThread( const RageThread &cpy );
2003-07-27 03:08:02 +00:00
~RageThread();
2006-11-01 05:42:15 +00:00
void SetName( const RString &n ) { m_sName = n; }
RString GetName() const { return m_sName; }
2003-07-27 03:08:02 +00:00
void Create( int (*fn)(void *), void *data );
/* For crash handlers: kill or suspend all threads (except for
* the running one) immediately. */
2003-07-27 07:00:13 +00:00
static void HaltAllThreads( bool Kill=false );
2004-01-12 01:36:25 +00:00
/* If HaltAllThreads was called (with Kill==false), resume. */
static void ResumeAllThreads();
2004-06-11 19:24:05 +00:00
static uint64_t GetCurrentThreadID();
2004-04-07 03:38:15 +00:00
static const char *GetCurrentThreadName();
2004-06-11 19:24:05 +00:00
static const char *GetThreadNameByID( uint64_t iID );
2004-09-07 02:58:59 +00:00
static bool EnumThreadIDs( int n, uint64_t &iID );
2003-07-27 03:08:02 +00:00
int Wait();
2004-06-11 19:24:05 +00:00
bool IsCreated() const { return m_pSlot != NULL; }
2004-09-09 02:28:05 +00:00
/* A system can define HAVE_TLS, indicating that it can compile thread_local
* code, but an individual environment may not actually have functional TLS.
* If this returns false, thread_local variables are considered undefined. */
static bool GetSupportsTLS() { return s_bSystemSupportsTLS; }
static void SetSupportsTLS( bool b ) { s_bSystemSupportsTLS = b; }
static bool GetIsShowingDialog() { return s_bIsShowingDialog; }
static void SetIsShowingDialog( bool b ) { s_bIsShowingDialog = b; }
static uint64_t GetInvalidThreadID();
2005-12-19 01:43:04 +00:00
private:
ThreadSlot *m_pSlot;
2006-11-01 05:42:15 +00:00
RString m_sName;
2005-12-19 01:43:04 +00:00
static bool s_bSystemSupportsTLS;
static bool s_bIsShowingDialog;
2003-07-27 03:08:02 +00:00
};
/* Register a thread created outside of RageThread. This gives it a name for RageThread::GetCurrentThreadName,
* and allocates a slot for checkpoints. */
class RageThreadRegister
{
public:
2006-01-21 23:01:06 +00:00
RageThreadRegister( const RString &sName );
~RageThreadRegister();
private:
ThreadSlot *m_pSlot;
};
namespace Checkpoints
{
void LogCheckpoints( bool yes=true );
void SetCheckpoint( const char *file, int line, const char *message );
2004-10-27 19:49:08 +00:00
void GetLogs( char *pBuf, int iSize, const char *delim );
};
#define CHECKPOINT (Checkpoints::SetCheckpoint(__FILE__, __LINE__, NULL))
#define CHECKPOINT_M(m) (Checkpoints::SetCheckpoint(__FILE__, __LINE__, m))
2003-07-27 03:08:02 +00:00
/* Mutex class that follows the behavior of Windows mutexes: if the same
* thread locks the same mutex twice, we just increase a refcount; a mutex
* is considered unlocked when the refcount reaches zero. This is more
* convenient, though much slower on some archs. (We don't have any tightly-
* coupled threads, so that's OK.) */
2004-06-11 19:24:05 +00:00
class MutexImpl;
class RageMutex
{
2004-10-27 22:12:17 +00:00
public:
2006-01-21 23:01:06 +00:00
RString GetName() const { return m_sName; }
void SetName( const RString &s ) { m_sName = s; }
2004-10-27 22:12:17 +00:00
virtual void Lock();
virtual bool TryLock();
virtual void Unlock();
virtual bool IsLockedByThisThread() const;
2006-01-21 23:01:06 +00:00
RageMutex( const RString &name );
2004-10-27 22:12:17 +00:00
virtual ~RageMutex();
2004-11-07 23:21:45 +00:00
protected:
2004-06-11 19:24:05 +00:00
MutexImpl *m_pMutex;
2006-01-21 23:01:06 +00:00
RString m_sName;
2004-03-21 08:36:43 +00:00
int m_UniqueID;
2004-06-11 19:24:05 +00:00
uint64_t m_LockedBy;
int m_LockCnt;
2004-03-21 08:36:43 +00:00
void MarkLockedMutex();
};
/* Lock a mutex on construction, unlock it on destruction. Helps for functions
* with more than one return path. */
class LockMutex
{
RageMutex &mutex;
2002-12-21 05:13:45 +00:00
const char *file;
int line;
float locked_at;
2002-12-27 22:11:55 +00:00
bool locked;
2002-12-21 05:13:45 +00:00
public:
2002-12-21 05:13:45 +00:00
LockMutex(RageMutex &mut, const char *file, int line);
2002-12-27 23:01:45 +00:00
LockMutex(RageMutex &mut): mutex(mut), file(NULL), line(-1), locked_at(-1), locked(true) { mutex.Lock(); }
2002-12-21 05:13:45 +00:00
~LockMutex();
2002-12-27 23:01:45 +00:00
LockMutex(LockMutex &cpy): mutex(cpy.mutex), file(NULL), line(-1), locked_at(cpy.locked_at), locked(true) { mutex.Lock(); }
2002-12-27 22:11:55 +00:00
/* Unlock the mutex (before this would normally go out of scope). This can
* only be called once. */
void Unlock();
};
2006-10-16 10:34:20 +00:00
#define LockMut(m) LockMutex UNIQUE_NAME(LocalLock) (m, __FILE__, __LINE__)
2002-12-21 05:13:45 +00:00
2004-11-07 23:21:45 +00:00
class EventImpl;
class RageEvent: public RageMutex
{
public:
2006-01-21 23:01:06 +00:00
RageEvent( RString name );
2004-11-07 23:21:45 +00:00
~RageEvent();
2005-01-26 20:59:41 +00:00
/*
* If pTimeout is non-NULL, the event will be automatically signalled at the given
* time. Note that implementing this timeout is optional; not all archs support it.
* If false is returned, the wait timed out (and the mutex is locked, as if the
* event had been signalled).
*/
bool Wait( RageTimer *pTimeout = NULL );
2004-11-07 23:21:45 +00:00
void Signal();
void Broadcast();
bool WaitTimeoutSupported() const;
2004-11-07 23:21:45 +00:00
private:
EventImpl *m_pEvent;
};
2004-06-14 05:29:12 +00:00
class SemaImpl;
class RageSemaphore
{
public:
2006-01-21 23:01:06 +00:00
RageSemaphore( RString sName, int iInitialValue = 0 );
2004-06-14 05:29:12 +00:00
~RageSemaphore();
2006-01-21 23:01:06 +00:00
RString GetName() const { return m_sName; }
2004-06-14 05:29:12 +00:00
int GetValue() const;
void Post();
2004-08-29 22:51:09 +00:00
void Wait( bool bFailOnTimeout=true );
2004-06-14 05:29:12 +00:00
bool TryWait();
private:
SemaImpl *m_pSema;
2006-01-21 23:01:06 +00:00
RString m_sName;
2004-06-14 05:29:12 +00:00
};
#endif
2004-05-06 02:40:33 +00:00
/*
* Copyright (c) 2001-2004 Glenn Maynard
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, and/or sell copies of the Software, and to permit persons to
* whom the Software is furnished to do so, provided that the above
* copyright notice(s) and this permission notice appear in all copies of
* the Software and that both the above copyright notice(s) and this
* permission notice appear in supporting documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/