Roc Toolkit internal modules
Roc Toolkit: real-time audio streaming
spsc_ring_buffer.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2024 Roc Streaming authors
3  *
4  * This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this
6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7  */
8 
9 //! @file roc_core/spsc_ring_buffer.h
10 //! @brief Single-producer single-consumer circular buffer of copyable objects.
11 
12 #ifndef ROC_CORE_SPSC_RING_BUFFER_H_
13 #define ROC_CORE_SPSC_RING_BUFFER_H_
14 
15 #include "roc_core/iarena.h"
16 #include "roc_core/noncopyable.h"
18 #include "roc_core/stddefs.h"
19 
20 namespace roc {
21 namespace core {
22 
23 //! Thread-safe lock-free single-producer single-consumer
24 //! circular buffer of copyable objects.
25 //!
26 //! Allows access from two concurrent threads: writer and reader.
27 //! Both writer and reader are never blocked.
28 //! Provides sequential consistency.
29 //!
30 //! @tparam T defines object type, it should be copyable.
31 //!
32 //! Implemented on top of SpscByteBuffer.
33 template <class T> class SpscRingBuffer : public NonCopyable<> {
34 public:
35  //! Initialize.
36  SpscRingBuffer(IArena& arena, size_t n_elements)
37  : byte_buf_(arena, sizeof(T), n_elements) {
38  }
39 
40  //! Deinitialize.
42  while (void* ptr = byte_buf_.begin_read()) {
43  static_cast<T*>(ptr)->~T();
44  byte_buf_.end_read();
45  }
46  }
47 
48  //! Check that allocation succeeded.
49  bool is_valid() const {
50  return byte_buf_.is_valid();
51  }
52 
53  //! Check if buffer is empty.
54  bool is_empty() const {
55  return byte_buf_.is_empty();
56  }
57 
58  //! Append element to the end of the buffer.
59  //! If buffer is full, drops element and returns false.
60  //! Should be called from writer thread.
61  //! Lock-free.
62  bool push_back(const T& element) {
63  void* ptr = byte_buf_.begin_write();
64  if (!ptr) {
65  return false;
66  }
67 
68  new (ptr) T(element);
69 
70  byte_buf_.end_write();
71 
72  return true;
73  }
74 
75  //! Fetch element from the beginning of the buffer.
76  //! If buffer is empty, returns false.
77  //! Should be called from reader thread.
78  //! Lock-free.
79  bool pop_front(T& element) {
80  void* ptr = byte_buf_.begin_read();
81  if (!ptr) {
82  element = T();
83  return false;
84  }
85 
86  element = *static_cast<T*>(ptr);
87  static_cast<T*>(ptr)->~T();
88 
89  byte_buf_.end_read();
90 
91  return true;
92  }
93 
94 private:
95  SpscByteBuffer byte_buf_;
96 };
97 
98 } // namespace core
99 } // namespace roc
100 
101 #endif // ROC_CORE_SPSC_RING_BUFFER_H_
Memory arena interface.
Definition: iarena.h:23
Base class for non-copyable objects.
Definition: noncopyable.h:23
Thread-safe lock-free single-producer single-consumer circular buffer of byte chunks.
void end_write()
End writing of a chunk. Should be called if and only if begin_write() returned non-NULL....
bool is_empty() const
Check if buffer is empty.
uint8_t * begin_write()
Begin writing of a chunk. If buffer is full, returns NULL. Should be called from writer thread....
bool is_valid() const
Check that initial allocation succeeded.
uint8_t * begin_read()
Begin reading of a chunk. If buffer is empty, returns NULL. Should be called from reader thread....
void end_read()
End reading of a chunk. Should be called if and only if begin_read() returned non-NULL....
Thread-safe lock-free single-producer single-consumer circular buffer of copyable objects.
SpscRingBuffer(IArena &arena, size_t n_elements)
Initialize.
bool push_back(const T &element)
Append element to the end of the buffer. If buffer is full, drops element and returns false....
bool pop_front(T &element)
Fetch element from the beginning of the buffer. If buffer is empty, returns false....
~SpscRingBuffer()
Deinitialize.
bool is_valid() const
Check that allocation succeeded.
bool is_empty() const
Check if buffer is empty.
Memory arena interface.
Root namespace.
Non-copyable object.
Single-producer single-consumer circular buffer of byte chunks.
Commonly used types and functions.