53 #include "CADebugMacros.h"
54 #include "CAException.h"
55 #include "CAHostTimeBase.h"
72 CAMutex::CAMutex(
const char* inName)
78 OSStatus theError = pthread_mutex_init(&mMutex, NULL);
79 ThrowIf(theError != 0, CAException(theError),
"CAMutex::CAMutex: Could not init the mutex");
82 DebugPrintfRtn(DebugPrintfFileComma
"%p %.4f: CAMutex::CAMutex: creating %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), mName, mOwner);
85 mMutex = CreateMutex(NULL,
false, NULL);
86 ThrowIfNULL(mMutex, CAException(GetLastError()),
"CAMutex::CAMutex: could not create the mutex.");
89 DebugPrintfRtn(DebugPrintfFileComma
"%lu %.4f: CAMutex::CAMutex: creating %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), mName, mOwner);
98 DebugPrintfRtn(DebugPrintfFileComma
"%p %.4f: CAMutex::~CAMutex: destroying %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), mName, mOwner);
100 pthread_mutex_destroy(&mMutex);
101 #elif TARGET_OS_WIN32
103 DebugPrintfRtn(DebugPrintfFileComma
"%lu %.4f: CAMutex::~CAMutex: destroying %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), mName, mOwner);
114 bool theAnswer =
false;
117 pthread_t theCurrentThread = pthread_self();
118 if(!pthread_equal(theCurrentThread, mOwner))
121 DebugPrintfRtn(DebugPrintfFileComma
"%p %.4f: CAMutex::Lock: thread %p is locking %s, owner: %p\n", theCurrentThread, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), theCurrentThread, mName, mOwner);
124 #if Log_LongLatencies
125 UInt64 lockTryTime = CAHostTimeBase::GetCurrentTimeInNanos();
128 OSStatus theError = pthread_mutex_lock(&mMutex);
129 ThrowIf(theError != 0, CAException(theError),
"CAMutex::Lock: Could not lock the mutex");
130 mOwner = theCurrentThread;
133 #if Log_LongLatencies
134 UInt64 lockAcquireTime = CAHostTimeBase::GetCurrentTimeInNanos();
135 if (lockAcquireTime - lockTryTime >= LongLatencyThresholdNS)
136 DebugPrintfRtn(DebugPrintfFileComma
"Thread %p took %.6fs to acquire the lock %s\n", theCurrentThread, (lockAcquireTime - lockTryTime) * 1.0e-9 , mName);
140 DebugPrintfRtn(DebugPrintfFileComma
"%p %.4f: CAMutex::Lock: thread %p has locked %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), pthread_self(), mName, mOwner);
143 #elif TARGET_OS_WIN32
144 if(mOwner != GetCurrentThreadId())
147 DebugPrintfRtn(DebugPrintfFileComma
"%lu %.4f: CAMutex::Lock: thread %lu is locking %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
150 OSStatus theError = WaitForSingleObject(mMutex, INFINITE);
151 ThrowIfError(theError, CAException(theError),
"CAMutex::Lock: could not lock the mutex");
152 mOwner = GetCurrentThreadId();
156 DebugPrintfRtn(DebugPrintfFileComma
"%lu %.4f: CAMutex::Lock: thread %lu has locked %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
164 void CAMutex::Unlock()
167 if(pthread_equal(pthread_self(), mOwner))
170 DebugPrintfRtn(DebugPrintfFileComma
"%p %.4f: CAMutex::Unlock: thread %p is unlocking %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), pthread_self(), mName, mOwner);
174 OSStatus theError = pthread_mutex_unlock(&mMutex);
175 ThrowIf(theError != 0, CAException(theError),
"CAMutex::Unlock: Could not unlock the mutex");
178 DebugPrintfRtn(DebugPrintfFileComma
"%p %.4f: CAMutex::Unlock: thread %p has unlocked %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), pthread_self(), mName, mOwner);
183 DebugMessage(
"CAMutex::Unlock: A thread is attempting to unlock a Mutex it doesn't own");
185 #elif TARGET_OS_WIN32
186 if(mOwner == GetCurrentThreadId())
189 DebugPrintfRtn(DebugPrintfFileComma
"%lu %.4f: CAMutex::Unlock: thread %lu is unlocking %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
193 bool wasReleased = ReleaseMutex(mMutex);
194 ThrowIf(!wasReleased, CAException(GetLastError()),
"CAMutex::Unlock: Could not unlock the mutex");
197 DebugPrintfRtn(DebugPrintfFileComma
"%lu %.4f: CAMutex::Unlock: thread %lu has unlocked %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
202 DebugMessage(
"CAMutex::Unlock: A thread is attempting to unlock a Mutex it doesn't own");
207 bool CAMutex::Try(
bool& outWasLocked)
209 bool theAnswer =
false;
210 outWasLocked =
false;
213 pthread_t theCurrentThread = pthread_self();
214 if(!pthread_equal(theCurrentThread, mOwner))
218 DebugPrintfRtn(DebugPrintfFileComma
"%p %.4f: CAMutex::Try: thread %p is try-locking %s, owner: %p\n", theCurrentThread, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), theCurrentThread, mName, mOwner);
222 int theError = pthread_mutex_trylock(&mMutex);
226 mOwner = theCurrentThread;
231 DebugPrintfRtn(DebugPrintfFileComma
"%p %.4f: CAMutex::Try: thread %p has locked %s, owner: %p\n", theCurrentThread, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), theCurrentThread, mName, mOwner);
234 else if(theError == EBUSY)
238 outWasLocked =
false;
241 DebugPrintfRtn(DebugPrintfFileComma
"%p %.4f: CAMutex::Try: thread %p failed to lock %s, owner: %p\n", theCurrentThread, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), theCurrentThread, mName, mOwner);
247 ThrowIfError(theError, CAException(theError),
"CAMutex::Try: call to pthread_mutex_trylock failed");
254 outWasLocked =
false;
256 #elif TARGET_OS_WIN32
257 if(mOwner != GetCurrentThreadId())
261 DebugPrintfRtn(DebugPrintfFileComma
"%lu %.4f: CAMutex::Try: thread %lu is try-locking %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
265 OSStatus theError = WaitForSingleObject(mMutex, 0);
266 if(theError == WAIT_OBJECT_0)
269 mOwner = GetCurrentThreadId();
274 DebugPrintfRtn(DebugPrintfFileComma
"%lu %.4f: CAMutex::Try: thread %lu has locked %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
277 else if(theError == WAIT_TIMEOUT)
281 outWasLocked =
false;
284 DebugPrintfRtn(DebugPrintfFileComma
"%lu %.4f: CAMutex::Try: thread %lu failed to lock %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
290 ThrowIfError(theError, CAException(GetLastError()),
"CAMutex::Try: call to lock the mutex failed");
297 outWasLocked =
false;
304 bool CAMutex::IsFree()
const
309 bool CAMutex::IsOwnedByCurrentThread()
const
311 bool theAnswer =
true;
314 theAnswer = pthread_equal(pthread_self(), mOwner);
315 #elif TARGET_OS_WIN32
316 theAnswer = (mOwner == GetCurrentThreadId());