Skip to content

Commit 725b6c9

Browse files
committed
Enhanced circular_queue from EspSoftwareSerial.
1 parent f4fbf2f commit 725b6c9

File tree

2 files changed

+46
-7
lines changed

2 files changed

+46
-7
lines changed

libraries/FastScheduler/src/circular_queue/circular_queue.h

+37-6
Original file line numberDiff line numberDiff line change
@@ -123,19 +123,35 @@ class circular_queue
123123
}
124124

125125
/*!
126-
@brief Peek at the next element pop returns without removing it from the queue.
127-
@return An rvalue copy of the next element that can be popped, or a default
128-
value of type T if the queue is empty.
126+
@brief Peek at the next element pop will return without removing it from the queue.
127+
@return An rvalue copy of the next element that can be popped. If the queue is empty,
128+
return an rvalue copy of the element that is pending the next push.
129129
*/
130130
T peek() const
131131
{
132-
const auto outPos = m_outPos.load(std::memory_order_acquire);
132+
const auto outPos = m_outPos.load(std::memory_order_relaxed);
133+
std::atomic_thread_fence(std::memory_order_acquire);
134+
return m_buffer[outPos];
135+
}
136+
137+
/*!
138+
@brief Peek at the next pending input value.
139+
@return A reference to the next element that can be pushed.
140+
*/
141+
T& IRAM_ATTR pushpeek()
142+
{
133143
const auto inPos = m_inPos.load(std::memory_order_relaxed);
134144
std::atomic_thread_fence(std::memory_order_acquire);
135-
if (inPos == outPos) return defaultValue;
136-
else return m_buffer[outPos];
145+
return m_buffer[inPos];
137146
}
138147

148+
/*!
149+
@brief Release the next pending input value, accessible by pushpeek(), into the queue.
150+
@return true if the queue accepted the value, false if the queue
151+
was full.
152+
*/
153+
bool IRAM_ATTR push();
154+
139155
/*!
140156
@brief Move the rvalue parameter into the queue.
141157
@return true if the queue accepted the value, false if the queue
@@ -212,6 +228,21 @@ bool circular_queue<T>::capacity(const size_t cap)
212228
return true;
213229
}
214230

231+
template< typename T >
232+
bool IRAM_ATTR circular_queue<T>::push()
233+
{
234+
const auto inPos = m_inPos.load(std::memory_order_acquire);
235+
const unsigned next = (inPos + 1) % m_bufSize;
236+
if (next == m_outPos.load(std::memory_order_relaxed)) {
237+
return false;
238+
}
239+
240+
std::atomic_thread_fence(std::memory_order_acquire);
241+
242+
m_inPos.store(next, std::memory_order_release);
243+
return true;
244+
}
245+
215246
template< typename T >
216247
bool IRAM_ATTR circular_queue<T>::push(T&& val)
217248
{

libraries/FastScheduler/src/circular_queue/circular_queue_mp.h

+9-1
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,14 @@ class circular_queue_mp : protected circular_queue<T>
7171
return circular_queue<T>::capacity(cap);
7272
}
7373

74+
bool IRAM_ATTR push() = delete;
75+
76+
/*!
77+
@brief Move the rvalue parameter into the queue, guarded
78+
for multiple concurrent producers.
79+
@return true if the queue accepted the value, false if the queue
80+
was full.
81+
*/
7482
bool IRAM_ATTR push(T&& val)
7583
{
7684
#ifdef ESP8266
@@ -82,7 +90,7 @@ class circular_queue_mp : protected circular_queue<T>
8290
}
8391

8492
/*!
85-
@brief Move the rvalue parameter into the queue, guarded
93+
@brief Push a copy of the parameter into the queue, guarded
8694
for multiple concurrent producers.
8795
@return true if the queue accepted the value, false if the queue
8896
was full.

0 commit comments

Comments
 (0)