diff --git a/README.md b/README.md index 4fe8c51..4b5a8b4 100644 --- a/README.md +++ b/README.md @@ -127,3 +127,34 @@ Or alternatively spin up a `rtlog::LogProcessingThread` ```c++ rtlog::LogProcessingThread thread(logger, PrintMessage, std::chrono::milliseconds(10)); ``` + +## Customizing the queue type + +If you don't want to use the SPSC moodycamel queue, you can provide your own queue type. + +** IT IS UP TO YOU TO ENSURE THE QUEUE YOU PROVIDE IS LOCK-FREE AND REAL-TIME SAFE ** + +The queue must have the following: +```c++ +template +class MyQueue +{ +public: + using value_type = T; + + MyQueue(int capacity); + bool try_dequeue(T& item); // MUST return false if the queue is empty + + bool try_enqueue(T&& item); + // OR + bool try_enqueue(const T& item); +}; +``` + +Then, when creating the logger, provide the queue type as a template parameter: + +```c++ +using RealtimeLogger = rtlog::Logger; +``` + +You can see an example of wrapping a known rt-safe queue in `examples/custom_queue_example`. diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 4075de1..522d6e5 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1 +1,2 @@ add_subdirectory(everlog) +add_subdirectory(custom_queue_example) diff --git a/examples/custom_queue_example/CMakeLists.txt b/examples/custom_queue_example/CMakeLists.txt new file mode 100644 index 0000000..5e3ada1 --- /dev/null +++ b/examples/custom_queue_example/CMakeLists.txt @@ -0,0 +1,29 @@ +if (NOT TARGET farbot) + include(FetchContent) + + FetchContent_Declare(farbot + GIT_REPOSITORY https://github.com/hogliux/farbot + GIT_TAG 0416705394720c12f0d02e55c144e4f69bb06912 + ) + # Note we do not "MakeAvailable" here, because farbot does not fully work via FetchContent + if(NOT farbot_POPULATED) + FetchContent_Populate(farbot) + endif() + add_library(farbot INTERFACE) + add_library(farbot::farbot ALIAS farbot) + + target_include_directories(farbot INTERFACE + $ + $ + ) +endif() + +add_executable(custom_queue_example + customqueuemain.cpp +) + +target_link_libraries(custom_queue_example + PRIVATE + rtlog::rtlog + farbot::farbot +) diff --git a/examples/custom_queue_example/customqueuemain.cpp b/examples/custom_queue_example/customqueuemain.cpp new file mode 100644 index 0000000..0bf6973 --- /dev/null +++ b/examples/custom_queue_example/customqueuemain.cpp @@ -0,0 +1,47 @@ +#include +#include + +template class FarbotMPSCQueueWrapper { + farbot::fifo // producer_failure_mode + + mQueue; + +public: + using value_type = T; + + FarbotMPSCQueueWrapper(int capacity) : mQueue(capacity) {} + + bool try_enqueue(T &&item) { return mQueue.push(std::move(item)); } + bool try_dequeue(T &item) { return mQueue.pop(item); } +}; + +struct LogData {}; + +std::atomic gSequenceNumber{0}; + +int main() { + rtlog::Logger + logger; + logger.Log({}, "Hello, World!"); + + logger.PrintAndClearLogQueue( + [](const LogData &data, size_t sequenceNumber, const char *fstring, ...) { + (void)data; + std::array buffer; + + va_list args; + va_start(args, fstring); + vsnprintf(buffer.data(), buffer.size(), fstring, args); + va_end(args); + + printf("{%zu} %s\n", sequenceNumber, buffer.data()); + }); + + return 0; +} diff --git a/include/rtlog/rtlog.h b/include/rtlog/rtlog.h index ce0169d..351ed6f 100644 --- a/include/rtlog/rtlog.h +++ b/include/rtlog/rtlog.h @@ -154,8 +154,10 @@ template using rtlog_SPSC = moodycamel::ReaderWriterQueue; * Requirements on QType: * 1. Is real-time safe * 2. Accepts one type template paramter for the type to be queued - * 3. Has a constructor that takes an integer which will be the queue's capacity - * 4. Has methods `bool try_enqueue(T &&item)` and/or `bool try_enqueue(const T &item)` and `bool try_dequeue(T &item)` + * 3. Has a constructor that takes an integer which will be the queue's + * capacity + * 4. Has methods `bool try_enqueue(T &&item)` and/or `bool + * try_enqueue(const T &item)` and `bool try_dequeue(T &item)` */ template &SequenceNumber,