From 22fe9d684138c3308cd68c3143b1599b954d5902 Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Mon, 14 Jun 2004 05:29:12 +0000 Subject: [PATCH] RageSemaphore --- stepmania/src/RageThreads.cpp | 61 +++++++++++++++++++++++++++++++++++ stepmania/src/RageThreads.h | 20 ++++++++++++ 2 files changed, 81 insertions(+) diff --git a/stepmania/src/RageThreads.cpp b/stepmania/src/RageThreads.cpp index fe16f93d96..801ef6b627 100644 --- a/stepmania/src/RageThreads.cpp +++ b/stepmania/src/RageThreads.cpp @@ -547,6 +547,22 @@ void RageMutex::Lock() // MarkLockedMutex(); } +bool RageMutex::TryLock() +{ + if( m_LockedBy == (uint64_t) GetThisThreadId() ) + { + ++m_LockCnt; + return true; + } + + if( !m_pMutex->TryLock() ) + return false; + + m_LockedBy = GetThisThreadId(); + + return true; +} + void RageMutex::Unlock() { if( m_LockCnt ) @@ -596,6 +612,51 @@ void LockMutex::Unlock() } } +RageSemaphore::RageSemaphore( CString sName, int iInitialValue ): + m_sName( sName ) +{ + m_pSema = MakeSemaphore( iInitialValue ); +} + +RageSemaphore::~RageSemaphore() +{ + delete m_pSema; +} + +int RageSemaphore::GetValue() const +{ + return m_pSema->GetValue(); +} + +void RageSemaphore::Post() +{ + m_pSema->Post(); +} + +void RageSemaphore::Wait() +{ + if( m_pSema->Wait() ) + return; + + /* We waited too long. We're probably deadlocked, though unlike mutexes, we can't + * tell which thread we're stuck on. */ +#if defined(CRASH_HANDLER) + const ThreadSlot *ThisSlot = GetThreadSlotFromID( GetThisThreadId() ); + const CString sReason = ssprintf( "Semaphore timeout on mutex %s on thread %s", + GetName().c_str(), ThisSlot? ThisSlot->GetThreadName(): "(???" ")" ); // stupid trigraph warnings + + ForceCrashHandler( sReason ); +#else + RageException::Throw( "%s", sReason.c_str() ); +#endif +} + +bool RageSemaphore::TryWait() +{ + return m_pSema->TryWait(); +} + + /* * Copyright (c) 2001-2004 Glenn Maynard * All rights reserved. diff --git a/stepmania/src/RageThreads.h b/stepmania/src/RageThreads.h index b5d3403594..b3ce4b39d6 100644 --- a/stepmania/src/RageThreads.h +++ b/stepmania/src/RageThreads.h @@ -61,6 +61,7 @@ public: CString GetName() const { return m_sName; } void SetName( const CString &s ) { m_sName = s; } void Lock(); + bool TryLock(); void Unlock(); bool IsLockedByThisThread() const; @@ -90,6 +91,7 @@ public: void Unlock(); }; + /* Double-abstracting __LINE__ lets us append it to other text, to generate * locally unique variable names. (Otherwise we get "LocalLock__LINE__".) I'm * not sure why this works, but it does, in both VC and GCC. */ @@ -117,6 +119,24 @@ public: #define LockMut(m) LockMutex LocalLock(m, __FUNCTION__, __LINE__) #endif +class SemaImpl; +class RageSemaphore +{ +public: + RageSemaphore( CString sName, int iInitialValue = 0 ); + ~RageSemaphore(); + + CString GetName() const { return m_sName; } + int GetValue() const; + void Post(); + void Wait(); + bool TryWait(); + +private: + SemaImpl *m_pSema; + CString m_sName; +}; + #endif /*