Soldered 125kHz RFID board Arduino library 1.0.0
Library for Soldered 125kHz RFID board.
Loading...
Searching...
No Matches
circular_queue_mp.h
Go to the documentation of this file.
1/*
2circular_queue_mp.h - Implementation of a lock-free circular queue for EspSoftwareSerial.
3Copyright (c) 2019 Dirk O. Kaar. All rights reserved.
4
5This library is free software; you can redistribute it and/or
6modify it under the terms of the GNU Lesser General Public
7License as published by the Free Software Foundation; either
8version 2.1 of the License, or (at your option) any later version.
9
10This library is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13Lesser General Public License for more details.
14
15You should have received a copy of the GNU Lesser General Public
16License along with this library; if not, write to the Free Software
17Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18*/
19
20#ifndef __circular_queue_mp_h
21#define __circular_queue_mp_h
22
23#include "circular_queue.h"
24
25#ifdef ESP8266
26#include "interrupts.h"
27#else
28#include <mutex>
29#endif
30
37template< typename T, typename ForEachArg = void >
38class circular_queue_mp : protected circular_queue<T, ForEachArg>
39{
40public:
41 circular_queue_mp() = default;
42 circular_queue_mp(const size_t capacity) : circular_queue<T, ForEachArg>(capacity)
43 {}
45 {}
46 using circular_queue<T, ForEachArg>::operator=;
47 using circular_queue<T, ForEachArg>::capacity;
48 using circular_queue<T, ForEachArg>::flush;
49 using circular_queue<T, ForEachArg>::available;
50 using circular_queue<T, ForEachArg>::available_for_push;
51 using circular_queue<T, ForEachArg>::peek;
52 using circular_queue<T, ForEachArg>::pop;
53 using circular_queue<T, ForEachArg>::pop_n;
54 using circular_queue<T, ForEachArg>::for_each;
55 using circular_queue<T, ForEachArg>::for_each_rev_requeue;
56
64 bool capacity(const size_t cap)
65 {
66#ifdef ESP8266
67 esp8266::InterruptLock lock;
68#else
69 std::lock_guard<std::mutex> lock(m_pushMtx);
70#endif
72 }
73
74 bool IRAM_ATTR push() = delete;
75
82 bool IRAM_ATTR push(T&& val)
83 {
84#ifdef ESP8266
85 esp8266::InterruptLock lock;
86#else
87 std::lock_guard<std::mutex> lock(m_pushMtx);
88#endif
90 }
91
98 bool IRAM_ATTR push(const T& val)
99 {
100#ifdef ESP8266
101 esp8266::InterruptLock lock;
102#else
103 std::lock_guard<std::mutex> lock(m_pushMtx);
104#endif
106 }
107
115 size_t push_n(const T* buffer, size_t size)
116 {
117#ifdef ESP8266
118 esp8266::InterruptLock lock;
119#else
120 std::lock_guard<std::mutex> lock(m_pushMtx);
121#endif
122 return circular_queue<T, ForEachArg>::push_n(buffer, size);
123 }
124
131 T& pop_requeue();
132
139 bool for_each_requeue(const Delegate<bool(T&), ForEachArg>& fun);
140
141#ifndef ESP8266
142protected:
143 std::mutex m_pushMtx;
144#endif
145};
146
147template< typename T, typename ForEachArg >
149{
150#ifdef ESP8266
151 esp8266::InterruptLock lock;
152#else
153 std::lock_guard<std::mutex> lock(m_pushMtx);
154#endif
158 if (inPos == outPos) return circular_queue<T, ForEachArg>::defaultValue;
160 const auto bufSize = circular_queue<T, ForEachArg>::m_bufSize;
164 return val;
165}
166
167template< typename T, typename ForEachArg >
169{
173 if (outPos == inPos0) return false;
174 do {
176 if (fun(val))
177 {
178#ifdef ESP8266
179 esp8266::InterruptLock lock;
180#else
181 std::lock_guard<std::mutex> lock(m_pushMtx);
182#endif
189 }
190 else
191 {
193 }
194 outPos = (outPos + 1) % circular_queue<T, ForEachArg>::m_bufSize;
196 } while (outPos != inPos0);
197 return true;
198}
199
200#endif // __circular_queue_mp_h
Definition Delegate.h:2049
Instance class for a multi-producer, single-consumer circular queue / ring buffer (FIFO)....
Definition circular_queue_mp.h:39
bool IRAM_ATTR push(T &&val)
Move the rvalue parameter into the queue, guarded for multiple concurrent producers.
Definition circular_queue_mp.h:82
size_t push_n(const T *buffer, size_t size)
Push copies of multiple elements from a buffer into the queue, in order, beginning at buffer's head....
Definition circular_queue_mp.h:115
circular_queue_mp(const size_t capacity)
Definition circular_queue_mp.h:42
bool for_each_requeue(const Delegate< bool(T &), ForEachArg > &fun)
Iterate over, pop and optionally requeue each available element from the queue, calling back fun with...
Definition circular_queue_mp.h:168
circular_queue_mp(circular_queue< T, ForEachArg > &&cq)
Definition circular_queue_mp.h:44
bool IRAM_ATTR push()=delete
T & pop_requeue()
Pops the next available element from the queue, requeues it immediately.
Definition circular_queue_mp.h:148
bool IRAM_ATTR push(const T &val)
Push a copy of the parameter into the queue, guarded for multiple concurrent producers.
Definition circular_queue_mp.h:98
circular_queue_mp()=default
std::mutex m_pushMtx
Definition circular_queue_mp.h:143
bool capacity(const size_t cap)
Resize the queue. The available elements in the queue are preserved. This is not lock-free,...
Definition circular_queue_mp.h:64
Instance class for a single-producer, single-consumer circular queue / ring buffer (FIFO)....
Definition circular_queue.h:48
size_t push_n(const T *buffer, size_t size)
Push copies of multiple elements from a buffer into the queue, in order, beginning at buffer's head.
Definition circular_queue.h:282
void for_each(const Delegate< void(T &&), void > &fun)
T pop()
Definition circular_queue.h:309
size_t available() const
Definition circular_queue.h:111
void flush()
Definition circular_queue.h:103
size_t pop_n(T *buffer, size_t size)
Definition circular_queue.h:326
size_t capacity() const
Definition circular_queue.h:86
T peek() const
Definition circular_queue.h:133
size_t available_for_push() const
Definition circular_queue.h:121
bool for_each_rev_requeue(const Delegate< bool(T &), void > &fun)
bool IRAM_ATTR push() __attribute__((always_inline))
Release the next pending input value, accessible by pushpeek(), into the queue.
Definition circular_queue.h:156
Definition ghostl.h:32
void atomic_thread_fence(std::memory_order order) noexcept
Definition ghostl.h:49
T && move(T &t) noexcept
Definition ghostl.h:50
@ memory_order_relaxed
Definition ghostl.h:35
@ memory_order_release
Definition ghostl.h:37
@ memory_order_acquire
Definition ghostl.h:36