mirror of
https://github.com/ETLCPP/etl.git
synced 2026-11-09 14:49:53 +08:00
Modified ISR queue to take references to etl::ifunction instances at runtime rather than static class at compile time.
This commit is contained in:
parent
0db4f32522
commit
4aab7c0173
@ -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<int, 10> myQueue;
|
||||
/// etl::iqueue_isr<int>& 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 <typename T, typename TAccess, const size_t MEMORY_MODEL = etl::memory_model::MEMORY_MODEL_LARGE>
|
||||
template <typename T, const size_t MEMORY_MODEL = etl::memory_model::MEMORY_MODEL_LARGE>
|
||||
class iqueue_spsc_isr : public queue_spsc_isr_base<T, MEMORY_MODEL>
|
||||
{
|
||||
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 <typename ... Args>
|
||||
bool emplace(Args&&... args)
|
||||
{
|
||||
TAccess::lock();
|
||||
lock();
|
||||
|
||||
bool result = this->emplace_implementation(std::forward<Args>(args)...);
|
||||
|
||||
TAccess::unlock();
|
||||
unlock();
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -450,11 +447,11 @@ namespace etl
|
||||
template <typename T1>
|
||||
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 <typename T1, typename T2>
|
||||
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 <typename T1, typename T2, typename T3>
|
||||
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 <typename T1, typename T2, typename T3, typename T4>
|
||||
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<void>& lock_, etl::ifunction<void>& 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<void>& lock; ///< The callback that locks interrupts.
|
||||
etl::ifunction<void>& 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 <typename T, size_t SIZE, typename TAccess, const size_t MEMORY_MODEL = etl::memory_model::MEMORY_MODEL_LARGE>
|
||||
class queue_spsc_isr : public etl::iqueue_spsc_isr<T, TAccess, MEMORY_MODEL>
|
||||
template <typename T, size_t SIZE, const size_t MEMORY_MODEL = etl::memory_model::MEMORY_MODEL_LARGE>
|
||||
class queue_spsc_isr : public etl::iqueue_spsc_isr<T, MEMORY_MODEL>
|
||||
{
|
||||
private:
|
||||
|
||||
typedef etl::iqueue_spsc_isr<T, TAccess, MEMORY_MODEL> base_t;
|
||||
typedef etl::iqueue_spsc_isr<T, MEMORY_MODEL> base_t;
|
||||
|
||||
public:
|
||||
|
||||
@ -653,8 +652,9 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Default constructor.
|
||||
//*************************************************************************
|
||||
queue_spsc_isr()
|
||||
: base_t(reinterpret_cast<T*>(&buffer[0]), MAX_SIZE)
|
||||
queue_spsc_isr(etl::ifunction<void>& lock,
|
||||
etl::ifunction<void>& unlock)
|
||||
: base_t(reinterpret_cast<T*>(&buffer[0]), MAX_SIZE, lock, unlock)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@ -29,6 +29,7 @@ SOFTWARE.
|
||||
#include "UnitTest++.h"
|
||||
|
||||
#include "etl/queue_spsc_isr.h"
|
||||
#include "etl/function.h"
|
||||
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
@ -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<Access, access, &Access::lock> lock;
|
||||
etl::function_imv<Access, access, &Access::unlock> 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<int, 4, Access> queue;
|
||||
etl::queue_spsc_isr<int, 4> 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<int, 4, Access> queue;
|
||||
etl::queue_spsc_isr<int, 4> 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<int, 4, Access> queue;
|
||||
etl::queue_spsc_isr<int, 4> queue(lock, unlock);
|
||||
|
||||
etl::iqueue_spsc_isr<int, Access>& iqueue = queue;
|
||||
etl::iqueue_spsc_isr<int>& 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<int, 4, Access> queue;
|
||||
etl::queue_spsc_isr<int, 4> 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<Data, 4, Access> queue;
|
||||
etl::queue_spsc_isr<Data, 4> 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<int, 4, Access> queue;
|
||||
etl::queue_spsc_isr<int, 4> 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<int, 4, Access> queue;
|
||||
etl::queue_spsc_isr<int, 4> 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<int, 4, Access> queue;
|
||||
etl::queue_spsc_isr<int, 4> 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<int, 10, ThreadLock> queue;
|
||||
etl::function_imv<ThreadLock, threadLock, &ThreadLock::lock> lock;
|
||||
etl::function_imv<ThreadLock, threadLock, &ThreadLock::unlock> unlock;
|
||||
|
||||
etl::queue_spsc_isr<int, 10> 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);
|
||||
|
||||
@ -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<Access, access, &Access::lock> lock;
|
||||
etl::function_imv<Access, access, &Access::unlock> 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<int, 4, Access, etl::memory_model::MEMORY_MODEL_SMALL> QueueInt;
|
||||
typedef etl::iqueue_spsc_isr<int, Access, etl::memory_model::MEMORY_MODEL_SMALL> IQueueInt;
|
||||
typedef etl::queue_spsc_isr<int, 4, etl::memory_model::MEMORY_MODEL_SMALL> QueueInt;
|
||||
typedef etl::iqueue_spsc_isr<int, etl::memory_model::MEMORY_MODEL_SMALL> IQueueInt;
|
||||
|
||||
typedef etl::queue_spsc_isr<int, 255, Access, etl::memory_model::MEMORY_MODEL_SMALL> QueueInt255;
|
||||
typedef etl::queue_spsc_isr<int, 255, etl::memory_model::MEMORY_MODEL_SMALL> 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<Data, 4, Access, etl::memory_model::MEMORY_MODEL_SMALL> queue;
|
||||
etl::queue_spsc_isr<Data, 4, etl::memory_model::MEMORY_MODEL_SMALL> 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<int, 10, ThreadLock> queue;
|
||||
etl::function_imv<ThreadLock, threadLock, &ThreadLock::lock> lock;
|
||||
etl::function_imv<ThreadLock, threadLock, &ThreadLock::unlock> unlock;
|
||||
|
||||
etl::queue_spsc_isr<int, 10> 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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user