iPlug2 - C++ Audio Plug-in Framework
Loading...
Searching...
No Matches
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#include "IPlugPlatform.h"
24
25BEGIN_IPLUG_NAMESPACE
26
30template<typename T>
31class IPlugQueue final
32{
33public:
36 IPlugQueue(int size)
37 {
38 Resize(size);
39 }
40
41 ~IPlugQueue(){}
42
43 IPlugQueue(const IPlugQueue&) = delete;
44 IPlugQueue& operator=(const IPlugQueue&) = delete;
45
48 void Resize(int size)
49 {
50 mData.Resize(size + 1);
51 }
52
57 bool Push(const T& item)
58 {
59 const auto currentWriteIndex = mWriteIndex.load(std::memory_order_relaxed);
60 const auto nextWriteIndex = Increment(currentWriteIndex);
61 if(nextWriteIndex != mReadIndex.load(std::memory_order_acquire))
62 {
63 mData.Get()[currentWriteIndex] = item;
64 mWriteIndex.store(nextWriteIndex, std::memory_order_release);
65 return true;
66 }
67 return false;
68 }
69
74 bool Pop(T& item)
75 {
76 const auto currentReadIndex = mReadIndex.load(std::memory_order_relaxed);
77 if(currentReadIndex == mWriteIndex.load(std::memory_order_acquire))
78 {
79 return false; // empty the queue
80 }
81 item = mData.Get()[currentReadIndex];
82 mReadIndex.store(Increment(currentReadIndex), std::memory_order_release);
83 return true;
84 }
85
88 size_t ElementsAvailable() const
89 {
90 size_t write = mWriteIndex.load(std::memory_order_acquire);
91 size_t read = mReadIndex.load(std::memory_order_relaxed);
92
93 return (read > write) ? mData.GetSize() - (read - write) : write - read;
94 }
95
100 const T& Peek()
101 {
102 const auto currentReadIndex = mReadIndex.load(std::memory_order_relaxed);
103 return mData.Get()[currentReadIndex];
104 }
105
109 bool WasEmpty() const
110 {
111 return (mWriteIndex.load() == mReadIndex.load());
112 }
113
117 bool WasFull() const
118 {
119 const auto nextWriteIndex = Increment(mWriteIndex.load());
120 return (nextWriteIndex == mReadIndex.load());
121 }
122
123private:
127 size_t Increment(size_t idx) const
128 {
129 return (idx + 1) % (mData.GetSize());
130 }
131
132 WDL_TypedBuf<T> mData;
133 std::atomic<size_t> mWriteIndex{0};
134 std::atomic<size_t> mReadIndex{0};
135};
136
137END_IPLUG_NAMESPACE
Include to get consistently named preprocessor macros for different platforms and logging functionali...
A lock-free SPSC queue used to transfer data between threads based on MLQueue.h by Randy Jones based ...
Definition: IPlugQueue.h:32
const T & Peek()
Definition: IPlugQueue.h:100
bool WasEmpty() const
Definition: IPlugQueue.h:109
bool Pop(T &item)
Definition: IPlugQueue.h:74
size_t ElementsAvailable() const
Definition: IPlugQueue.h:88
bool Push(const T &item)
Definition: IPlugQueue.h:57
bool WasFull() const
Definition: IPlugQueue.h:117
IPlugQueue(int size)
IPlugQueue constructor.
Definition: IPlugQueue.h:36
void Resize(int size)
Definition: IPlugQueue.h:48