diff --git a/include/etl/queue_spsc_isr.h b/include/etl/queue_spsc_isr.h index e4918ad7..838e356f 100644 --- a/include/etl/queue_spsc_isr.h +++ b/include/etl/queue_spsc_isr.h @@ -39,6 +39,7 @@ SOFTWARE. #include "parameter_type.h" #include "memory_model.h" #include "integral_limits.h" +#include "function.h" #undef ETL_FILE #define ETL_FILE "46" @@ -390,14 +391,10 @@ namespace etl ///\ingroup queue_spsc ///\brief This is the base for all queue_spsc_isrs that contain a particular type. ///\details Normally a reference to this type will be taken from a derived queue_spsc_isr. - ///\code - /// etl::queue_spsc_isr_isr myQueue; - /// etl::iqueue_isr& iQueue = myQueue; - ///\endcode /// This queue supports concurrent access by one producer and one consumer. /// \tparam T The type of value that the queue_spsc_isr holds. //*************************************************************************** - template + template class iqueue_spsc_isr : public queue_spsc_isr_base { private: @@ -417,11 +414,11 @@ namespace etl //************************************************************************* bool push(parameter_t value) { - TAccess::lock(); + lock(); bool result = this->push_implementation(value); - TAccess::unlock(); + unlock(); return result; } @@ -434,11 +431,11 @@ namespace etl template bool emplace(Args&&... args) { - TAccess::lock(); + lock(); bool result = this->emplace_implementation(std::forward(args)...); - TAccess::unlock(); + unlock(); return result; } @@ -450,11 +447,11 @@ namespace etl template bool emplace(const T1& value1) { - TAccess::lock(); + lock(); bool result = this->emplace_implementation(value1); - TAccess::unlock(); + unlock(); return result; } @@ -466,11 +463,11 @@ namespace etl template bool emplace(const T1& value1, const T2& value2) { - TAccess::lock(); + lock(); bool result = this->emplace_implementation(value1, value2); - TAccess::unlock(); + unlock(); return result; } @@ -482,11 +479,11 @@ namespace etl template bool emplace(const T1& value1, const T2& value2, const T3& value3) { - TAccess::lock(); + lock(); bool result = this->emplace_implementation(value1, value2, value3); - TAccess::unlock(); + unlock(); return result; } @@ -498,11 +495,11 @@ namespace etl template bool emplace(const T1& value1, const T2& value2, const T3& value3, const T4& value4) { - TAccess::lock(); + lock(); bool result = this->emplace_implementation(value1, value2, value3, value4); - TAccess::unlock(); + unlock(); return result; } @@ -513,11 +510,11 @@ namespace etl //************************************************************************* bool pop(reference value) { - TAccess::lock(); + lock(); bool result = this->pop_implementation(value); - TAccess::unlock(); + unlock(); return result; } @@ -527,11 +524,11 @@ namespace etl //************************************************************************* bool pop() { - TAccess::lock(); + lock(); bool result = this->pop_implementation(); - TAccess::unlock(); + unlock(); return result; } @@ -541,14 +538,14 @@ namespace etl //************************************************************************* void clear() { - TAccess::lock(); + lock(); while (this->pop_implementation()) { // Do nothing. } - TAccess::unlock(); + unlock(); } //************************************************************************* @@ -556,11 +553,11 @@ namespace etl //************************************************************************* bool empty() const { - TAccess::lock(); + lock(); size_type result = (this->current_size == 0); - TAccess::unlock(); + unlock(); return result; } @@ -570,11 +567,11 @@ namespace etl //************************************************************************* bool full() const { - TAccess::lock(); + lock(); size_type result = (this->current_size == this->MAX_SIZE); - TAccess::unlock(); + unlock(); return result; } @@ -584,11 +581,11 @@ namespace etl //************************************************************************* size_type size() const { - TAccess::lock(); + lock(); size_type result = this->current_size; - TAccess::unlock(); + unlock(); return result; } @@ -598,11 +595,11 @@ namespace etl //************************************************************************* size_type available() const { - TAccess::lock(); + lock(); size_type result = this->MAX_SIZE - this->current_size; - TAccess::unlock(); + unlock(); return result; } @@ -612,8 +609,10 @@ namespace etl //************************************************************************* /// The constructor that is called from derived classes. //************************************************************************* - iqueue_spsc_isr(T* p_buffer_, size_type max_size_) + iqueue_spsc_isr(T* p_buffer_, size_type max_size_, etl::ifunction& lock_, etl::ifunction& unlock_) : base_t(p_buffer_, max_size_) + , lock(lock_) + , unlock(unlock_) { } @@ -623,7 +622,8 @@ namespace etl iqueue_spsc_isr(const iqueue_spsc_isr&); iqueue_spsc_isr& operator =(const iqueue_spsc_isr&); - TAccess access; ///< The object that locks/unlocks interrupts. + etl::ifunction& lock; ///< The callback that locks interrupts. + etl::ifunction& unlock; ///< The callback that unlocks interrupts. }; //*************************************************************************** @@ -632,15 +632,14 @@ namespace etl /// This queue supports concurrent access by one producer and one consumer. /// \tparam T The type this queue should support. /// \tparam SIZE The maximum capacity of the queue. - /// \tparam TAccess The type that will lock and unlock interrupts. /// \tparam MEMORY_MODEL The memory model for the queue. Determines the type of the internal counter variables. //*************************************************************************** - template - class queue_spsc_isr : public etl::iqueue_spsc_isr + template + class queue_spsc_isr : public etl::iqueue_spsc_isr { private: - typedef etl::iqueue_spsc_isr base_t; + typedef etl::iqueue_spsc_isr base_t; public: @@ -653,8 +652,9 @@ namespace etl //************************************************************************* /// Default constructor. //************************************************************************* - queue_spsc_isr() - : base_t(reinterpret_cast(&buffer[0]), MAX_SIZE) + queue_spsc_isr(etl::ifunction& lock, + etl::ifunction& unlock) + : base_t(reinterpret_cast(&buffer[0]), MAX_SIZE, lock, unlock) { } diff --git a/test/test_queue_spsc_isr.cpp b/test/test_queue_spsc_isr.cpp index 56516beb..ed465660 100644 --- a/test/test_queue_spsc_isr.cpp +++ b/test/test_queue_spsc_isr.cpp @@ -29,6 +29,7 @@ SOFTWARE. #include "UnitTest++.h" #include "etl/queue_spsc_isr.h" +#include "etl/function.h" #include #include @@ -46,44 +47,46 @@ namespace { public: - static void clear() + void clear() { - called_lock = false; + called_lock = false; called_unlock = false; } - static void lock() + void lock() { called_lock = true; } - static void unlock() + void unlock() { called_unlock = true; } - static bool called_lock; - static bool called_unlock; + bool called_lock; + bool called_unlock; }; - bool Access::called_lock; - bool Access::called_unlock; + Access access; + + etl::function_imv lock; + etl::function_imv unlock; struct Data { Data(int a_, int b_ = 2, int c_ = 3, int d_ = 4) : a(a_), - b(b_), - c(c_), - d(d_) + b(b_), + c(c_), + d(d_) { } Data() : a(0), - b(0), - c(0), - d(0) + b(0), + c(0), + d(0) { } @@ -103,121 +106,121 @@ namespace //************************************************************************* TEST(test_constructor) { - Access::clear(); + access.clear(); - etl::queue_spsc_isr queue; + etl::queue_spsc_isr queue(lock, unlock); CHECK_EQUAL(4U, queue.max_size()); CHECK_EQUAL(4U, queue.capacity()); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); } //************************************************************************* TEST(test_size_push_pop) { - Access::clear(); + access.clear(); - etl::queue_spsc_isr queue; + etl::queue_spsc_isr queue(lock, unlock); CHECK_EQUAL(0U, queue.size_from_isr()); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); - Access::clear(); + access.clear(); CHECK_EQUAL(4U, queue.available_from_isr()); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); - Access::clear(); + access.clear(); CHECK_EQUAL(0U, queue.size()); - CHECK(Access::called_lock); - CHECK(Access::called_unlock); + CHECK(access.called_lock); + CHECK(access.called_unlock); - Access::clear(); + access.clear(); CHECK_EQUAL(4U, queue.available()); - CHECK(Access::called_lock); - CHECK(Access::called_unlock); + CHECK(access.called_lock); + CHECK(access.called_unlock); - Access::clear(); + access.clear(); queue.push_from_isr(1); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); CHECK_EQUAL(1U, queue.size_from_isr()); CHECK_EQUAL(3U, queue.available_from_isr()); - Access::clear(); + access.clear(); queue.push(2); - CHECK(Access::called_lock); - CHECK(Access::called_unlock); + CHECK(access.called_lock); + CHECK(access.called_unlock); CHECK_EQUAL(2U, queue.size_from_isr()); CHECK_EQUAL(2U, queue.available_from_isr()); - Access::clear(); + access.clear(); queue.push(3); - CHECK(Access::called_lock); - CHECK(Access::called_unlock); + CHECK(access.called_lock); + CHECK(access.called_unlock); CHECK_EQUAL(3U, queue.size_from_isr()); CHECK_EQUAL(1U, queue.available_from_isr()); - Access::clear(); + access.clear(); queue.push(4); - CHECK(Access::called_lock); - CHECK(Access::called_unlock); + CHECK(access.called_lock); + CHECK(access.called_unlock); CHECK_EQUAL(4U, queue.size_from_isr()); CHECK_EQUAL(0U, queue.available_from_isr()); - Access::clear(); + access.clear(); CHECK(!queue.push(5)); CHECK(!queue.push_from_isr(5)); - Access::clear(); + access.clear(); int i; CHECK(queue.pop(i)); CHECK_EQUAL(1, i); - CHECK(Access::called_lock); - CHECK(Access::called_unlock); + CHECK(access.called_lock); + CHECK(access.called_unlock); CHECK_EQUAL(3U, queue.size_from_isr()); - Access::clear(); + access.clear(); CHECK(queue.pop_from_isr(i)); CHECK_EQUAL(2, i); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); CHECK_EQUAL(2U, queue.size_from_isr()); - Access::clear(); + access.clear(); CHECK(queue.pop_from_isr(i)); CHECK_EQUAL(3, i); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); CHECK_EQUAL(1U, queue.size_from_isr()); - Access::clear(); + access.clear(); CHECK(queue.pop_from_isr(i)); CHECK_EQUAL(4, i); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); CHECK_EQUAL(0U, queue.size_from_isr()); - Access::clear(); + access.clear(); CHECK(!queue.pop(i)); CHECK(!queue.pop_from_isr(i)); @@ -226,92 +229,92 @@ namespace //************************************************************************* TEST(test_size_push_pop_iqueue) { - Access::clear(); + access.clear(); - etl::queue_spsc_isr queue; + etl::queue_spsc_isr queue(lock, unlock); - etl::iqueue_spsc_isr& iqueue = queue; + etl::iqueue_spsc_isr& iqueue = queue; CHECK_EQUAL(0U, iqueue.size_from_isr()); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); - Access::clear(); + access.clear(); CHECK_EQUAL(0U, iqueue.size()); - CHECK(Access::called_lock); - CHECK(Access::called_unlock); + CHECK(access.called_lock); + CHECK(access.called_unlock); - Access::clear(); + access.clear(); iqueue.push_from_isr(1); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); CHECK_EQUAL(1U, iqueue.size_from_isr()); - Access::clear(); + access.clear(); iqueue.push(2); - CHECK(Access::called_lock); - CHECK(Access::called_unlock); + CHECK(access.called_lock); + CHECK(access.called_unlock); CHECK_EQUAL(2U, iqueue.size_from_isr()); - Access::clear(); + access.clear(); iqueue.push(3); - CHECK(Access::called_lock); - CHECK(Access::called_unlock); + CHECK(access.called_lock); + CHECK(access.called_unlock); CHECK_EQUAL(3U, iqueue.size_from_isr()); - Access::clear(); + access.clear(); iqueue.push(4); - CHECK(Access::called_lock); - CHECK(Access::called_unlock); + CHECK(access.called_lock); + CHECK(access.called_unlock); CHECK_EQUAL(4U, iqueue.size_from_isr()); - Access::clear(); + access.clear(); CHECK(!iqueue.push(5)); CHECK(!iqueue.push_from_isr(5)); - Access::clear(); + access.clear(); int i; CHECK(iqueue.pop(i)); CHECK_EQUAL(1, i); - CHECK(Access::called_lock); - CHECK(Access::called_unlock); + CHECK(access.called_lock); + CHECK(access.called_unlock); CHECK_EQUAL(3U, iqueue.size_from_isr()); - Access::clear(); + access.clear(); CHECK(iqueue.pop_from_isr(i)); CHECK_EQUAL(2, i); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); CHECK_EQUAL(2U, iqueue.size_from_isr()); - Access::clear(); + access.clear(); CHECK(iqueue.pop_from_isr(i)); CHECK_EQUAL(3, i); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); CHECK_EQUAL(1U, iqueue.size_from_isr()); - Access::clear(); + access.clear(); CHECK(iqueue.pop_from_isr(i)); CHECK_EQUAL(4, i); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); CHECK_EQUAL(0U, iqueue.size_from_isr()); - Access::clear(); + access.clear(); CHECK(!iqueue.pop(i)); CHECK(!iqueue.pop_from_isr(i)); @@ -320,84 +323,84 @@ namespace //************************************************************************* TEST(test_size_push_pop_void) { - Access::clear(); + access.clear(); - etl::queue_spsc_isr queue; + etl::queue_spsc_isr queue(lock, unlock); CHECK_EQUAL(0U, queue.size_from_isr()); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); - Access::clear(); + access.clear(); CHECK_EQUAL(0U, queue.size()); - CHECK(Access::called_lock); - CHECK(Access::called_unlock); + CHECK(access.called_lock); + CHECK(access.called_unlock); - Access::clear(); + access.clear(); queue.push_from_isr(1); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); CHECK_EQUAL(1U, queue.size_from_isr()); - Access::clear(); + access.clear(); queue.push(2); - CHECK(Access::called_lock); - CHECK(Access::called_unlock); + CHECK(access.called_lock); + CHECK(access.called_unlock); CHECK_EQUAL(2U, queue.size_from_isr()); - Access::clear(); + access.clear(); queue.push(3); - CHECK(Access::called_lock); - CHECK(Access::called_unlock); + CHECK(access.called_lock); + CHECK(access.called_unlock); CHECK_EQUAL(3U, queue.size_from_isr()); - Access::clear(); + access.clear(); queue.push(4); - CHECK(Access::called_lock); - CHECK(Access::called_unlock); + CHECK(access.called_lock); + CHECK(access.called_unlock); CHECK_EQUAL(4U, queue.size_from_isr()); - Access::clear(); + access.clear(); CHECK(!queue.push(5)); CHECK(!queue.push_from_isr(5)); - Access::clear(); + access.clear(); CHECK(queue.pop()); - CHECK(Access::called_lock); - CHECK(Access::called_unlock); + CHECK(access.called_lock); + CHECK(access.called_unlock); CHECK_EQUAL(3U, queue.size_from_isr()); - Access::clear(); + access.clear(); CHECK(queue.pop_from_isr()); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); CHECK_EQUAL(2U, queue.size_from_isr()); - Access::clear(); + access.clear(); CHECK(queue.pop_from_isr()); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); CHECK_EQUAL(1U, queue.size_from_isr()); - Access::clear(); + access.clear(); CHECK(queue.pop_from_isr()); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); CHECK_EQUAL(0U, queue.size_from_isr()); - Access::clear(); + access.clear(); CHECK(!queue.pop()); CHECK(!queue.pop_from_isr()); @@ -406,7 +409,7 @@ namespace //************************************************************************* TEST(test_multiple_emplace) { - etl::queue_spsc_isr queue; + etl::queue_spsc_isr queue(lock, unlock); queue.emplace(1); queue.emplace(1, 2); @@ -430,20 +433,20 @@ namespace //************************************************************************* TEST(test_clear) { - Access::clear(); + access.clear(); - etl::queue_spsc_isr queue; + etl::queue_spsc_isr queue(lock, unlock); CHECK_EQUAL(0U, queue.size()); queue.push(1); queue.push(2); queue.clear(); - CHECK(Access::called_lock); - CHECK(Access::called_unlock); + CHECK(access.called_lock); + CHECK(access.called_unlock); CHECK_EQUAL(0U, queue.size()); - Access::clear(); + access.clear(); // Do it again to check that clear() didn't screw up the internals. queue.push_from_isr(1); @@ -451,84 +454,84 @@ namespace CHECK_EQUAL(2U, queue.size_from_isr()); queue.clear_from_isr(); CHECK_EQUAL(0U, queue.size_from_isr()); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); } //************************************************************************* TEST(test_empty) { - Access::clear(); + access.clear(); - etl::queue_spsc_isr queue; + etl::queue_spsc_isr queue(lock, unlock); CHECK(queue.empty()); - CHECK(Access::called_lock); - CHECK(Access::called_unlock); + CHECK(access.called_lock); + CHECK(access.called_unlock); queue.push(1); - Access::clear(); + access.clear(); CHECK(!queue.empty()); - CHECK(Access::called_lock); - CHECK(Access::called_unlock); + CHECK(access.called_lock); + CHECK(access.called_unlock); queue.clear(); - Access::clear(); + access.clear(); CHECK(queue.empty_from_isr()); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); queue.push(1); - Access::clear(); + access.clear(); CHECK(!queue.empty_from_isr()); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); } //************************************************************************* TEST(test_full) { - Access::clear(); + access.clear(); - etl::queue_spsc_isr queue; + etl::queue_spsc_isr queue(lock, unlock); CHECK(!queue.full()); - CHECK(Access::called_lock); - CHECK(Access::called_unlock); + CHECK(access.called_lock); + CHECK(access.called_unlock); queue.push(1); queue.push(2); queue.push(3); queue.push(4); - Access::clear(); + access.clear(); CHECK(queue.full()); - CHECK(Access::called_lock); - CHECK(Access::called_unlock); + CHECK(access.called_lock); + CHECK(access.called_unlock); queue.clear(); - Access::clear(); + access.clear(); CHECK(!queue.full_from_isr()); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); queue.push(1); queue.push(2); queue.push(3); queue.push(4); - Access::clear(); + access.clear(); CHECK(queue.full_from_isr()); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); } //========================================================================= @@ -544,22 +547,25 @@ namespace struct ThreadLock { - static void lock() + void lock() { mutex.lock(); } - static void unlock() + void unlock() { mutex.unlock(); } - static std::mutex mutex; + std::mutex mutex; }; - std::mutex ThreadLock::mutex; + ThreadLock threadLock; - etl::queue_spsc_isr queue; + etl::function_imv lock; + etl::function_imv unlock; + + etl::queue_spsc_isr queue(lock, unlock); const size_t LENGTH = 1000; @@ -574,14 +580,14 @@ namespace while (ticks <= LENGTH) { - if (ThreadLock::mutex.try_lock()) + if (threadLock.mutex.try_lock()) { if (queue.push_from_isr(ticks)) { ++ticks; } - ThreadLock::mutex.unlock(); + threadLock.mutex.unlock(); } Sleep(0); diff --git a/test/test_queue_spsc_isr_small.cpp b/test/test_queue_spsc_isr_small.cpp index ca5f4f22..643970a6 100644 --- a/test/test_queue_spsc_isr_small.cpp +++ b/test/test_queue_spsc_isr_small.cpp @@ -46,44 +46,46 @@ namespace { public: - static void clear() + void clear() { called_lock = false; called_unlock = false; } - static void lock() + void lock() { called_lock = true; } - static void unlock() + void unlock() { called_unlock = true; } - static bool called_lock; - static bool called_unlock; + bool called_lock; + bool called_unlock; }; - bool Access::called_lock; - bool Access::called_unlock; + Access access; + + etl::function_imv lock; + etl::function_imv unlock; struct Data { Data(int a_, int b_ = 2, int c_ = 3, int d_ = 4) : a(a_), - b(b_), - c(c_), - d(d_) + b(b_), + c(c_), + d(d_) { } Data() : a(0), - b(0), - c(0), - d(0) + b(0), + c(0), + d(0) { } @@ -98,131 +100,131 @@ namespace return (lhs.a == rhs.a) && (lhs.b == rhs.b) && (lhs.c == rhs.c) && (lhs.d == rhs.d); } - typedef etl::queue_spsc_isr QueueInt; - typedef etl::iqueue_spsc_isr IQueueInt; + typedef etl::queue_spsc_isr QueueInt; + typedef etl::iqueue_spsc_isr IQueueInt; - typedef etl::queue_spsc_isr QueueInt255; + typedef etl::queue_spsc_isr QueueInt255; SUITE(test_queue_isr) { //************************************************************************* TEST(test_constructor) { - Access::clear(); + access.clear(); - QueueInt queue; + QueueInt queue(lock, unlock); CHECK_EQUAL(4U, queue.max_size()); CHECK_EQUAL(4U, queue.capacity()); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); } //************************************************************************* TEST(test_size_push_pop) { - Access::clear(); + access.clear(); - QueueInt queue; + QueueInt queue(lock, unlock); CHECK_EQUAL(0U, queue.size_from_isr()); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); - Access::clear(); + access.clear(); CHECK_EQUAL(4U, queue.available_from_isr()); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); - Access::clear(); + access.clear(); CHECK_EQUAL(0U, queue.size()); - CHECK(Access::called_lock); - CHECK(Access::called_unlock); + CHECK(access.called_lock); + CHECK(access.called_unlock); - Access::clear(); + access.clear(); CHECK_EQUAL(4U, queue.available()); - CHECK(Access::called_lock); - CHECK(Access::called_unlock); + CHECK(access.called_lock); + CHECK(access.called_unlock); - Access::clear(); + access.clear(); queue.push_from_isr(1); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); CHECK_EQUAL(1U, queue.size_from_isr()); CHECK_EQUAL(3U, queue.available_from_isr()); - Access::clear(); + access.clear(); queue.push(2); - CHECK(Access::called_lock); - CHECK(Access::called_unlock); + CHECK(access.called_lock); + CHECK(access.called_unlock); CHECK_EQUAL(2U, queue.size_from_isr()); CHECK_EQUAL(2U, queue.available_from_isr()); - Access::clear(); + access.clear(); queue.push(3); - CHECK(Access::called_lock); - CHECK(Access::called_unlock); + CHECK(access.called_lock); + CHECK(access.called_unlock); CHECK_EQUAL(3U, queue.size_from_isr()); CHECK_EQUAL(1U, queue.available_from_isr()); - Access::clear(); + access.clear(); queue.push(4); - CHECK(Access::called_lock); - CHECK(Access::called_unlock); + CHECK(access.called_lock); + CHECK(access.called_unlock); CHECK_EQUAL(4U, queue.size_from_isr()); CHECK_EQUAL(0U, queue.available_from_isr()); - Access::clear(); + access.clear(); CHECK(!queue.push(5)); CHECK(!queue.push_from_isr(5)); - Access::clear(); + access.clear(); int i; CHECK(queue.pop(i)); CHECK_EQUAL(1, i); - CHECK(Access::called_lock); - CHECK(Access::called_unlock); + CHECK(access.called_lock); + CHECK(access.called_unlock); CHECK_EQUAL(3U, queue.size_from_isr()); - Access::clear(); + access.clear(); CHECK(queue.pop_from_isr(i)); CHECK_EQUAL(2, i); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); CHECK_EQUAL(2U, queue.size_from_isr()); - Access::clear(); + access.clear(); CHECK(queue.pop_from_isr(i)); CHECK_EQUAL(3, i); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); CHECK_EQUAL(1U, queue.size_from_isr()); - Access::clear(); + access.clear(); CHECK(queue.pop_from_isr(i)); CHECK_EQUAL(4, i); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); CHECK_EQUAL(0U, queue.size_from_isr()); - Access::clear(); + access.clear(); CHECK(!queue.pop(i)); CHECK(!queue.pop_from_isr(i)); @@ -231,92 +233,92 @@ namespace //************************************************************************* TEST(test_size_push_pop_iqueue) { - Access::clear(); + access.clear(); - QueueInt queue; + QueueInt queue(lock, unlock); IQueueInt& iqueue = queue; CHECK_EQUAL(0U, iqueue.size_from_isr()); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); - Access::clear(); + access.clear(); CHECK_EQUAL(0U, iqueue.size()); - CHECK(Access::called_lock); - CHECK(Access::called_unlock); + CHECK(access.called_lock); + CHECK(access.called_unlock); - Access::clear(); + access.clear(); iqueue.push_from_isr(1); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); CHECK_EQUAL(1U, iqueue.size_from_isr()); - Access::clear(); + access.clear(); iqueue.push(2); - CHECK(Access::called_lock); - CHECK(Access::called_unlock); + CHECK(access.called_lock); + CHECK(access.called_unlock); CHECK_EQUAL(2U, iqueue.size_from_isr()); - Access::clear(); + access.clear(); iqueue.push(3); - CHECK(Access::called_lock); - CHECK(Access::called_unlock); + CHECK(access.called_lock); + CHECK(access.called_unlock); CHECK_EQUAL(3U, iqueue.size_from_isr()); - Access::clear(); + access.clear(); iqueue.push(4); - CHECK(Access::called_lock); - CHECK(Access::called_unlock); + CHECK(access.called_lock); + CHECK(access.called_unlock); CHECK_EQUAL(4U, iqueue.size_from_isr()); - Access::clear(); + access.clear(); CHECK(!iqueue.push(5)); CHECK(!iqueue.push_from_isr(5)); - Access::clear(); + access.clear(); int i; CHECK(iqueue.pop(i)); CHECK_EQUAL(1, i); - CHECK(Access::called_lock); - CHECK(Access::called_unlock); + CHECK(access.called_lock); + CHECK(access.called_unlock); CHECK_EQUAL(3U, iqueue.size_from_isr()); - Access::clear(); + access.clear(); CHECK(iqueue.pop_from_isr(i)); CHECK_EQUAL(2, i); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); CHECK_EQUAL(2U, iqueue.size_from_isr()); - Access::clear(); + access.clear(); CHECK(iqueue.pop_from_isr(i)); CHECK_EQUAL(3, i); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); CHECK_EQUAL(1U, iqueue.size_from_isr()); - Access::clear(); + access.clear(); CHECK(iqueue.pop_from_isr(i)); CHECK_EQUAL(4, i); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); CHECK_EQUAL(0U, iqueue.size_from_isr()); - Access::clear(); + access.clear(); CHECK(!iqueue.pop(i)); CHECK(!iqueue.pop_from_isr(i)); @@ -325,84 +327,84 @@ namespace //************************************************************************* TEST(test_size_push_pop_void) { - Access::clear(); + access.clear(); - QueueInt queue; + QueueInt queue(lock, unlock); CHECK_EQUAL(0U, queue.size_from_isr()); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); - Access::clear(); + access.clear(); CHECK_EQUAL(0U, queue.size()); - CHECK(Access::called_lock); - CHECK(Access::called_unlock); + CHECK(access.called_lock); + CHECK(access.called_unlock); - Access::clear(); + access.clear(); queue.push_from_isr(1); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); CHECK_EQUAL(1U, queue.size_from_isr()); - Access::clear(); + access.clear(); queue.push(2); - CHECK(Access::called_lock); - CHECK(Access::called_unlock); + CHECK(access.called_lock); + CHECK(access.called_unlock); CHECK_EQUAL(2U, queue.size_from_isr()); - Access::clear(); + access.clear(); queue.push(3); - CHECK(Access::called_lock); - CHECK(Access::called_unlock); + CHECK(access.called_lock); + CHECK(access.called_unlock); CHECK_EQUAL(3U, queue.size_from_isr()); - Access::clear(); + access.clear(); queue.push(4); - CHECK(Access::called_lock); - CHECK(Access::called_unlock); + CHECK(access.called_lock); + CHECK(access.called_unlock); CHECK_EQUAL(4U, queue.size_from_isr()); - Access::clear(); + access.clear(); CHECK(!queue.push(5)); CHECK(!queue.push_from_isr(5)); - Access::clear(); + access.clear(); CHECK(queue.pop()); - CHECK(Access::called_lock); - CHECK(Access::called_unlock); + CHECK(access.called_lock); + CHECK(access.called_unlock); CHECK_EQUAL(3U, queue.size_from_isr()); - Access::clear(); + access.clear(); CHECK(queue.pop_from_isr()); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); CHECK_EQUAL(2U, queue.size_from_isr()); - Access::clear(); + access.clear(); CHECK(queue.pop_from_isr()); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); CHECK_EQUAL(1U, queue.size_from_isr()); - Access::clear(); + access.clear(); CHECK(queue.pop_from_isr()); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); CHECK_EQUAL(0U, queue.size_from_isr()); - Access::clear(); + access.clear(); CHECK(!queue.pop()); CHECK(!queue.pop_from_isr()); @@ -411,7 +413,7 @@ namespace //************************************************************************* TEST(test_push_255) { - QueueInt255 queue; + QueueInt255 queue(lock, unlock); for (int i = 0; i < 255; ++i) { @@ -424,7 +426,7 @@ namespace //************************************************************************* TEST(test_multiple_emplace) { - etl::queue_spsc_isr queue; + etl::queue_spsc_isr queue(lock, unlock); queue.emplace(1); queue.emplace(1, 2); @@ -448,20 +450,20 @@ namespace //************************************************************************* TEST(test_clear) { - Access::clear(); + access.clear(); - QueueInt queue; + QueueInt queue(lock, unlock); CHECK_EQUAL(0U, queue.size()); queue.push(1); queue.push(2); queue.clear(); - CHECK(Access::called_lock); - CHECK(Access::called_unlock); + CHECK(access.called_lock); + CHECK(access.called_unlock); CHECK_EQUAL(0U, queue.size()); - Access::clear(); + access.clear(); // Do it again to check that clear() didn't screw up the internals. queue.push_from_isr(1); @@ -469,84 +471,84 @@ namespace CHECK_EQUAL(2U, queue.size_from_isr()); queue.clear_from_isr(); CHECK_EQUAL(0U, queue.size_from_isr()); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); } //************************************************************************* TEST(test_empty) { - Access::clear(); + access.clear(); - QueueInt queue; + QueueInt queue(lock, unlock); CHECK(queue.empty()); - CHECK(Access::called_lock); - CHECK(Access::called_unlock); + CHECK(access.called_lock); + CHECK(access.called_unlock); queue.push(1); - Access::clear(); + access.clear(); CHECK(!queue.empty()); - CHECK(Access::called_lock); - CHECK(Access::called_unlock); + CHECK(access.called_lock); + CHECK(access.called_unlock); queue.clear(); - Access::clear(); + access.clear(); CHECK(queue.empty_from_isr()); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); queue.push(1); - Access::clear(); + access.clear(); CHECK(!queue.empty_from_isr()); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); } //************************************************************************* TEST(test_full) { - Access::clear(); + access.clear(); - QueueInt queue; + QueueInt queue(lock, unlock); CHECK(!queue.full()); - CHECK(Access::called_lock); - CHECK(Access::called_unlock); + CHECK(access.called_lock); + CHECK(access.called_unlock); queue.push(1); queue.push(2); queue.push(3); queue.push(4); - Access::clear(); + access.clear(); CHECK(queue.full()); - CHECK(Access::called_lock); - CHECK(Access::called_unlock); + CHECK(access.called_lock); + CHECK(access.called_unlock); queue.clear(); - Access::clear(); + access.clear(); CHECK(!queue.full_from_isr()); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); queue.push(1); queue.push(2); queue.push(3); queue.push(4); - Access::clear(); + access.clear(); CHECK(queue.full_from_isr()); - CHECK(!Access::called_lock); - CHECK(!Access::called_unlock); + CHECK(!access.called_lock); + CHECK(!access.called_unlock); } //========================================================================= @@ -562,22 +564,25 @@ namespace struct ThreadLock { - static void lock() + void lock() { mutex.lock(); } - static void unlock() + void unlock() { mutex.unlock(); } - static std::mutex mutex; + std::mutex mutex; }; - std::mutex ThreadLock::mutex; + ThreadLock threadLock; - etl::queue_spsc_isr queue; + etl::function_imv lock; + etl::function_imv unlock; + + etl::queue_spsc_isr queue(lock, unlock); const size_t LENGTH = 1000; @@ -592,14 +597,14 @@ namespace while (ticks <= LENGTH) { - if (ThreadLock::mutex.try_lock()) + if (threadLock.mutex.try_lock()) { if (queue.push_from_isr(ticks)) { ++ticks; } - ThreadLock::mutex.unlock(); + threadLock.mutex.unlock(); } Sleep(0);