Skip to content

Commit cb61a73

Browse files
committed
Add custom queue example, more readme
1 parent 342164f commit cb61a73

5 files changed

Lines changed: 112 additions & 2 deletions

File tree

README.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,3 +127,34 @@ Or alternatively spin up a `rtlog::LogProcessingThread`
127127
```c++
128128
rtlog::LogProcessingThread thread(logger, PrintMessage, std::chrono::milliseconds(10));
129129
```
130+
131+
## Customizing the queue type
132+
133+
If you don't want to use the SPSC moodycamel queue, you can provide your own queue type.
134+
135+
** IT IS UP TO YOU TO ENSURE THE QUEUE YOU PROVIDE IS LOCK-FREE AND REAL-TIME SAFE **
136+
137+
The queue must have the following:
138+
```c++
139+
template <typename T>
140+
class MyQueue
141+
{
142+
public:
143+
using value_type = T;
144+
145+
MyQueue(int capacity);
146+
bool try_dequeue(T& item); // MUST return false if the queue is empty
147+
148+
bool try_enqueue(T&& item);
149+
// OR
150+
bool try_enqueue(const T& item);
151+
};
152+
```
153+
154+
Then, when creating the logger, provide the queue type as a template parameter:
155+
156+
```c++
157+
using RealtimeLogger = rtlog::Logger<ExampleLogData, MAX_NUM_LOG_MESSAGES, MAX_LOG_MESSAGE_LENGTH, gSequenceNumber, MyQueue>;
158+
```
159+
160+
You can see an example of wrapping a known rt-safe queue in `examples/custom_queue_example`.

examples/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
add_subdirectory(everlog)
2+
add_subdirectory(custom_queue_example)
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
if (NOT TARGET farbot)
2+
include(FetchContent)
3+
4+
FetchContent_Declare(farbot
5+
GIT_REPOSITORY https://github.com/hogliux/farbot
6+
GIT_TAG 0416705394720c12f0d02e55c144e4f69bb06912
7+
)
8+
# Note we do not "MakeAvailable" here, because farbot does not fully work via FetchContent
9+
if(NOT farbot_POPULATED)
10+
FetchContent_Populate(farbot)
11+
endif()
12+
add_library(farbot INTERFACE)
13+
add_library(farbot::farbot ALIAS farbot)
14+
15+
target_include_directories(farbot INTERFACE
16+
$<BUILD_INTERFACE:${farbot_SOURCE_DIR}/include>
17+
$<INSTALL_INTERFACE:include>
18+
)
19+
endif()
20+
21+
add_executable(custom_queue_example
22+
customqueuemain.cpp
23+
)
24+
25+
target_link_libraries(custom_queue_example
26+
PRIVATE
27+
rtlog::rtlog
28+
farbot::farbot
29+
)
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#include <farbot/fifo.hpp>
2+
#include <rtlog/rtlog.h>
3+
4+
template <typename T> class FarbotMPSCQueueWrapper {
5+
farbot::fifo<T,
6+
farbot::fifo_options::concurrency::single, // Consumer
7+
farbot::fifo_options::concurrency::multiple, // Producer
8+
farbot::fifo_options::full_empty_failure_mode::
9+
return_false_on_full_or_empty, // consumer_failure_mode
10+
farbot::fifo_options::full_empty_failure_mode::
11+
overwrite_or_return_default> // producer_failure_mode
12+
13+
mQueue;
14+
15+
public:
16+
using value_type = T;
17+
18+
FarbotMPSCQueueWrapper(int capacity) : mQueue(capacity) {}
19+
20+
bool try_enqueue(T &&item) { return mQueue.push(std::move(item)); }
21+
bool try_dequeue(T &item) { return mQueue.pop(item); }
22+
};
23+
24+
struct LogData {};
25+
26+
std::atomic<size_t> gSequenceNumber{0};
27+
28+
int main() {
29+
rtlog::Logger<LogData, 128, 128, gSequenceNumber, FarbotMPSCQueueWrapper>
30+
logger;
31+
logger.Log({}, "Hello, World!");
32+
33+
logger.PrintAndClearLogQueue(
34+
[](const LogData &data, size_t sequenceNumber, const char *fstring, ...) {
35+
(void)data;
36+
std::array<char, 128> buffer;
37+
38+
va_list args;
39+
va_start(args, fstring);
40+
vsnprintf(buffer.data(), buffer.size(), fstring, args);
41+
va_end(args);
42+
43+
printf("{%zu} %s\n", sequenceNumber, buffer.data());
44+
});
45+
46+
return 0;
47+
}

include/rtlog/rtlog.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,10 @@ template <typename T> using rtlog_SPSC = moodycamel::ReaderWriterQueue<T, 512>;
154154
* Requirements on QType:
155155
* 1. Is real-time safe
156156
* 2. Accepts one type template paramter for the type to be queued
157-
* 3. Has a constructor that takes an integer which will be the queue's capacity
158-
* 4. Has methods `bool try_enqueue(T &&item)` and/or `bool try_enqueue(const T &item)` and `bool try_dequeue(T &item)`
157+
* 3. Has a constructor that takes an integer which will be the queue's
158+
* capacity
159+
* 4. Has methods `bool try_enqueue(T &&item)` and/or `bool
160+
* try_enqueue(const T &item)` and `bool try_dequeue(T &item)`
159161
*/
160162
template <typename LogData, size_t MaxNumMessages, size_t MaxMessageLength,
161163
std::atomic<std::size_t> &SequenceNumber,

0 commit comments

Comments
 (0)