Add front() to locked queues

This commit is contained in:
John Wellbelove 2021-10-02 12:00:27 +01:00
parent 88f2ff8e63
commit 3f79e61f97
16 changed files with 607 additions and 15 deletions

2
.gitignore vendored
View File

@ -325,3 +325,5 @@ test/vs2019/Test2
test/vs2019/Debug MSVC - Force C++03
test/vs2019/Debug LLVM - No STL
test/vs2019/Debug - No STL
test/build-make
test/build-ninja

View File

@ -475,6 +475,50 @@ namespace etl
return result;
}
//*************************************************************************
/// Peek a value at the front of the queue without locking.
//*************************************************************************
reference front_unlocked()
{
return front_implementation();
}
//*************************************************************************
/// Peek a value at the front of the queue without locking.
//*************************************************************************
const_reference front_unlocked() const
{
return front_implementation();
}
//*************************************************************************
/// Peek a value at the front of the queue.
//*************************************************************************
reference front()
{
this->lock();
reference result = front_implementation();
this->unlock();
return result;
}
//*************************************************************************
/// Peek a value at the front of the queue.
//*************************************************************************
const_reference front() const
{
this->lock();
const_reference result = front_implementation();
this->unlock();
return result;
}
//*************************************************************************
/// Clear the queue, unlocked.
//*************************************************************************
@ -709,6 +753,22 @@ namespace etl
return true;
}
//*************************************************************************
/// Peek a value at the front of the queue without locking
//*************************************************************************
reference front_implementation()
{
return p_buffer[this->read_index];;
}
//*************************************************************************
/// Peek a value at the front of the queue without locking
//*************************************************************************
const_reference front_implementation() const
{
return p_buffer[this->read_index];;
}
// Disable copy construction and assignment.
iqueue_lockable(const iqueue_lockable&) ETL_DELETE;
iqueue_lockable& operator =(const iqueue_lockable&) ETL_DELETE;

View File

@ -292,6 +292,34 @@ namespace etl
return result;
}
//*************************************************************************
/// Peek a value at the front of the queue.
//*************************************************************************
reference front()
{
access.lock();
reference result = front_implementation();
access.unlock();
return result;
}
//*************************************************************************
/// Peek a value at the front of the queue.
//*************************************************************************
const_reference front() const
{
access.lock();
const_reference result = front_implementation();
access.unlock();
return result;
}
//*************************************************************************
/// Clear the queue.
//*************************************************************************
@ -571,6 +599,22 @@ namespace etl
return true;
}
//*************************************************************************
/// Peek a value at the front of the queue.
//*************************************************************************
reference front_implementation()
{
return p_buffer[read_index];
}
//*************************************************************************
/// Peek a value at the front of the queue.
//*************************************************************************
const_reference front_implementation() const
{
return p_buffer[read_index];
}
// Disable copy construction and assignment.
iqueue_mpmc_mutex(const iqueue_mpmc_mutex&);
iqueue_mpmc_mutex& operator =(const iqueue_mpmc_mutex&);

View File

@ -368,7 +368,7 @@ namespace etl
//*************************************************************************
/// Peek the next value in the queue without removing it.
//*************************************************************************
bool peek(reference value)
bool front(reference value)
{
size_type read_index = read.load(etl::memory_order_relaxed);
@ -433,6 +433,26 @@ namespace etl
return true;
}
//*************************************************************************
/// Peek a value from the front of the queue.
//*************************************************************************
reference front()
{
size_type read_index = read.load(etl::memory_order_relaxed);
return p_buffer[read_index];
}
//*************************************************************************
/// Peek a value from the front of the queue.
//*************************************************************************
const_reference front() const
{
size_type read_index = read.load(etl::memory_order_relaxed);
return p_buffer[read_index];
}
//*************************************************************************
/// Clear the queue.
/// Must be called from thread that pops the queue or when there is no

View File

@ -106,6 +106,22 @@ namespace etl
return pop_implementation();
}
//*************************************************************************
/// Peek a value at the front of the queue from an ISR
//*************************************************************************
reference front_from_isr()
{
return front_implementation();
}
//*************************************************************************
/// Peek a value at the front of the queue from an ISR
//*************************************************************************
const_reference front_from_isr() const
{
return front_implementation();
}
//*************************************************************************
/// How much free space available in the queue.
/// Called from ISR.
@ -362,6 +378,22 @@ namespace etl
return true;
}
//*************************************************************************
/// Peek a value at the front of the queue.
//*************************************************************************
reference front_implementation()
{
return p_buffer[read_index];
}
//*************************************************************************
/// Peek a value at the front of the queue.
//*************************************************************************
const_reference front_implementation() const
{
return p_buffer[read_index];
}
//*************************************************************************
/// Pop a value from the queue and discard.
//*************************************************************************
@ -589,6 +621,34 @@ namespace etl
return result;
}
//*************************************************************************
/// Peek a value at the front of the queue.
//*************************************************************************
reference front()
{
TAccess::lock();
reference result = this->front_implementation();
TAccess::unlock();
return result;
}
//*************************************************************************
/// Peek a value at the front of the queue.
//*************************************************************************
const_reference front() const
{
TAccess::lock();
const_reference result = this->front_implementation();
TAccess::unlock();
return result;
}
//*************************************************************************
/// Clear the queue.
//*************************************************************************

