1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
|
#include "stdafx.h"
#include "Lock.h"
namespace storm {
Lock::Lock() : alloc(new Data()) {}
Lock::Lock(const Lock &o) : alloc(o.alloc) {
atomicIncrement(alloc->refs);
}
Lock::~Lock() {
if (atomicDecrement(alloc->refs) == 0) {
// Last one remaining!
delete alloc;
}
}
void Lock::deepCopy(CloneEnv *) {
// Nothing to do.
}
void Lock::lock() {
size_t owner = (size_t)os::UThread::current().threadData();
if (atomicRead(alloc->owner) == owner) {
// We've already locked this lock.
alloc->recursion++;
} else {
// That was not us. Lock properly.
alloc->sema.down();
alloc->owner = owner;
alloc->recursion = 1;
}
}
void Lock::unlock() {
assert((size_t)os::UThread::current().threadData() == alloc->owner, L"Attempting to unlock from wrong thread!");
if (--alloc->recursion == 0) {
alloc->owner = 0;
alloc->sema.up();
}
}
Lock::Guard::Guard(Lock *l) : lock(l) {
lock->lock();
}
Lock::Guard::~Guard() {
lock->unlock();
}
Lock::Guard::Guard(const Guard &o) : lock(o.lock) {
lock->lock();
}
Lock::Guard &Lock::Guard::operator =(const Guard &o) {
if (&o == this)
return *this;
lock->unlock();
lock = o.lock;
lock->lock();
return *this;
}
Lock::Data::Data() : refs(1), owner(0), recursion(0), sema(1) {}
}
|