Skip to content

Commit 2c50633

Browse files
committed
Add comprehensive documentation to SlickQueue class
- Added Doxygen-style comments for class overview, constructors, and all public methods - Enhanced API documentation for better usability and maintainability of the lock-free queue implementation - Minor fix: corrected size() method to return size_ instead of mask_ + 1 for accuracy
1 parent ebaec3c commit 2c50633

File tree

1 file changed

+75
-7
lines changed

1 file changed

+75
-7
lines changed

include/slick_queue/slick_queue.h

Lines changed: 75 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,14 @@
3535

3636
namespace slick {
3737

38+
/**
39+
* @brief A lock-free multi-producer multi-consumer queue with optional shared memory support.
40+
*
41+
* This queue allows a multiple producer thread to write data and a multiple consumer thread to read data concurrently without locks.
42+
* It can optionally use shared memory for inter-process communication.
43+
*
44+
* @tparam T The type of elements stored in the queue.
45+
*/
3846
template<typename T>
3947
class SlickQueue {
4048
struct slot {
@@ -61,6 +69,15 @@ class SlickQueue {
6169
#endif
6270

6371
public:
72+
/**
73+
* @brief Construct a new SlickQueue object
74+
*
75+
* @param size The size of the queue, must be a power of 2.
76+
* @param shm_name The name of the shared memory segment. If nullptr, the queue will use local memory.
77+
*
78+
* @throws std::runtime_error if shared memory allocation fails.
79+
* @throws std::invalid_argument if size is not a power of 2.
80+
*/
6481
SlickQueue(uint32_t size, const char* const shm_name = nullptr)
6582
: size_(size)
6683
, buffered_size_(size + 1024) // add some buffer at the end
@@ -75,13 +92,15 @@ class SlickQueue {
7592
if (shm_name) {
7693
allocate_shm_data(shm_name, false);
7794
}
78-
79-
// if (own_) {
80-
// // invalidate first slot
81-
// control_[0].data_index.store(-1, std::memory_order_relaxed);
82-
// }
8395
}
8496

97+
/**
98+
* @brief Open an existing SlickQueue in shared memory
99+
*
100+
* @param shm_name The name of the shared memory segment.
101+
*
102+
* @throws std::runtime_error if shared memory allocation fails or the segment does not exist.
103+
*/
85104
SlickQueue(const char* const shm_name)
86105
: own_(false)
87106
, use_shm_(true)
@@ -124,32 +143,75 @@ class SlickQueue {
124143
}
125144
}
126145

146+
/**
147+
* @brief Check if the queue owns the memory buffer
148+
* @return true if the queue owns the memory buffer, false otherwise
149+
*/
127150
bool own_buffer() const noexcept { return own_; }
151+
152+
/**
153+
* @brief Check if the queue uses shared memory
154+
* @return true if the queue uses shared memory, false otherwise
155+
*/
128156
bool use_shm() const noexcept { return use_shm_; }
129-
constexpr uint32_t size() const noexcept { return mask_ + 1; }
130157

158+
/**
159+
* @brief Get the size of the queue
160+
* @return Size of the queue
161+
*/
162+
constexpr uint32_t size() const noexcept { return size_; }
163+
164+
/**
165+
* @brief Get the initial reading index, which is 0 if the queue is newly created or the current writing index if opened existing
166+
* @return Initial reading index
167+
*/
131168
uint64_t initial_reading_index() const noexcept {
132169
return reserved_->load(std::memory_order_relaxed);
133170
}
134171

172+
/**
173+
* @brief Reserve space in the queue for writing
174+
* @param n Number of slots to reserve, default is 1
175+
* @return The starting index of the reserved space
176+
*/
135177
uint64_t reserve(uint32_t n = 1) noexcept {
136178
return reserved_->fetch_add(n, std::memory_order_acq_rel);
137179
}
138180

181+
/**
182+
* @brief Access the reserved space for writing
183+
* @param index The index returned by reserve()
184+
* @return Pointer to the reserved space
185+
*/
139186
T* operator[] (uint64_t index) noexcept {
140187
return &data_[index & mask_];
141188
}
142189

190+
/**
191+
* @brief Access the reserved space for writing (const version)
192+
* @param index The index returned by reserve()
193+
* @return Pointer to the reserved space
194+
*/
143195
const T* operator[] (uint64_t index) const noexcept {
144196
return &data_[index & mask_];
145197
}
146198

199+
/**
200+
* @brief Publish the data written in the reserved space
201+
* @param index The index returned by reserve()
202+
* @param n Number of slots to publish, default is 1
203+
*/
147204
void publish(uint64_t index, uint32_t n = 1) noexcept {
148205
auto& slot = control_[index & mask_];
149206
slot.size = n;
150207
slot.data_index.store(index, std::memory_order_release);
151208
}
152209

210+
/**
211+
* @brief Read data from the queue
212+
* @param read_index Reference to the reading index, will be updated to the next index after reading
213+
* @return Pair of pointer to the data and the size of the data, or nullptr and 0 if no data is available
214+
*/
153215
std::pair<T*, uint32_t> read(uint64_t& read_index) noexcept {
154216
auto& slot = control_[read_index & mask_];
155217
auto index = slot.data_index.load(std::memory_order_relaxed);
@@ -169,7 +231,8 @@ class SlickQueue {
169231
}
170232

171233
/**
172-
* Read the last published data in the queue
234+
* @brief Read the last published data in the queue
235+
* @return Pointer to the last published data, or nullptr if no data is available
173236
*/
174237
T* read_last() noexcept {
175238
auto reserved = reserved_->load(std::memory_order_relaxed);
@@ -192,6 +255,11 @@ class SlickQueue {
192255
return &data_[index & mask_];
193256
}
194257

258+
/**
259+
* @brief Reset the queue, invalidating all existing data
260+
*
261+
* Note: This function is not thread-safe and should be called when no other threads are accessing the queue.
262+
*/
195263
void reset() noexcept {
196264
if (use_shm_) {
197265
control_ = new ((uint8_t*)lpvMem_ + 64) slot[buffered_size_];

0 commit comments

Comments
 (0)