diff --git a/.dir-locals.el b/.dir-locals.el-disabled similarity index 100% rename from .dir-locals.el rename to .dir-locals.el-disabled diff --git a/emper/CMakeLists.txt b/emper/CMakeLists.txt index 946a1042496ffab53ccf786c82f8364cc91fcb31..62472c71c7b5533d05e38243094a1a8330561472 100644 --- a/emper/CMakeLists.txt +++ b/emper/CMakeLists.txt @@ -12,6 +12,7 @@ add_files(EMPER_SOURCE ContextManager.cpp) add_files(EMPER_SOURCE BinaryPrivateSemaphore.cpp) add_files(EMPER_SOURCE CountingPrivateSemaphore.cpp) add_files(EMPER_SOURCE Fibril.cpp) +add_files(EMPER_SOURCE Semaphore.cpp) add_files(EMPER_INCLUDE ".") add_files(EMPER_INCLUDE "include") diff --git a/emper/Semaphore.cpp b/emper/Semaphore.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d6df0b442c9b9d5eddec7056548929d8fce3a193 --- /dev/null +++ b/emper/Semaphore.cpp @@ -0,0 +1,17 @@ +#include "Semaphore.hpp" + +using namespace emper; + +void Semaphore::print() { + unsigned int count = this->count; + unsigned int waiterListSize; + { + const std::lock_guard<std::mutex> lock(mutex); + waiterListSize = waiterList.size(); + } + + std::cout << "Semaphore" + << " count=" << count + << " waiterListSize=" << waiterListSize + << std::endl; +} diff --git a/emper/Semaphore.hpp b/emper/Semaphore.hpp new file mode 100644 index 0000000000000000000000000000000000000000..83b13d09892729cb2523a7d026d7f23225426dd0 --- /dev/null +++ b/emper/Semaphore.hpp @@ -0,0 +1,53 @@ +#pragma once + +#include <queue> +#include <mutex> + +#include "BinaryPrivateSemaphore.hpp" + +namespace emper { + +class Semaphore { +private: + + std::queue<BinaryPrivateSemaphore*> waiterList; + unsigned int count; + std::mutex mutex; + +public: + bool acquire() { + bool blocked; + mutex.lock(); + if (count > 0) { + count--; + mutex.unlock(); + blocked = false; + } else { + BinaryPrivateSemaphore semaphore; + waiterList.push(&semaphore); + mutex.unlock(); + semaphore.wait(); + blocked = true; + } + return blocked; + } + + bool release() { + mutex.lock(); + bool waiterListEmpty = waiterList.empty(); + if (waiterListEmpty) { + count++; + mutex.unlock(); + } else { + BinaryPrivateSemaphore* semaphore = waiterList.front(); + waiterList.pop(); + mutex.unlock(); + semaphore->signal(); + } + return waiterListEmpty; + } + + void print(); +}; + +} diff --git a/emper/lib/adt/WsClQueue.hpp b/emper/lib/adt/WsClQueue.hpp index 881fff3745607d06aa240f2c3fca331438f1a4f1..ec90f9196eb9a047c4af193d471c9a95a6b7bd07 100644 --- a/emper/lib/adt/WsClQueue.hpp +++ b/emper/lib/adt/WsClQueue.hpp @@ -109,6 +109,11 @@ bool WsClQueue<_PAYLOAD, _CAPACITY>::popBottom(_PAYLOAD *item) { // bool res = top.compare_exchange_weak(localTop, localTop + 1, std::memory_order_release, std::memory_order_relaxed); bool res = top.compare_exchange_weak(localTop, localTop + 1); + // Either a popTop() removed the element ('res' is false) or we + // removed the element ('res' is true), but we need to increment + // the 'bottom' value, since the element bottom pointed at is now + // gone. N.B. bottom does point to the next free slot, the actual + // element we remove is bottom-1. bottom = localBottom + 1; return res; } diff --git a/emper/lib/adt/WsClV2Queue.hpp b/emper/lib/adt/WsClV2Queue.hpp index 64cb6e0aec40631fb2a58221a46a4a593fb2e003..102f8867570f48f724543f4f3ff26004556e70d1 100644 --- a/emper/lib/adt/WsClV2Queue.hpp +++ b/emper/lib/adt/WsClV2Queue.hpp @@ -100,8 +100,12 @@ bool WsClV2Queue<ITEM_TYPE, CAPACITY>::popBottom(ITEM_TYPE *item) { if (localBottom > localTop) return true; bool res = top.compare_exchange_weak(localTop, localTop + 1, std::memory_order_release, std::memory_order_relaxed); - // TODO: Why do we reset bottom here? - bottom = localTop + 1; + // Either a popTop() removed the element ('res' is false) or we + // removed the element ('res' is true), but we need to increment + // the 'bottom' value, since the element bottom pointed at is now + // gone. N.B. bottom does point to the next free slot, the actual + // element we remove is bottom-1. + bottom = localBottom + 1; return res; } diff --git a/emper/lib/sync/Latch.hpp b/emper/lib/sync/Latch.hpp index 04e40e5fe5a8195096137834ecaf897f6f11b3f2..2eb144cd3f72a55e65c48111f16e62a1078d88bc 100644 --- a/emper/lib/sync/Latch.hpp +++ b/emper/lib/sync/Latch.hpp @@ -8,7 +8,7 @@ class Latch { private: const unsigned int num; std::atomic<unsigned int> counter; - Semaphore semaphore; + emper::lib::sync::Semaphore semaphore; public: Latch(unsigned int counter) : num(counter), counter(counter), semaphore(0) { diff --git a/emper/lib/sync/Semaphore.hpp b/emper/lib/sync/Semaphore.hpp index a8653daa4bc3583f450866f0da950993902db235..46be64ecdccf2b37bea7dfea2909b00b1640d59d 100644 --- a/emper/lib/sync/Semaphore.hpp +++ b/emper/lib/sync/Semaphore.hpp @@ -3,6 +3,12 @@ #include <mutex> #include <condition_variable> +namespace emper { + +namespace lib { + +namespace sync { + class Semaphore { private: std::mutex m; @@ -32,3 +38,8 @@ public: } }; +} + +} + +}