123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- #include "Critical.h"
- #include <iostream>
- #include <time.h>
- #include "Globals.h"
- #include "Thread.h"
- using namespace Framework;
- // Inhalt der Critical class aus Critical.h
- // Konstructor
- Critical::Critical()
- {
- InitializeCriticalSection(&cs);
- owner = 0;
- lockCount = 0;
- id = (int)time(0);
- }
- // Destructor
- Critical::~Critical()
- {
- DeleteCriticalSection(&cs);
- }
- pthread_t CachedCurrentThread()
- {
- volatile thread_local static pthread_t t = GetCurrentThread();
- return (pthread_t)t;
- }
- // sperrt das Objekt
- void Critical::lock()
- {
- getThreadRegister()->lock();
- Thread* tmp = getThreadRegister()->zThread(CachedCurrentThread());
- if (tmp) tmp->addCriticalLock();
- getThreadRegister()->unlock();
- EnterCriticalSection(&cs);
- if (!owner) owner = tmp;
- lockCount++;
- }
- // versucht das Objekt zu sperren
- bool Critical::tryLock()
- {
- if (lockCount > 0) return false;
- getThreadRegister()->lock();
- Thread* tmp = getThreadRegister()->zThread(CachedCurrentThread());
- if (tmp) tmp->addCriticalLock();
- getThreadRegister()->unlock();
- EnterCriticalSection(&cs);
- if (!owner) owner = tmp;
- lockCount++;
- return true;
- }
- // entsperrt das Objekt
- void Critical::unlock()
- {
- getThreadRegister()->lock();
- Thread* tmp = 0;
- if (getThreadRegister()->isThread(owner))
- {
- 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;
- }
- getThreadRegister()->unlock();
- if (!--lockCount) owner = 0;
- LeaveCriticalSection(&cs);
- getThreadRegister()->lock();
- if (tmp && getThreadRegister()->isThread(tmp)) tmp->removeCriticalLock();
- getThreadRegister()->unlock();
- }
- // gibt true zurück, wenn das Objekt gesperrt ist
- bool Critical::isLocked() const
- {
- return lockCount > 0;
- }
- // gibt einen Zeiger auf den Thread zurück, der das Objekt gesperrt hat
- const Thread* Critical::zOwner() const
- {
- return owner;
- }
- Synchronizer::Synchronizer()
- : numWaiting(0),
- skip(0)
- {}
- Synchronizer::~Synchronizer()
- {
- skip = 1;
- std::unique_lock<std::mutex> lk(mutex);
- if (numWaiting > 0)
- {
- lk.unlock();
- block.notify_all();
- }
- else
- lk.unlock();
- while (numWaiting > 0)
- Sleep(10);
- lk.lock();
- }
- bool Synchronizer::wait()
- {
- std::unique_lock<std::mutex> lk(mutex);
- if (skip) return false;
- numWaiting++;
- block.wait(lk);
- numWaiting--;
- return !skip;
- }
- bool Synchronizer::wait(int milisec)
- {
- std::unique_lock<std::mutex> lk(mutex);
- if (skip) return false;
- numWaiting++;
- std::cv_status status
- = block.wait_for(lk, std::chrono::milliseconds(milisec));
- numWaiting--;
- return !skip && status == std::cv_status::no_timeout;
- }
- void Synchronizer::notify()
- {
- block.notify_one();
- }
- void Synchronizer::notify(int amount)
- {
- while (amount--)
- block.notify_one();
- }
- void Synchronizer::notifyAll()
- {
- block.notify_all();
- }
- int Synchronizer::getNumberOfWaitingThreads() const
- {
- return numWaiting;
- }
- Framework::CriticalLock::CriticalLock(Critical* critical)
- {
- this->critical = critical;
- critical->lock();
- }
- Framework::CriticalLock::~CriticalLock()
- {
- critical->unlock();
- }
|