|
|
@@ -13,9 +13,7 @@ using namespace Framework;
|
|
|
Critical::Critical()
|
|
|
{
|
|
|
InitializeCriticalSection(&cs);
|
|
|
- owner = 0;
|
|
|
lockCount = 0;
|
|
|
- id = (int)time(0);
|
|
|
}
|
|
|
|
|
|
// Destructor
|
|
|
@@ -24,21 +22,11 @@ Critical::~Critical()
|
|
|
DeleteCriticalSection(&cs);
|
|
|
}
|
|
|
|
|
|
-pthread_t CachedCurrentThread()
|
|
|
-{
|
|
|
- volatile thread_local static pthread_t t = GetCurrentThread();
|
|
|
- return (pthread_t)t;
|
|
|
-}
|
|
|
-
|
|
|
// locks the object
|
|
|
void Critical::lock()
|
|
|
{
|
|
|
- getThreadRegister()->lock();
|
|
|
- Thread* tmp = getThreadRegister()->zThread(CachedCurrentThread());
|
|
|
- if (tmp) tmp->addCriticalLock();
|
|
|
- getThreadRegister()->unlock();
|
|
|
+ currentThreadLockCount++;
|
|
|
EnterCriticalSection(&cs);
|
|
|
- if (!owner) owner = tmp;
|
|
|
lockCount++;
|
|
|
}
|
|
|
|
|
|
@@ -46,12 +34,8 @@ void Critical::lock()
|
|
|
bool Critical::tryLock()
|
|
|
{
|
|
|
if (lockCount > 0) return false;
|
|
|
- getThreadRegister()->lock();
|
|
|
- Thread* tmp = getThreadRegister()->zThread(CachedCurrentThread());
|
|
|
- if (tmp) tmp->addCriticalLock();
|
|
|
- getThreadRegister()->unlock();
|
|
|
+ currentThreadLockCount++;
|
|
|
EnterCriticalSection(&cs);
|
|
|
- if (!owner) owner = tmp;
|
|
|
lockCount++;
|
|
|
return true;
|
|
|
}
|
|
|
@@ -59,23 +43,13 @@ bool Critical::tryLock()
|
|
|
// unlocks the object
|
|
|
void Critical::unlock()
|
|
|
{
|
|
|
- getThreadRegister()->lock();
|
|
|
- Thread* tmp = 0;
|
|
|
- if (getThreadRegister()->isThread(owner))
|
|
|
+ if (lockCount <= 0)
|
|
|
{
|
|
|
- if (owner
|
|
|
- && GetThreadId(owner->getThreadHandle())
|
|
|
- != GetThreadId(CachedCurrentThread()))
|
|
|
- throw std::runtime_error("A Thread that does not own a Critical "
|
|
|
- "Object trys to unlock it");
|
|
|
- tmp = owner;
|
|
|
+ throw "A Thread tried to unlock a critical that was not locked before";
|
|
|
}
|
|
|
- getThreadRegister()->unlock();
|
|
|
- if (!--lockCount) owner = 0;
|
|
|
+ lockCount--;
|
|
|
LeaveCriticalSection(&cs);
|
|
|
- getThreadRegister()->lock();
|
|
|
- if (tmp && getThreadRegister()->isThread(tmp)) tmp->removeCriticalLock();
|
|
|
- getThreadRegister()->unlock();
|
|
|
+ currentThreadLockCount--;
|
|
|
}
|
|
|
|
|
|
// returns true if the object is locked
|
|
|
@@ -84,12 +58,6 @@ bool Critical::isLocked() const
|
|
|
return lockCount > 0;
|
|
|
}
|
|
|
|
|
|
-// returns a pointer to the thread that locked the object
|
|
|
-const Thread* Critical::zOwner() const
|
|
|
-{
|
|
|
- return owner;
|
|
|
-}
|
|
|
-
|
|
|
Synchronizer::Synchronizer()
|
|
|
: numWaiting(0),
|
|
|
skip(0)
|
|
|
@@ -153,32 +121,31 @@ int Synchronizer::getNumberOfWaitingThreads() const
|
|
|
return numWaiting;
|
|
|
}
|
|
|
|
|
|
-Framework::CriticalLock::CriticalLock(
|
|
|
- std::initializer_list<Critical*> criticals)
|
|
|
+Framework::StackLock::StackLock(std::initializer_list<Lock*> locks)
|
|
|
{
|
|
|
- this->criticals = new Critical*[criticals.size()];
|
|
|
+ this->locks = new Lock*[locks.size()];
|
|
|
int i = 0;
|
|
|
- for (Critical* c : criticals)
|
|
|
+ for (Lock* c : locks)
|
|
|
{
|
|
|
- this->criticals[i] = c;
|
|
|
+ this->locks[i] = c;
|
|
|
i++;
|
|
|
}
|
|
|
- size = (int)criticals.size();
|
|
|
+ size = (int)locks.size();
|
|
|
if (size > 0)
|
|
|
{
|
|
|
- this->criticals[0]->lock();
|
|
|
+ this->locks[0]->lock();
|
|
|
int index = 1;
|
|
|
while (index < size)
|
|
|
{
|
|
|
- if (!this->criticals[index]->tryLock())
|
|
|
+ if (!this->locks[index]->tryLock())
|
|
|
{
|
|
|
for (int i = 0; i < index; i++)
|
|
|
{
|
|
|
- this->criticals[i]->unlock();
|
|
|
+ this->locks[i]->unlock();
|
|
|
}
|
|
|
- this->criticals[index]->lock();
|
|
|
- this->criticals[index]->unlock();
|
|
|
- this->criticals[0]->lock();
|
|
|
+ this->locks[index]->lock();
|
|
|
+ this->locks[index]->unlock();
|
|
|
+ this->locks[0]->lock();
|
|
|
index = 1;
|
|
|
}
|
|
|
else
|
|
|
@@ -187,13 +154,13 @@ Framework::CriticalLock::CriticalLock(
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-Framework::CriticalLock::~CriticalLock()
|
|
|
+Framework::StackLock::~StackLock()
|
|
|
{
|
|
|
for (int i = 0; i < size; i++)
|
|
|
{
|
|
|
- criticals[i]->unlock();
|
|
|
+ locks[i]->unlock();
|
|
|
}
|
|
|
- delete[] criticals;
|
|
|
+ delete[] locks;
|
|
|
}
|
|
|
|
|
|
class Framework::InternalReadLock : public Lock
|
|
|
@@ -287,6 +254,7 @@ void Framework::ReadWriteLock::lockRead()
|
|
|
cs.lock();
|
|
|
waitingReaders--;
|
|
|
}
|
|
|
+ currentThreadLockCount++;
|
|
|
int index = -1;
|
|
|
for (int i = 0; i < readerThreadCount; i++)
|
|
|
{
|
|
|
@@ -334,6 +302,7 @@ void Framework::ReadWriteLock::lockWrite()
|
|
|
cs.lock();
|
|
|
waitingWriters--;
|
|
|
}
|
|
|
+ currentThreadLockCount++;
|
|
|
writerThread = currentThreadId;
|
|
|
writerCount++;
|
|
|
cs.unlock();
|
|
|
@@ -367,6 +336,7 @@ void Framework::ReadWriteLock::unlockRead()
|
|
|
{
|
|
|
writerBlock.notify();
|
|
|
}
|
|
|
+ currentThreadLockCount--;
|
|
|
cs.unlock();
|
|
|
}
|
|
|
|
|
|
@@ -390,6 +360,7 @@ void Framework::ReadWriteLock::unlockWrite()
|
|
|
readerBlock.notify(waitingReaders);
|
|
|
}
|
|
|
}
|
|
|
+ currentThreadLockCount--;
|
|
|
cs.unlock();
|
|
|
}
|
|
|
|
|
|
@@ -401,6 +372,7 @@ bool Framework::ReadWriteLock::tryLockRead()
|
|
|
cs.unlock();
|
|
|
return false;
|
|
|
}
|
|
|
+ currentThreadLockCount++;
|
|
|
int index = -1;
|
|
|
for (int i = 0; i < readerThreadCount; i++)
|
|
|
{
|
|
|
@@ -445,6 +417,7 @@ bool Framework::ReadWriteLock::tryLockWrite()
|
|
|
cs.unlock();
|
|
|
return false;
|
|
|
}
|
|
|
+ currentThreadLockCount++;
|
|
|
writerThread = currentThreadId;
|
|
|
writerCount++;
|
|
|
cs.unlock();
|