View File

@ -431,6 +431,52 @@ namespace etl
return result;
}
//*************************************************************************
/// Peek a value from the front of the queue.
/// Unlocked
//*************************************************************************
reference front_from_unlocked()
{
return front_implementation();
}
//*************************************************************************
/// Peek a value from the front of the queue.
/// Unlocked
//*************************************************************************
const_reference front_from_unlocked() const
{
return front_implementation();
}
//*************************************************************************
/// Peek a value from the front of the queue.
//*************************************************************************
reference front()
{
lock();
reference result = front_implementation();
unlock();
return result;
}
//*************************************************************************
/// Peek a value from the front of the queue.
//*************************************************************************
const_reference front() const
{
lock();
const_reference result = front_implementation();
unlock();
return result;
}
//*************************************************************************
/// Clear the queue from the ISR.
//*************************************************************************
@ -706,6 +752,24 @@ namespace etl
return true;
}
//*************************************************************************
/// Peek a value from the front of the queue.
/// Unlocked
//*************************************************************************
reference front_implementation()
{
return p_buffer[this->read_index];
}
//*************************************************************************
/// Peek a value from the front of the queue.
/// Unlocked
//*************************************************************************
const_reference front_implementation() const
{
return p_buffer[this->read_index];
}
//*************************************************************************
/// Pop a value from the queue.
/// Unlocked

View File

@ -509,6 +509,44 @@ namespace
CHECK(!queue.pop());
}
//*************************************************************************
TEST(test_size_push_front_pop)
{
QueueInt queue;
CHECK_EQUAL(0U, queue.size());
queue.push(1);
queue.push(2);
queue.push(3);
queue.push(4);
CHECK_EQUAL(4U, queue.size());
CHECK_EQUAL(1, queue.front());
CHECK_EQUAL(4U, queue.size());
CHECK_EQUAL(1, queue.front());
CHECK_EQUAL(4U, queue.size());
CHECK(queue.pop());
CHECK_EQUAL(3U, queue.size());
CHECK(queue.pop());
CHECK_EQUAL(2U, queue.size());
CHECK(queue.pop());
CHECK_EQUAL(1U, queue.size());
CHECK_EQUAL(4, queue.front());
CHECK_EQUAL(1U, queue.size());
CHECK_EQUAL(4, queue.front());
CHECK_EQUAL(1U, queue.size());
CHECK(queue.pop());
CHECK_EQUAL(0U, queue.size());
}
//*************************************************************************
TEST(test_multiple_emplace)
{

View File

@ -509,6 +509,44 @@ namespace
CHECK(!queue.pop());
}
//*************************************************************************
TEST(test_size_push_front_pop)
{
QueueInt queue;
CHECK_EQUAL(0U, queue.size());
queue.push(1);
queue.push(2);
queue.push(3);
queue.push(4);
CHECK_EQUAL(4U, queue.size());
CHECK_EQUAL(1, queue.front());
CHECK_EQUAL(4U, queue.size());
CHECK_EQUAL(1, queue.front());
CHECK_EQUAL(4U, queue.size());
CHECK(queue.pop());
CHECK_EQUAL(3U, queue.size());
CHECK(queue.pop());
CHECK_EQUAL(2U, queue.size());
CHECK(queue.pop());
CHECK_EQUAL(1U, queue.size());
CHECK_EQUAL(4, queue.front());
CHECK_EQUAL(1U, queue.size());
CHECK_EQUAL(4, queue.front());
CHECK_EQUAL(1U, queue.size());
CHECK(queue.pop());
CHECK_EQUAL(0U, queue.size());
}
//*************************************************************************
TEST(test_multiple_emplace)
{

View File

@ -298,6 +298,44 @@ namespace
CHECK(!queue.pop());
}
//*************************************************************************
TEST(test_size_push_front_pop)
{
etl::queue_mpmc_mutex<int, 4> queue;
CHECK_EQUAL(0U, queue.size());
queue.push(1);
queue.push(2);
queue.push(3);
queue.push(4);
CHECK_EQUAL(4U, queue.size());
CHECK_EQUAL(1, queue.front());
CHECK_EQUAL(4U, queue.size());
CHECK_EQUAL(1, queue.front());
CHECK_EQUAL(4U, queue.size());
CHECK(queue.pop());
CHECK_EQUAL(3U, queue.size());
CHECK(queue.pop());
CHECK_EQUAL(2U, queue.size());
CHECK(queue.pop());
CHECK_EQUAL(1U, queue.size());
CHECK_EQUAL(4, queue.front());
CHECK_EQUAL(1U, queue.size());
CHECK_EQUAL(4, queue.front());
CHECK_EQUAL(1U, queue.size());
CHECK(queue.pop());
CHECK_EQUAL(0U, queue.size());
}
//*************************************************************************
TEST(test_clear)
{

View File

@ -310,6 +310,44 @@ namespace
CHECK(!queue.pop());
}
//*************************************************************************
TEST(test_size_push_front_pop)
{
QueueInt queue;
CHECK_EQUAL(0U, queue.size());
queue.push(1);
queue.push(2);
queue.push(3);
queue.push(4);
CHECK_EQUAL(4U, queue.size());
CHECK_EQUAL(1, queue.front());
CHECK_EQUAL(4U, queue.size());
CHECK_EQUAL(1, queue.front());
CHECK_EQUAL(4U, queue.size());
CHECK(queue.pop());
CHECK_EQUAL(3U, queue.size());
CHECK(queue.pop());
CHECK_EQUAL(2U, queue.size());
CHECK(queue.pop());
CHECK_EQUAL(1U, queue.size());
CHECK_EQUAL(4, queue.front());
CHECK_EQUAL(1U, queue.size());
CHECK_EQUAL(4, queue.front());
CHECK_EQUAL(1U, queue.size());
CHECK(queue.pop());
CHECK_EQUAL(0U, queue.size());
}
//*************************************************************************
TEST(test_push_255)
{

View File

@ -271,7 +271,8 @@ namespace
CHECK(!queue.pop());
}
TEST(test_size_push_peek_pop)
//*************************************************************************
TEST(test_size_push_front_pop)
{
etl::queue_spsc_atomic<int, 4> queue;
@ -283,14 +284,10 @@ namespace
queue.push(4);
CHECK_EQUAL(4U, queue.size());
int i;
CHECK(queue.peek(i));
CHECK_EQUAL(1, i);
CHECK_EQUAL(1, queue.front());
CHECK_EQUAL(4U, queue.size());
CHECK(queue.peek(i));
CHECK_EQUAL(1, i);
CHECK_EQUAL(1, queue.front());
CHECK_EQUAL(4U, queue.size());
CHECK(queue.pop());
@ -302,19 +299,14 @@ namespace
CHECK(queue.pop());
CHECK_EQUAL(1U, queue.size());
CHECK(queue.peek(i));
CHECK_EQUAL(4, i);
CHECK_EQUAL(4, queue.front());
CHECK_EQUAL(1U, queue.size());
CHECK(queue.peek(i));
CHECK_EQUAL(4, i);
CHECK_EQUAL(4, queue.front());
CHECK_EQUAL(1U, queue.size());
CHECK(queue.pop());
CHECK_EQUAL(0U, queue.size());
CHECK(!queue.peek(i));
CHECK(!queue.peek(i));
}
//*************************************************************************

View File

