iPlug2 - C++ Audio Plug-in Framework
IPlugQueue.h
Go to the documentation of this file.
1 /*
2  ==============================================================================
3 
4  This file is part of the iPlug 2 library. Copyright (C) the iPlug 2 developers.
5 
6  See LICENSE.txt for more info.
7 
8  ==============================================================================
9 */
10 
11 #pragma once
12 
18 #include <atomic>
19 #include <cstddef>
20 
21 #include "heapbuf.h"
22 
23 BEGIN_IPLUG_NAMESPACE
24 
28 template<typename T>
29 class IPlugQueue final
30 {
31 public:
34  IPlugQueue(int size)
35  {
36  Resize(size);
37  }
38 
39  ~IPlugQueue(){}
40 
41  IPlugQueue(const IPlugQueue&) = delete;
42  IPlugQueue& operator=(const IPlugQueue&) = delete;
43 
46  void Resize(int size)
47  {
48  mData.Resize(size + 1);
49  }
50 
55  bool Push(const T& item)
56  {
57  const auto currentWriteIndex = mWriteIndex.load(std::memory_order_relaxed);
58  const auto nextWriteIndex = Increment(currentWriteIndex);
59  if(nextWriteIndex != mReadIndex.load(std::memory_order_acquire))
60  {
61  mData.Get()[currentWriteIndex] = item;
62  mWriteIndex.store(nextWriteIndex, std::memory_order_release);
63  return true;
64  }
65  return false;
66  }
67 
72  bool Pop(T& item)
73  {
74  const auto currentReadIndex = mReadIndex.load(std::memory_order_relaxed);
75  if(currentReadIndex == mWriteIndex.load(std::memory_order_acquire))
76  {
77  return false; // empty the queue
78  }
79  item = mData.Get()[currentReadIndex];
80  mReadIndex.store(Increment(currentReadIndex), std::memory_order_release);
81  return true;
82  }
83 
86  size_t ElementsAvailable() const
87  {
88  return (mWriteIndex.load(std::memory_order_acquire) - mReadIndex.load(std::memory_order_relaxed))%mData.GetSize();
89  }
90 
95  const T& Peek()
96  {
97  const auto currentReadIndex = mReadIndex.load(std::memory_order_relaxed);
98  return mData[currentReadIndex];
99  }
100 
104  bool WasEmpty() const
105  {
106  return (mWriteIndex.load() == mReadIndex.load());
107  }
108 
112  bool WasFull() const
113  {
114  const auto nextWriteIndex = Increment(mWriteIndex.load());
115  return (nextWriteIndex == mReadIndex.load());
116  }
117 
118 private:
122  size_t Increment(size_t idx) const
123  {
124  return (idx + 1) % (mData.GetSize());
125  }
126 
127  WDL_TypedBuf<T> mData;
128  std::atomic<size_t> mWriteIndex{0};
129  std::atomic<size_t> mReadIndex{0};
130 };
131 
132 END_IPLUG_NAMESPACE
bool Push(const T &item)
Definition: IPlugQueue.h:55
IPlugQueue(int size)
IPlugQueue constructor.
Definition: IPlugQueue.h:34
size_t ElementsAvailable() const
Definition: IPlugQueue.h:86
bool WasFull() const
Definition: IPlugQueue.h:112
void Resize(int size)
Definition: IPlugQueue.h:46
const T & Peek()
Definition: IPlugQueue.h:95
bool Pop(T &item)
Definition: IPlugQueue.h:72
bool WasEmpty() const
Definition: IPlugQueue.h:104
A lock-free SPSC queue used to transfer data between threads based on MLQueue.h by Randy Jones based ...
Definition: IPlugQueue.h:29