Skip to content
Snippets Groups Projects
Commit 09ad928f authored by Martin Karsten's avatar Martin Karsten
Browse files

- rename BargingMutex to SpinMutex and add proper barging mutex without atomic spinning

parent 768cec27
No related branches found
No related tags found
No related merge requests found
......@@ -410,8 +410,43 @@ public:
}
};
template<typename Semaphore, bool OwnerLock, size_t SpinStart, size_t SpinEnd>
template<typename Lock, bool OwnerLock = false, typename BQ = BlockingQueue<Lock>>
class BargingMutex {
Lock lock;
StackContext* owner;
BQ bq;
protected:
bool internalAcquire(bool wait, const Time& timeout = Time::zero()) {
StackContext* cs = CurrStack();
for (;;) {
lock.acquire();
if (!owner) break;
if (owner == cs) { GENASSERT1(OwnerLock, FmtHex(owner)); break; }
if (!bq.block(lock, wait, timeout)) return false;
}
owner = cs;
lock.release();
return true;
}
public:
BargingMutex() : owner(nullptr) {}
bool test() { return owner != nullptr; }
bool tryAcquire() { return internalAcquire(false); }
bool acquire(const Time& timeout = Time::zero()) { return internalAcquire(true, timeout); }
void release() {
ScopedLock<Lock> al(lock);
GENASSERT1(owner == CurrStack(), FmtHex(owner));
owner = nullptr;
bq.unblock();
}
};
template<typename Semaphore, bool OwnerLock, size_t SpinStart, size_t SpinEnd>
class SpinMutex {
StackContext* owner;
Semaphore sem;
......@@ -442,7 +477,7 @@ protected:
}
public:
BargingMutex() : owner(nullptr), sem(1) {}
SpinMutex() : owner(nullptr), sem(1) {}
bool test() { return __atomic_load_n(&owner, __ATOMIC_RELAXED) != nullptr; }
bool tryAcquire() { return internalAcquire(false); }
......@@ -480,10 +515,12 @@ public:
template<typename Lock>
#if TESTING_MUTEX_FIFO
class Mutex : public FifoMutex<Lock> {};
#elif TESTING_MUTEX_BARGING
class Mutex : public BargingMutex<Lock> {};
#elif TESTING_MUTEX_SPIN
class Mutex : public BargingMutex<Benaphore<BargingSemaphore<Lock>>, false, 4, 1024> {};
class Mutex : public SpinMutex<Benaphore<BargingSemaphore<Lock>>, false, 4, 1024> {};
#else
class Mutex : public BargingMutex<Benaphore<BargingSemaphore<Lock>>, false, 1, 0> {};
class Mutex : public SpinMutex<Benaphore<BargingSemaphore<Lock>>, false, 1, 0> {};
#endif
// simple blocking RW lock: release alternates; new readers block when writer waits -> no starvation
......
......@@ -20,6 +20,7 @@
//#define TESTING_BLOCKING_CONCURRENT 1 // using MPSC blocking semantics (no prio levels)
//#define TESTING_IDLE_SPIN 128 // spin before idle/halt threshold
//#define TESTING_MUTEX_FIFO 1 // use fifo/baton mutex
//#define TESTING_MUTEX_BARGING 1 // use blocking/barging mutex
//#define TESTING_MUTEX_SPIN 1 // spin before block in non-fifo mutex
//#define TESTING_PLACEMENT_RR 1 // RR placement, instead of load-based staging
#define TESTING_WAKE_CLUSTER 1 // try waking idle processor on cluster backlog
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment