From 9004f77702a31183d4713fdc9acd0c95ef017b55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kjell=20Hedstr=C3=B6m=20-=20seeking=20Senior=20Engineering?= =?UTF-8?q?=20roles=20as=20well=20as=20contract=20opportunities?= Date: Thu, 4 Jan 2024 15:33:19 -0700 Subject: [PATCH] Simplify - KISS SPSC (#22) * KISS, for now only one type of lock-free SPSC queue * rename file --- CMakeLists.txt | 6 +- README.md | 8 +- benchmark/benchmark_main.cpp | 4 +- benchmark/test_performance.cpp | 24 ++-- examples/spsc_main.cpp | 8 +- spsc.md | 5 +- src/q/mpsc_receiver_round_robin.hpp | 2 +- src/q/spmc_sender_round_robin.hpp | 2 +- src/q/spsc.hpp | 3 +- ...rcular_fifo.hpp => spsc_circular_fifo.hpp} | 2 - src/q/spsc_fixed_circular_fifo.hpp | 126 ------------------ src/q/test_queue.cpp | 81 +++-------- test/test.cmake | 8 ++ test/test_mpsc_spmc_round_robin_queues.cpp | 24 ++-- test/test_queue.cpp | 84 +++--------- test/test_spsc_circular_queue.cpp | 28 +--- 16 files changed, 97 insertions(+), 318 deletions(-) rename src/q/{spsc_flexible_circular_fifo.hpp => spsc_circular_fifo.hpp} (98%) delete mode 100644 src/q/spsc_fixed_circular_fifo.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index c29e6d3..b48712e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,11 @@ if ( NOT VERSION ) execute_process(COMMAND bash "-c" "git rev-list --branches HEAD | wc -l | tr -d ' ' | tr -d '\n'" OUTPUT_VARIABLE GIT_VERSION WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) endif() +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + message( STATUS "Compiler: ${CMAKE_C_COMPILER}") +message(STATUS "C++ version: ${CMAKE_CXX_STANDARD}") set(MINOR_VERSION 1) math(EXPR VERSION-BASE ${GIT_VERSION}/255) @@ -44,7 +48,7 @@ endif() # change to c++20 in version 2.0 if (MSVC) else () - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wunused -std=c++17 -pthread -D_GLIBCXX_USE_NANOSLEEP") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wunused -pthread -D_GLIBCXX_USE_NANOSLEEP") endif() if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") diff --git a/README.md b/README.md index 5e75fb0..ed1232b 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ All queues are in-process, thread-to-thread queues. This lock-free queue is safe to use between one producer thread and one consumer thread. **SPSC lock-free options:** 1. `fixed_circular_fifo`: Set the size of the queue in your code, the size is set during compiled time. -1. `flexible_circular_fifo`: Set the size of the queue in the constructor. +1. `circular_fifo`: Set the size of the queue in the constructor. _The SPSC is a powerful building block from which you can create more lock-free complicated queue structures if number of producers and consumers are known at creation time._ @@ -20,11 +20,11 @@ Please see [benchmark documentation](benchmark.md) for details. # NOT YET DOCUMENTED API 2. **MPMC:** *multiple producer, multiple consumer* - - `lock flexible-lock-queue`: runtime, at construction, set max size of queue or set to unlimited in size + - `dynamically sized, mutex-lock-queue`: runtime, at construction, set max size of queue or set to unlimited in size 3. **MPSC:** *multiple producer, singe consumer* - - `flexible or fixed lock-free circular fifo`: Using fair scheduling the many SPSC queues are consumed in an optimized round-robin manner + - `lock-free circular fifo`: Using fair scheduling the many SPSC queues are consumed in an optimized round-robin manner 4. **SPMC:** *single producer, multiple consumer* - - `flexible or fixed lock-free circular fifo`: Using fair scheduling the producer transfers over many SPSC queues + - `lock-free circular fifo`: Using fair scheduling the producer transfers over many SPSC queues diff --git a/benchmark/benchmark_main.cpp b/benchmark/benchmark_main.cpp index 1a24279..c55d8c5 100644 --- a/benchmark/benchmark_main.cpp +++ b/benchmark/benchmark_main.cpp @@ -4,7 +4,7 @@ #include "benchmark_runs.hpp" #include "q/mpmc_lock_queue.hpp" #include "q/q_api.hpp" -#include "q/spsc_flexible_circular_fifo.hpp" +#include "q/spsc_circular_fifo.hpp" namespace { const size_t kGoodSizedQueueSize = (2 << 16); // 65536 @@ -76,7 +76,7 @@ int main() { // Print the headers std::cout << "#runs,\t#p,\t#c,\t#msgs/s,\t#min_msgs/s,\t#max_msgs/s,\tavg call [ns],\tcomment" << std::endl; - auto spsc_result = benchmark_queue>("SPSC benchmark"); + auto spsc_result = benchmark_queue>("SPSC benchmark"); print_result(spsc_result); auto spsc_lockqueue_result = benchmark_queue>("SPSC using the lock-based MPMC benchmark"); diff --git a/benchmark/test_performance.cpp b/benchmark/test_performance.cpp index 9817f53..dffc08b 100644 --- a/benchmark/test_performance.cpp +++ b/benchmark/test_performance.cpp @@ -26,8 +26,8 @@ // using namespace test_performance; -// TEST(Performance, SPSC_Flexible_CircularFifo) { -// auto queue = queue_api::CreateQueue>(kGoodSizedQueueSize); +// TEST(Performance, SPSC_circular_fifo_CircularFifo) { +// auto queue = queue_api::CreateQueue>(kGoodSizedQueueSize); // auto result = RunSPS2C(queue, kAmount); // EXPECT_EQ(result.size(), 3); // auto sent = result[0]; @@ -38,13 +38,13 @@ // std::cout << "messages / second " << kAmount/(runner.nanotime * 1000000000) // } -// // TEST(Performance, SPSC_Flexible_CircularFifo) { -// // auto queue = queue_api::CreateQueue>(kSmallQueueSize); +// // TEST(Performance, SPSC_circular_fifo_CircularFifo) { +// // auto queue = queue_api::CreateQueue>(kSmallQueueSize); // // RunSPSC(queue, kAmount); // // } -// // TEST(Performance, SPSC_Flexible_CircularFifo_Smaller) { -// // auto queue = queue_api::CreateQueue>(kSmallQueueSize); +// // TEST(Performance, SPSC_circular_fifo_CircularFifo_Smaller) { +// // auto queue = queue_api::CreateQueue>(kSmallQueueSize); // // RunSPSC(queue, kAmount); // // } @@ -73,9 +73,9 @@ // // RunSPSC(queue, kAmount); // // } -// // TEST(Performance, DISABLED_SPSC_Flexible_20secRun_LargeData) { +// // TEST(Performance, DISABLED_SPSC_circular_fifo_20secRun_LargeData) { // // using namespace std; -// // auto queue = queue_api::CreateQueue>(kSmallQueueSize); +// // auto queue = queue_api::CreateQueue>(kSmallQueueSize); // // const size_t large = 65000; // // std::string payload(large, 'x'); // // EXPECT_EQ(large, payload.size()); @@ -124,7 +124,7 @@ // // TEST(Performance, DISABLED_lock_free__SPMC_1_to_4_20secRun_LargeData) { // // using namespace std; // // using element = std::string; -// // using qtype = spsc::flexible::circular_fifo; +// // using qtype = spsc::circular_fifo; // // using qtype_pair = std::tuple, queue_api::Receiver>; // // std::vector queues; // // for (size_t i = 0; i < 4; ++i) { @@ -141,7 +141,7 @@ // // TEST(Performance, DISABLED_lock_free__SPMC_1_to_4_20secRun_SmallData) { // // using namespace std; // // using element = std::string; -// // using qtype = spsc::flexible::circular_fifo; +// // using qtype = spsc::circular_fifo; // // using qtype_pair = std::tuple, queue_api::Receiver>; // // std::vector queues; // // for (size_t i = 0; i < 4; ++i) { @@ -182,7 +182,7 @@ // // TEST(Performance, DISABLED_lock_free__MPSC_4_to_1_20secRun_LargeData) { // // using namespace std; // // using element = std::string; -// // using qtype = spsc::flexible::circular_fifo; +// // using qtype = spsc::circular_fifo; // // using qtype_pair = std::tuple, queue_api::Receiver>; // // std::vector queues; // // for (size_t i = 0; i < 4; ++i) { @@ -199,7 +199,7 @@ // // TEST(Performance, DISABLED_lock_free__MPSC_4_to_1_20secRun_SmallData) { // // using namespace std; // // using element = std::string; -// // using qtype = spsc::flexible::circular_fifo; +// // using qtype = spsc::circular_fifo; // // using qtype_pair = std::tuple, queue_api::Receiver>; // // std::vector queues; // // for (size_t i = 0; i < 4; ++i) { diff --git a/examples/spsc_main.cpp b/examples/spsc_main.cpp index 32a99b5..73096b9 100644 --- a/examples/spsc_main.cpp +++ b/examples/spsc_main.cpp @@ -7,11 +7,11 @@ #include "q/spsc.hpp" // Alias for easier readability -using spsc_queue_type = spsc::flexible::circular_fifo; +using spsc_queue_type = spsc::circular_fifo; using sender_type = std::shared_ptr>; using receiver_type = std::shared_ptr>; -void produceMessages(queue_api::Sender>& sender, std::atomic& should_continue_working) { +void produceMessages(queue_api::Sender>& sender, std::atomic& should_continue_working) { std::vector greetings = {"Hello", "Bonjour", "Tjena", "Ciao", "Hola", "Hallo", "Hei", "Aloha", "Shalom", "Namaste", "Hello", "Bonjour", "Tjena", "Ciao", "Hola", "Hallo", "Hei", "Aloha", "Shalom", "Namaste"}; @@ -43,8 +43,8 @@ void consumeMessages(ReceiverQ& receiver, std::atomic& keep_working) { } int main() { - // Create a flexible SPSC queue with a dynamic size, determined at runtime initialization. - auto queue = queue_api::CreateQueue>(10); + // Create a circular_fifo SPSC queue with a dynamic size, determined at runtime initialization. + auto queue = queue_api::CreateQueue>(10); // Get the sender and receiver endpoints of the queue auto senderQ = std::get(queue); diff --git a/spsc.md b/spsc.md index ea2e8ff..604bb88 100644 --- a/spsc.md +++ b/spsc.md @@ -2,15 +2,14 @@ This lock-free queue is safe to use between one producer thread and one consumer thread. **SPSC lock-free options:** -1. `fixed_circular_fifo`: Set the size of the queue in your code, the size is set during compiled time. -1. `flexible_circular_fifo`: Set the size of the queue in the constructor. +1. `circular_fifo`: Set the size of the queue in the constructor. _The SPSC is a powerful building block from which you can create more lock-free complicated queue structures if number of producers and consumers are known at creation time._ **SPSC Naive Example** The raw and "unsafe" way to create the queue is to just "create it". This makes it harder to use right as the producer and consumer threads must only touch "their" parts of the API or the queue would not be thread-safe. ``` -using spsc_queue_type = spsc::flexible::circular_fifo; +using spsc_queue_type = spsc::circular_fifo; auto q_size = 1000; auto spsc_queue = spsc_queue_type(q_size); // through spsc_queue the FULL producer/consumer API is available, diff --git a/src/q/mpsc_receiver_round_robin.hpp b/src/q/mpsc_receiver_round_robin.hpp index 7d6fddc..24aed0d 100644 --- a/src/q/mpsc_receiver_round_robin.hpp +++ b/src/q/mpsc_receiver_round_robin.hpp @@ -29,7 +29,7 @@ #include #include "q/q_api.hpp" #include "q/round_robin_api.hpp" -#include "q/spsc_flexible_circular_fifo.hpp" +#include "q/spsc_circular_fifo.hpp" // MPSC : Many Single Producers - Single Consumer namespace mpsc { diff --git a/src/q/spmc_sender_round_robin.hpp b/src/q/spmc_sender_round_robin.hpp index 882b1e2..c1d0da5 100644 --- a/src/q/spmc_sender_round_robin.hpp +++ b/src/q/spmc_sender_round_robin.hpp @@ -30,7 +30,7 @@ #include #include "q/q_api.hpp" #include "q/round_robin_api.hpp" -#include "q/spsc_flexible_circular_fifo.hpp" +#include "q/spsc_circular_fifo.hpp" // MPSC : Many Single Producers - Single Consumer namespace spmc { diff --git a/src/q/spsc.hpp b/src/q/spsc.hpp index 72fbca4..ed5742b 100644 --- a/src/q/spsc.hpp +++ b/src/q/spsc.hpp @@ -21,5 +21,4 @@ #pragma once -#include "q/spsc_fixed_circular_fifo.hpp" -#include "q/spsc_flexible_circular_fifo.hpp" +#include "q/spsc_circular_fifo.hpp" diff --git a/src/q/spsc_flexible_circular_fifo.hpp b/src/q/spsc_circular_fifo.hpp similarity index 98% rename from src/q/spsc_flexible_circular_fifo.hpp rename to src/q/spsc_circular_fifo.hpp index 5bb778d..8e02690 100644 --- a/src/q/spsc_flexible_circular_fifo.hpp +++ b/src/q/spsc_circular_fifo.hpp @@ -30,7 +30,6 @@ #include namespace spsc { - namespace flexible { template class circular_fifo { public: @@ -138,5 +137,4 @@ namespace spsc { size_t circular_fifo::usage() const { return (100 * size() / kSize); } - } // namespace flexible } // namespace spsc diff --git a/src/q/spsc_fixed_circular_fifo.hpp b/src/q/spsc_fixed_circular_fifo.hpp deleted file mode 100644 index ba8b060..0000000 --- a/src/q/spsc_fixed_circular_fifo.hpp +++ /dev/null @@ -1,126 +0,0 @@ -/* -* Not any company's property but Public-Domain -* Do with source-code as you will. No requirement to keep this -* header if need to use it/change it/ or do whatever with it -* -* Note that there is No guarantee that this code will work -* and I take no responsibility for this code and any problems you -* might get if using it. -* -* Code & platform dependent issues with it was originally -* published at http://www.kjellkod.cc/threadsafecircularqueue -* 2012-16-19 @author Kjell Hedström, hedstrom@kjellkod.cc */ - -// should be mentioned the thinking of what goes where -// it is a "controversy" whether what is tail and what is head -// http://en.wikipedia.org/wiki/FIFO#Head_ortail__first - -#pragma once - -#include -#include -#include - -namespace spsc { - namespace fixed { - template - class circular_fifo { - public: - typedef char cache_line[64]; - enum alignas(64) { kSize = Size }; - enum alignas(64) { kCapacity = kSize + 1 }; // http://en.cppreference.com/w/cpp/types/aligned_storage - - circular_fifo() : - tail_(0), - head_(0) {} - virtual ~circular_fifo() {} - - bool push(Element& item); - bool pop(Element& item); - bool empty() const; - bool full() const; - size_t capacity() const; - size_t capacity_free() const; - size_t usage() const; - size_t size() const; - bool lock_free() const; - size_t tail() const { return tail_.load(); } - size_t head() const { return head_.load(); } - - private: - size_t increment(size_t idx) const { return (idx + 1) % kCapacity; } - - cache_line pad_storage_; - alignas(64) Element array_[kCapacity]; - cache_line padtail_; - alignas(64) std::atomic tail_; - cache_line padhead_; - alignas(64) std::atomic head_; // head(output) index - cache_line padend_; - }; - - template - bool circular_fifo::push(Element& item) { - const auto currenttail_ = tail_.load(std::memory_order_relaxed); - const auto nexttail_ = increment(currenttail_); - if (nexttail_ != head_.load(std::memory_order_acquire)) { - array_[currenttail_] = std::move(item); - tail_.store(nexttail_, std::memory_order_release); - return true; - } - - return false; // full queue - } - - // Pop by Consumer can only update the head (load with relaxed, store with release) - // the tail must be accessed with at least aquire - template - bool circular_fifo::pop(Element& item) { - const auto currenthead_ = head_.load(std::memory_order_relaxed); - if (currenthead_ == tail_.load(std::memory_order_acquire)) - return false; // empty queue - - item = std::move(array_[currenthead_]); - head_.store(increment(currenthead_), std::memory_order_release); - return true; - } - - template - bool circular_fifo::empty() const { - // snapshot with acceptance of that this comparison operation is not atomic - return (head_.load(std::memory_order_relaxed) == tail_.load(std::memory_order_relaxed)); - } - - // snapshot with acceptance that this comparison is not atomic - template - bool circular_fifo::full() const { - const auto nexttail_ = increment(tail_.load(std::memory_order_relaxed)); // aquire, we dont know who call - return (nexttail_ == head_.load(std::memory_order_relaxed)); - } - - template - bool circular_fifo::lock_free() const { - return std::atomic{}.is_lock_free(); - } - - template - size_t circular_fifo::size() const { - return ((tail_.load() - head_.load() + kCapacity) % kCapacity); - } - - template - size_t circular_fifo::capacity_free() const { - return (kCapacity - size() - 1); - } - - template - size_t circular_fifo::capacity() const { - return kSize; - } - - template - size_t circular_fifo::usage() const { - return (100 * size() / kSize); - } - } // namespace fixed -} // namespace spsc diff --git a/src/q/test_queue.cpp b/src/q/test_queue.cpp index 4194e92..14620f4 100644 --- a/src/q/test_queue.cpp +++ b/src/q/test_queue.cpp @@ -17,9 +17,7 @@ using namespace std; using Type = string; -using FlexibleQ = spsc::flexible::circular_fifo; -using FixedQ = spsc::fixed::circular_fifo; -using FixedSmallQ = spsc::fixed::circular_fifo; +using circular_fifoQ = spsc::circular_fifo; using LockedQ = mpmc::lock_queue; template @@ -44,19 +42,19 @@ void ProdConsInitialization(Prod& prod, Cons& cons) { } TEST(Queue, ProdConsInitialization) { - auto queue = queue_api::CreateQueue(10); + auto queue = queue_api::CreateQueue(10); auto producer = std::get(queue); auto consumer = std::get(queue); } TEST(Queue, ProdConsInitializationCopy) { using namespace queue_api; - using QueuePair = std::pair, Receiver>; - QueuePair queue = CreateQueue(10); - Sender sender1 = std::get(queue); - Sender sender2(std::get(queue)); - Receiver receiver1 = std::get(queue); - Receiver receiver2(std::get(queue)); + using QueuePair = std::pair, Receiver>; + QueuePair queue = CreateQueue(10); + Sender sender1 = std::get(queue); + Sender sender2(std::get(queue)); + Receiver receiver1 = std::get(queue); + Receiver receiver2(std::get(queue)); } struct HasWaitAndPop { @@ -117,8 +115,8 @@ struct HasPush { } }; -TEST(Queue, BaseAPI_Flexible) { - auto queue = queue_api::CreateQueue(10); +TEST(Queue, BaseAPI_circular_fifo) { + auto queue = queue_api::CreateQueue(10); auto producer = std::get(queue); auto consumer = std::get(queue); EXPECT_TRUE(producer.empty()); @@ -130,18 +128,6 @@ TEST(Queue, BaseAPI_Flexible) { EXPECT_EQ(0, producer.usage()); } -TEST(Queue, BaseAPI_Fixed) { - auto queue = queue_api::CreateQueue(); - auto producer = std::get(queue); - auto consumer = std::get(queue); - EXPECT_TRUE(producer.empty()); - EXPECT_FALSE(producer.full()); - EXPECT_EQ(100, producer.capacity()); - EXPECT_EQ(100, producer.capacity_free()); - EXPECT_EQ(0, producer.size()); - EXPECT_TRUE(producer.lock_free()); - EXPECT_EQ(0, producer.usage()); -} TEST(Queue, BaseAPI_DynamicLocked) { auto queue = queue_api::CreateQueue(10); @@ -216,10 +202,8 @@ void QAddOne(Prod& prod) { } TEST(Queue, CircularQueue_AddOne) { - FlexibleQ dQ{100}; + circular_fifoQ dQ{100}; QAddOne(dQ); - - FixedQ fQ{}; QAddOne(fQ); } @@ -258,19 +242,13 @@ void AddTillFullRemoveTillEmpty(Prod& prod, Cons& cons) { } } -TEST(Queue, FlexibleQueue_AddTillFullRemoveTillEmpty) { - auto queue = queue_api::CreateQueue(100); +TEST(Queue, circular_fifoQueue_AddTillFullRemoveTillEmpty) { + auto queue = queue_api::CreateQueue(100); auto producer = std::get(queue); auto consumer = std::get(queue); AddTillFullRemoveTillEmpty(producer, consumer); } -TEST(Queue, FixedQueue_AddTillFullRemoveTillEmpty) { - auto queue = queue_api::CreateQueue(); - auto producer = std::get(queue); - auto consumer = std::get(queue); - AddTillFullRemoveTillEmpty(producer, consumer); -} TEST(Queue, LockedQ_AddTillFullRemoveTillEmpty) { auto queue = queue_api::CreateQueue(100); @@ -298,15 +276,8 @@ void MoveArgument(Prod& prod, Cons& cons) { EXPECT_EQ("hello", arg); } -TEST(Queue, FlexibleQ_MoveArgument) { - auto queue = queue_api::CreateQueue(2); - auto producer = std::get(queue); - auto consumer = std::get(queue); - MoveArgument(producer, consumer); -} - -TEST(Queue, FixedSmallQ_MoveArgument) { - auto queue = queue_api::CreateQueue(); +TEST(Queue, circular_fifoQ_MoveArgument) { + auto queue = queue_api::CreateQueue(2); auto producer = std::get(queue); auto consumer = std::get(queue); MoveArgument(producer, consumer); @@ -343,15 +314,8 @@ namespace { using Unique = unique_ptr; } -TEST(Queue, FlexibleQ_MoveUnique) { - auto queue = queue_api::CreateQueue>(2); - auto producer = std::get(queue); - auto consumer = std::get(queue); - MoveUniquePtrArgument(producer, consumer); -} - -TEST(Queue, FixedQ_MoveUnique) { - auto queue = queue_api::CreateQueue>(); +TEST(Queue, circular_fifoQ_MoveUnique) { + auto queue = queue_api::CreateQueue>(2); auto producer = std::get(queue); auto consumer = std::get(queue); MoveUniquePtrArgument(producer, consumer); @@ -394,15 +358,8 @@ namespace { using Ptr = string*; } -TEST(Queue, FlexibleQ_NoMoveOfPtr) { - auto queue = queue_api::CreateQueue>(2); - auto producer = std::get(queue); - auto consumer = std::get(queue); - NoMovePtrArgument(producer, consumer); -} - -TEST(Queue, FixedQ_NoMoveOfPtr) { - auto queue = queue_api::CreateQueue>(); +TEST(Queue, circular_fifo_fifo_fifo_fifo_fifoQ_NoMoveOfPtr) { + auto queue = queue_api::CreateQueue>(2); auto producer = std::get(queue); auto consumer = std::get(queue); NoMovePtrArgument(producer, consumer); diff --git a/test/test.cmake b/test/test.cmake index d4939ce..c9b61e9 100644 --- a/test/test.cmake +++ b/test/test.cmake @@ -4,6 +4,14 @@ # ===================================================== # ref: https://google.github.io/googletest/quickstart-cmake.html + + +# Avoid warning about DOWNLOAD_EXTRACT_TIMESTAMP in CMake 3.24: +if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.24.0") + cmake_policy(SET CMP0135 NEW) +endif() + + include(FetchContent) FetchContent_Declare( googletest diff --git a/test/test_mpsc_spmc_round_robin_queues.cpp b/test/test_mpsc_spmc_round_robin_queues.cpp index 8198dce..7023e06 100644 --- a/test/test_mpsc_spmc_round_robin_queues.cpp +++ b/test/test_mpsc_spmc_round_robin_queues.cpp @@ -13,11 +13,11 @@ #include "q/mpsc_receiver_round_robin.hpp" #include "q/q_api.hpp" #include "q/spmc_sender_round_robin.hpp" -#include "q/spsc_flexible_circular_fifo.hpp" +#include "q/spsc_circular_fifo.hpp" TEST(MPSC_SPMC, CreateOneQueue_MPSC) { using element = std::string; - using qtype = spsc::flexible::circular_fifo; + using qtype = spsc::circular_fifo; auto queue = queue_api::CreateQueue(10); auto producer = std::get(queue); auto temporary = std::get(queue); @@ -37,7 +37,7 @@ TEST(MPSC_SPMC, CreateOneQueue_MPSC) { TEST(MPSC_SPMC, CreateManyQueues) { using element = std::string; - using qtype = spsc::flexible::circular_fifo; + using qtype = spsc::circular_fifo; constexpr auto senderID = queue_api::index::sender; constexpr auto receiverID = queue_api::index::receiver; @@ -58,7 +58,7 @@ TEST(MPSC_SPMC, CreateManyQueues) { TEST(MPSC_SPMC, RoundRobinOfOne) { using element = std::string; - using qtype = spsc::flexible::circular_fifo; + using qtype = spsc::circular_fifo; auto queue = queue_api::CreateQueue(2); auto temporary = std::get(queue); // convert the setup to a MPSC setup @@ -73,7 +73,7 @@ TEST(MPSC_SPMC, RoundRobinOfOne) { TEST(MPSC_SPMC, RoundRobinOfMany) { using element = std::string; - using qtype = spsc::flexible::circular_fifo; + using qtype = spsc::circular_fifo; auto q1 = queue_api::CreateQueue(2); auto q2 = queue_api::CreateQueue(2); auto r1 = std::get(q1); @@ -94,7 +94,7 @@ TEST(MPSC_SPMC, RoundRobinOfMany) { TEST(MPSC_SPMC, full) { using element = std::string; - using qtype = spsc::flexible::circular_fifo; + using qtype = spsc::circular_fifo; auto q1 = queue_api::CreateQueue(1); auto q2 = queue_api::CreateQueue(1); auto r1 = std::get(q1); @@ -119,7 +119,7 @@ TEST(MPSC_SPMC, full) { TEST(MPSC_SPMC, size) { using element = std::string; - using qtype = spsc::flexible::circular_fifo; + using qtype = spsc::circular_fifo; auto q1 = queue_api::CreateQueue(1); auto q2 = queue_api::CreateQueue(1); auto r1 = std::get(q1); @@ -144,7 +144,7 @@ TEST(MPSC_SPMC, size) { TEST(MPSC_SPMC, pop) { using element = std::string; - using qtype = spsc::flexible::circular_fifo; + using qtype = spsc::circular_fifo; auto q1 = queue_api::CreateQueue(1); auto q2 = queue_api::CreateQueue(1); auto r1 = std::get(q1); @@ -179,7 +179,7 @@ TEST(MPSC_SPMC, pop) { TEST(MPSC_SPMC, usage) { using element = std::string; - using qtype = spsc::flexible::circular_fifo; + using qtype = spsc::circular_fifo; auto q1 = queue_api::CreateQueue(1); auto q2 = queue_api::CreateQueue(1); auto r1 = std::get(q1); @@ -201,7 +201,7 @@ TEST(MPSC_SPMC, usage) { TEST(MPSC_SPMC, CreateOneQueue_SPMC) { using element = std::string; - using qtype = spsc::flexible::circular_fifo; + using qtype = spsc::circular_fifo; auto queue = queue_api::CreateQueue(10); auto temporary = std::get(queue); auto consumer = std::get(queue); @@ -221,7 +221,7 @@ TEST(MPSC_SPMC, CreateOneQueue_SPMC) { TEST(MPSC_SPMC, CreateManyQueues_SPMC) { using element = std::string; - using qtype = spsc::flexible::circular_fifo; + using qtype = spsc::circular_fifo; constexpr auto senderID = queue_api::index::sender; constexpr auto receiverID = queue_api::index::receiver; @@ -242,7 +242,7 @@ TEST(MPSC_SPMC, CreateManyQueues_SPMC) { TEST(MPSC_SPMC, push_SPMC) { using element = std::string; - using qtype = spsc::flexible::circular_fifo; + using qtype = spsc::circular_fifo; auto q1 = queue_api::CreateQueue(1); auto q2 = queue_api::CreateQueue(1); auto r1 = std::get(q1); diff --git a/test/test_queue.cpp b/test/test_queue.cpp index 4194e92..ec9a587 100644 --- a/test/test_queue.cpp +++ b/test/test_queue.cpp @@ -17,9 +17,7 @@ using namespace std; using Type = string; -using FlexibleQ = spsc::flexible::circular_fifo; -using FixedQ = spsc::fixed::circular_fifo; -using FixedSmallQ = spsc::fixed::circular_fifo; +using circular_fifoQ = spsc::circular_fifo; using LockedQ = mpmc::lock_queue; template @@ -44,19 +42,19 @@ void ProdConsInitialization(Prod& prod, Cons& cons) { } TEST(Queue, ProdConsInitialization) { - auto queue = queue_api::CreateQueue(10); + auto queue = queue_api::CreateQueue(10); auto producer = std::get(queue); auto consumer = std::get(queue); } TEST(Queue, ProdConsInitializationCopy) { using namespace queue_api; - using QueuePair = std::pair, Receiver>; - QueuePair queue = CreateQueue(10); - Sender sender1 = std::get(queue); - Sender sender2(std::get(queue)); - Receiver receiver1 = std::get(queue); - Receiver receiver2(std::get(queue)); + using QueuePair = std::pair, Receiver>; + QueuePair queue = CreateQueue(10); + Sender sender1 = std::get(queue); + Sender sender2(std::get(queue)); + Receiver receiver1 = std::get(queue); + Receiver receiver2(std::get(queue)); } struct HasWaitAndPop { @@ -117,8 +115,8 @@ struct HasPush { } }; -TEST(Queue, BaseAPI_Flexible) { - auto queue = queue_api::CreateQueue(10); +TEST(Queue, BaseAPI_circular_fifo) { + auto queue = queue_api::CreateQueue(10); auto producer = std::get(queue); auto consumer = std::get(queue); EXPECT_TRUE(producer.empty()); @@ -130,19 +128,6 @@ TEST(Queue, BaseAPI_Flexible) { EXPECT_EQ(0, producer.usage()); } -TEST(Queue, BaseAPI_Fixed) { - auto queue = queue_api::CreateQueue(); - auto producer = std::get(queue); - auto consumer = std::get(queue); - EXPECT_TRUE(producer.empty()); - EXPECT_FALSE(producer.full()); - EXPECT_EQ(100, producer.capacity()); - EXPECT_EQ(100, producer.capacity_free()); - EXPECT_EQ(0, producer.size()); - EXPECT_TRUE(producer.lock_free()); - EXPECT_EQ(0, producer.usage()); -} - TEST(Queue, BaseAPI_DynamicLocked) { auto queue = queue_api::CreateQueue(10); auto producer = std::get(queue); @@ -216,11 +201,8 @@ void QAddOne(Prod& prod) { } TEST(Queue, CircularQueue_AddOne) { - FlexibleQ dQ{100}; + circular_fifoQ dQ{100}; QAddOne(dQ); - - FixedQ fQ{}; - QAddOne(fQ); } template @@ -258,15 +240,8 @@ void AddTillFullRemoveTillEmpty(Prod& prod, Cons& cons) { } } -TEST(Queue, FlexibleQueue_AddTillFullRemoveTillEmpty) { - auto queue = queue_api::CreateQueue(100); - auto producer = std::get(queue); - auto consumer = std::get(queue); - AddTillFullRemoveTillEmpty(producer, consumer); -} - -TEST(Queue, FixedQueue_AddTillFullRemoveTillEmpty) { - auto queue = queue_api::CreateQueue(); +TEST(Queue, circular_fifoQueue_AddTillFullRemoveTillEmpty) { + auto queue = queue_api::CreateQueue(100); auto producer = std::get(queue); auto consumer = std::get(queue); AddTillFullRemoveTillEmpty(producer, consumer); @@ -298,15 +273,8 @@ void MoveArgument(Prod& prod, Cons& cons) { EXPECT_EQ("hello", arg); } -TEST(Queue, FlexibleQ_MoveArgument) { - auto queue = queue_api::CreateQueue(2); - auto producer = std::get(queue); - auto consumer = std::get(queue); - MoveArgument(producer, consumer); -} - -TEST(Queue, FixedSmallQ_MoveArgument) { - auto queue = queue_api::CreateQueue(); +TEST(Queue, circular_fifoQ_MoveArgument) { + auto queue = queue_api::CreateQueue(2); auto producer = std::get(queue); auto consumer = std::get(queue); MoveArgument(producer, consumer); @@ -343,15 +311,8 @@ namespace { using Unique = unique_ptr; } -TEST(Queue, FlexibleQ_MoveUnique) { - auto queue = queue_api::CreateQueue>(2); - auto producer = std::get(queue); - auto consumer = std::get(queue); - MoveUniquePtrArgument(producer, consumer); -} - -TEST(Queue, FixedQ_MoveUnique) { - auto queue = queue_api::CreateQueue>(); +TEST(Queue, circular_fifoQ_MoveUnique) { + auto queue = queue_api::CreateQueue>(2); auto producer = std::get(queue); auto consumer = std::get(queue); MoveUniquePtrArgument(producer, consumer); @@ -394,15 +355,8 @@ namespace { using Ptr = string*; } -TEST(Queue, FlexibleQ_NoMoveOfPtr) { - auto queue = queue_api::CreateQueue>(2); - auto producer = std::get(queue); - auto consumer = std::get(queue); - NoMovePtrArgument(producer, consumer); -} - -TEST(Queue, FixedQ_NoMoveOfPtr) { - auto queue = queue_api::CreateQueue>(); +TEST(Queue, circular_fifoQ_NoMoveOfPtr) { + auto queue = queue_api::CreateQueue>(2); auto producer = std::get(queue); auto consumer = std::get(queue); NoMovePtrArgument(producer, consumer); diff --git a/test/test_spsc_circular_queue.cpp b/test/test_spsc_circular_queue.cpp index af692a9..817787b 100644 --- a/test/test_spsc_circular_queue.cpp +++ b/test/test_spsc_circular_queue.cpp @@ -14,9 +14,7 @@ #include "q/spsc.hpp" using namespace std; -using FlexibleQ = spsc::flexible::circular_fifo; -using FixedQ = spsc::fixed::circular_fifo; -using FixedSmallQ = spsc::fixed::circular_fifo; +using circular_fifoQ = spsc::circular_fifo; template void Initialization(Q& q) { @@ -31,9 +29,7 @@ void Initialization(Q& q) { } TEST(SPCS_CircularQueue, Initialization) { - FlexibleQ dQ{10}; - FixedQ fQ{}; - Initialization(fQ); + circular_fifoQ dQ{10}; Initialization(dQ); } @@ -49,9 +45,7 @@ void AddOne(Q& q) { } TEST(SPCS_CircularQueue, AddOne) { - FlexibleQ dQ{10}; - FixedQ fQ{}; - AddOne(fQ); + circular_fifoQ dQ{10}; AddOne(dQ); } @@ -71,9 +65,7 @@ void AddRemoveOne(Q& q) { } TEST(SPCS_CircularQueue, AddRemoveOne) { - FlexibleQ dQ{10}; - FixedQ fQ{}; - AddRemoveOne(fQ); + circular_fifoQ dQ{10}; AddRemoveOne(dQ); } @@ -114,9 +106,7 @@ void LoopTillBeginning(Q& q) { } TEST(SPCS_CircularQueue, LoopTillBeginning) { - FlexibleQ dQ{3}; - FixedSmallQ fQ{}; - LoopTillBeginning(fQ); + circular_fifoQ dQ{3}; LoopTillBeginning(dQ); } @@ -135,9 +125,7 @@ void Full(Q& q) { } TEST(SPCS_CircularQueue, Full) { - FlexibleQ dQ{10}; - FixedQ fQ{}; - Full(fQ); + circular_fifoQ dQ{10}; Full(dQ); } @@ -169,8 +157,6 @@ void AddTillFullRemoveTillEmpty(Q& q) { } TEST(SPCS_CircularQueue, AddTillFullRemoveTillEmpty) { - spsc::fixed::circular_fifo fQ; - spsc::flexible::circular_fifo dQ(10); - AddTillFullRemoveTillEmpty(fQ); + spsc::circular_fifo dQ(10); AddTillFullRemoveTillEmpty(dQ); }