@ -289,6 +289,44 @@ namespace
CHECK_EQUAL(254U, queue.size());
}
//*************************************************************************
TEST(test_size_push_front_pop)
{
etl::queue_spsc_atomic<int, 4, etl::memory_model::MEMORY_MODEL_SMALL> queue;
CHECK_EQUAL(0U, queue.size());
queue.push(1);
queue.push(2);
queue.push(3);
queue.push(4);
CHECK_EQUAL(4U, queue.size());
CHECK_EQUAL(1, queue.front());
CHECK_EQUAL(4U, queue.size());
CHECK_EQUAL(1, queue.front());
CHECK_EQUAL(4U, queue.size());
CHECK(queue.pop());
CHECK_EQUAL(3U, queue.size());
CHECK(queue.pop());
CHECK_EQUAL(2U, queue.size());
CHECK(queue.pop());
CHECK_EQUAL(1U, queue.size());
CHECK_EQUAL(4, queue.front());
CHECK_EQUAL(1U, queue.size());
CHECK_EQUAL(4, queue.front());
CHECK_EQUAL(1U, queue.size());
CHECK(queue.pop());
CHECK_EQUAL(0U, queue.size());
}
//*************************************************************************
TEST(test_multiple_emplace)
{

View File

@ -453,6 +453,46 @@ namespace
CHECK(!queue.pop_from_isr());
}
//*************************************************************************
TEST(test_size_push_front_pop)
{
Access::clear();
etl::queue_spsc_isr<int, 4, Access> queue;
CHECK_EQUAL(0U, queue.size());
queue.push(1);
queue.push(2);
queue.push(3);
queue.push(4);
CHECK_EQUAL(4U, queue.size());
CHECK_EQUAL(1, queue.front());
CHECK_EQUAL(4U, queue.size());
CHECK_EQUAL(1, queue.front());
CHECK_EQUAL(4U, queue.size());
CHECK(queue.pop());
CHECK_EQUAL(3U, queue.size());
CHECK(queue.pop());
CHECK_EQUAL(2U, queue.size());
CHECK(queue.pop());
CHECK_EQUAL(1U, queue.size());
CHECK_EQUAL(4, queue.front());
CHECK_EQUAL(1U, queue.size());
CHECK_EQUAL(4, queue.front());
CHECK_EQUAL(1U, queue.size());
CHECK(queue.pop());
CHECK_EQUAL(0U, queue.size());
}
//*************************************************************************
TEST(test_multiple_emplace)
{

View File

@ -471,6 +471,46 @@ namespace
CHECK_EQUAL(255U, queue.size());
}
//*************************************************************************
TEST(test_size_push_front_pop)
{
Access::clear();
etl::queue_spsc_isr<int, 4, Access, etl::memory_model::MEMORY_MODEL_SMALL> queue;
CHECK_EQUAL(0U, queue.size());
queue.push(1);
queue.push(2);
queue.push(3);
queue.push(4);
CHECK_EQUAL(4U, queue.size());
CHECK_EQUAL(1, queue.front());
CHECK_EQUAL(4U, queue.size());
CHECK_EQUAL(1, queue.front());
CHECK_EQUAL(4U, queue.size());
CHECK(queue.pop());
CHECK_EQUAL(3U, queue.size());
CHECK(queue.pop());
CHECK_EQUAL(2U, queue.size());
CHECK(queue.pop());
CHECK_EQUAL(1U, queue.size());
CHECK_EQUAL(4, queue.front());
CHECK_EQUAL(1U, queue.size());
CHECK_EQUAL(4, queue.front());
CHECK_EQUAL(1U, queue.size());
CHECK(queue.pop());
CHECK_EQUAL(0U, queue.size());
}
//*************************************************************************
TEST(test_multiple_emplace)
{

View File

@ -458,6 +458,46 @@ namespace
CHECK(!queue.pop_from_unlocked());
}
//*************************************************************************
TEST(test_size_push_front_pop)
{
access.clear();
etl::queue_spsc_locked<int, 4> queue(lock, unlock);
CHECK_EQUAL(0U, queue.size());
queue.push(1);
queue.push(2);
queue.push(3);
queue.push(4);
CHECK_EQUAL(4U, queue.size());
CHECK_EQUAL(1, queue.front());
CHECK_EQUAL(4U, queue.size());
CHECK_EQUAL(1, queue.front());
CHECK_EQUAL(4U, queue.size());
CHECK(queue.pop());
CHECK_EQUAL(3U, queue.size());
CHECK(queue.pop());
CHECK_EQUAL(2U, queue.size());
CHECK(queue.pop());
CHECK_EQUAL(1U, queue.size());
CHECK_EQUAL(4, queue.front());
CHECK_EQUAL(1U, queue.size());
CHECK_EQUAL(4, queue.front());
CHECK_EQUAL(1U, queue.size());
CHECK(queue.pop());
CHECK_EQUAL(0U, queue.size());
}
//*************************************************************************
TEST(test_multiple_emplace)
{

View File

@ -475,6 +475,46 @@ namespace
CHECK_EQUAL(255U, queue.size());
}
//*************************************************************************
TEST(test_size_push_front_pop)
{
access.clear();
etl::queue_spsc_locked<int, 4, etl::memory_model::MEMORY_MODEL_SMALL> queue(lock, unlock);
CHECK_EQUAL(0U, queue.size());
queue.push(1);
queue.push(2);
queue.push(3);
queue.push(4);
CHECK_EQUAL(4U, queue.size());
CHECK_EQUAL(1, queue.front());
CHECK_EQUAL(4U, queue.size());
CHECK_EQUAL(1, queue.front());
CHECK_EQUAL(4U, queue.size());
CHECK(queue.pop());
CHECK_EQUAL(3U, queue.size());
CHECK(queue.pop());
CHECK_EQUAL(2U, queue.size());
CHECK(queue.pop());
CHECK_EQUAL(1U, queue.size());
CHECK_EQUAL(4, queue.front());
CHECK_EQUAL(1U, queue.size());
CHECK_EQUAL(4, queue.front());
CHECK_EQUAL(1U, queue.size());
CHECK(queue.pop());
CHECK_EQUAL(0U, queue.size());
}
//*************************************************************************
TEST(test_multiple_emplace)
{