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

- separate BargingSemaphore class into benaphore and proper barging semaphore elements

parent a1dcb5a8
No related branches found
No related tags found
No related merge requests found
...@@ -34,9 +34,12 @@ public: ...@@ -34,9 +34,12 @@ public:
sem.reset(0); sem.reset(0);
} }
bool P() { template<typename... Args>
if (__atomic_sub_fetch(&counter, 1, __ATOMIC_SEQ_CST) < 0) return sem.P(); bool P(const Args&... a) {
return true; if (__atomic_sub_fetch(&counter, 1, __ATOMIC_SEQ_CST) >= 0) return true;
if (sem.P(a...)) return true;
V();
return false;
} }
void V() { void V() {
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#ifndef _BlockingSync_h_ #ifndef _BlockingSync_h_
#define _BlockingSync_h_ 1 #define _BlockingSync_h_ 1
#include "generic/Benaphore.h"
#include "runtime/StackContext.h" #include "runtime/StackContext.h"
#include <list> #include <list>
...@@ -183,7 +184,7 @@ inline void TimerQueueGeneric<Lock>::checkExpiry(const Time& now) { ...@@ -183,7 +184,7 @@ inline void TimerQueueGeneric<Lock>::checkExpiry(const Time& now) {
lock.release(); lock.release();
for (auto f : fireList) { // timeout lock released for (auto f : fireList) { // timeout lock released
f.second->cancelSync(f.first); // can acquire event locks f.second->cancelSync(f.first); // can acquire event locks
f.first->resume(); f.first->resume<true>();
Runtime::debugB( "Stack ", FmtHex(f.first), " timed out"); Runtime::debugB( "Stack ", FmtHex(f.first), " timed out");
} }
} }
...@@ -323,43 +324,36 @@ public: ...@@ -323,43 +324,36 @@ public:
template<typename Lock, typename BQ = BlockingQueue<Lock>> template<typename Lock, typename BQ = BlockingQueue<Lock>>
class BargingSemaphore { class BargingSemaphore {
ssize_t counter;
Lock lock; Lock lock;
ssize_t waiters; ssize_t counter;
BQ bq; BQ bq;
bool internalP(bool wait, const Time& timeout = Time::zero()) { bool internalP(bool wait, const Time& timeout = Time::zero()) {
if (__atomic_sub_fetch(&counter, 1, __ATOMIC_SEQ_CST) >= 0) return true; for (;;) {
lock.acquire(); lock.acquire();
waiters += 1; if (counter >= 1) break;
if (waiters > 0) { if (!bq.block(lock, wait, timeout)) return false;
if (!bq.block(lock, wait, timeout)) {
internalV();
return false;
}
} else {
lock.release();
} }
counter -= 1;
lock.release();
return true; return true;
} }
StackContext* internalV(bool resumeNow = true) { StackContext* internalV(bool resumeNow = true) {
if (__atomic_add_fetch(&counter, 1, __ATOMIC_SEQ_CST) > 0) return nullptr;
ScopedLock<Lock> al(lock); ScopedLock<Lock> al(lock);
waiters -= 1; counter += 1;
return bq.unblock(resumeNow); return bq.unblock(resumeNow);
} }
public: public:
explicit BargingSemaphore(ssize_t c = 0) : counter(c), waiters(0) {} explicit BargingSemaphore(ssize_t c = 0) : counter(0) {}
bool empty() { return bq.empty(); } bool empty() { return bq.empty(); }
bool open() { return getValue() >= 1; } bool open() { return getValue() >= 1; }
ssize_t getValue() { return __atomic_load_n(&counter, __ATOMIC_RELAXED); } ssize_t getValue() { return counter; }
void reset(ssize_t c = 0) { void reset(ssize_t c = 0) {
lock.acquire(); lock.acquire();
counter = c; counter = c;
waiters = 0;
bq.clear(lock); bq.clear(lock);
} }
...@@ -416,7 +410,7 @@ public: ...@@ -416,7 +410,7 @@ public:
} }
}; };
template<typename Semaphore, bool OwnerLock = false, size_t SpinStart = 4, size_t SpinEnd = 1024> template<typename Semaphore, bool OwnerLock, size_t SpinStart, size_t SpinEnd>
class BargingMutex { class BargingMutex {
StackContext* owner; StackContext* owner;
Semaphore sem; Semaphore sem;
...@@ -487,9 +481,9 @@ template<typename Lock> ...@@ -487,9 +481,9 @@ template<typename Lock>
#if TESTING_MUTEX_FIFO #if TESTING_MUTEX_FIFO
class Mutex : public FifoMutex<Lock> {}; class Mutex : public FifoMutex<Lock> {};
#elif TESTING_MUTEX_SPIN #elif TESTING_MUTEX_SPIN
class Mutex : public BargingMutex<BargingSemaphore<Lock>> {}; class Mutex : public BargingMutex<Benaphore<BargingSemaphore<Lock>>, false, 4, 1024> {};
#else #else
class Mutex : public BargingMutex<BargingSemaphore<Lock>, false, 1, 0> {}; class Mutex : public BargingMutex<Benaphore<BargingSemaphore<Lock>>, false, 1, 0> {};
#endif #endif
// simple blocking RW lock: release alternates; new readers block when writer waits -> no starvation // simple blocking RW lock: release alternates; new readers block when writer waits -> no starvation
......
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