Embedded Template Library 1.0
Loading...
Searching...
No Matches
queue_spsc_locked.h
Go to the documentation of this file.
1
2
3/******************************************************************************
4The MIT License(MIT)
5
6Embedded Template Library.
7https://github.com/ETLCPP/etl
8https://www.etlcpp.com
9
10Copyright(c) 2019 John Wellbelove
11
12Permission is hereby granted, free of charge, to any person obtaining a copy
13of this software and associated documentation files(the "Software"), to deal
14in the Software without restriction, including without limitation the rights
15to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
16copies of the Software, and to permit persons to whom the Software is
17furnished to do so, subject to the following conditions :
18
19The above copyright notice and this permission notice shall be included in all
20copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
25AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28SOFTWARE.
29******************************************************************************/
30
31#ifndef ETL_SPSC_QUEUE_LOCKED_INCLUDED
32#define ETL_SPSC_QUEUE_LOCKED_INCLUDED
33
34#include "platform.h"
35#include "function.h"
36#include "integral_limits.h"
37#include "memory.h"
38#include "memory_model.h"
39#include "mutex.h"
40#include "parameter_type.h"
41#include "placement_new.h"
42#include "utility.h"
43
44#include <stddef.h>
45#include <stdint.h>
46
47namespace etl
48{
49 //***************************************************************************
52 //***************************************************************************
53 class queue_spsc_locked_exception : public exception
54 {
55 public:
56
57 queue_spsc_locked_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
58 : exception(reason_, file_name_, line_number_)
59 {
60 }
61 };
62
63 //***************************************************************************
66 //***************************************************************************
67 class queue_spsc_locked_empty : public queue_spsc_locked_exception
68 {
69 public:
70
71 queue_spsc_locked_empty(string_type file_name_, numeric_type line_number_)
72 : queue_spsc_locked_exception(ETL_ERROR_TEXT("queue_spsc_locked:empty", ETL_QUEUE_SPSC_LOCKED_FILE_ID"A"), file_name_, line_number_)
73 {
74 }
75 };
76
77 template <size_t MEMORY_MODEL = etl::memory_model::MEMORY_MODEL_LARGE>
78 class iqueue_spsc_locked_base
79 {
80 public:
81
84
85 //*************************************************************************
87 //*************************************************************************
92
93 //*************************************************************************
95 //*************************************************************************
96 bool full_from_unlocked() const
97 {
98 return full_implementation();
99 }
100
101 //*************************************************************************
103 //*************************************************************************
105 {
106 return size_implementation();
107 }
108
109 //*************************************************************************
111 //*************************************************************************
113 {
114 return empty_implementation();
115 }
116
117 //*************************************************************************
119 //*************************************************************************
121 {
122 return MAX_SIZE;
123 }
124
125 //*************************************************************************
127 //*************************************************************************
129 {
130 return MAX_SIZE;
131 }
132
133 protected:
134
136 : write_index(0)
137 , read_index(0)
138 , current_size(0)
139 , MAX_SIZE(max_size_)
140 {
141 }
142
143 //*************************************************************************
145 //*************************************************************************
147 {
148 ++index;
149
150 if (index == maximum) ETL_UNLIKELY
151 {
152 index = 0;
153 }
154
155 return index;
156 }
157
162
163 protected:
164
165 //*************************************************************************
167 //*************************************************************************
169 {
170 return MAX_SIZE - current_size;
171 }
172
173 //*************************************************************************
175 //*************************************************************************
177 {
178 return (current_size == MAX_SIZE);
179 }
180
181 //*************************************************************************
183 //*************************************************************************
185 {
186 return current_size;
187 }
188
189 //*************************************************************************
191 //*************************************************************************
193 {
194 return (current_size == 0);
195 }
196
197 //*************************************************************************
199 //*************************************************************************
200#if defined(ETL_POLYMORPHIC_SPSC_QUEUE_ISR) || defined(ETL_POLYMORPHIC_CONTAINERS)
201
202 public:
203
204 virtual ~iqueue_spsc_locked_base() {}
205#else
206
207 protected:
208
210#endif
211 };
212
213 //***************************************************************************
221 //***************************************************************************
222 template <typename T, const size_t MEMORY_MODEL = etl::memory_model::MEMORY_MODEL_LARGE>
223 class iqueue_spsc_locked : public iqueue_spsc_locked_base<MEMORY_MODEL>
224 {
225 private:
226
227 typedef iqueue_spsc_locked_base<MEMORY_MODEL> base_t;
228
229 public:
230
231 typedef T value_type;
232 typedef T& reference;
233 typedef const T& const_reference;
234#if ETL_USING_CPP11
235 typedef T&& rvalue_reference;
236#endif
237 typedef typename base_t::size_type size_type;
238
239 //*************************************************************************
241 //*************************************************************************
243 {
244 return push_implementation(value);
245 }
246
247 //*************************************************************************
249 //*************************************************************************
251 {
252 lock();
253
254 bool result = push_implementation(value);
255
256 unlock();
257
258 return result;
259 }
260
261#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT && !defined(ETL_QUEUE_LOCKED_FORCE_CPP03_IMPLEMENTATION)
262 //*************************************************************************
265 //*************************************************************************
266 bool push_from_unlocked(rvalue_reference value)
267 {
268 return push_implementation(etl::move(value));
269 }
270
271 //*************************************************************************
274 //*************************************************************************
275 bool push(rvalue_reference value)
276 {
277 lock();
278
279 bool result = push_implementation(etl::move(value));
280
281 unlock();
282
283 return result;
284 }
285#endif
286
287#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT && !defined(ETL_QUEUE_LOCKED_FORCE_CPP03_IMPLEMENTATION)
288 //*************************************************************************
291 //*************************************************************************
292 template <typename... Args>
293 bool emplace_from_unlocked(Args&&... args)
294 {
295 return emplace_implementation(etl::forward<Args>(args)...);
296 }
297
298 //*************************************************************************
301 //*************************************************************************
302 template <typename... Args>
303 bool emplace(Args&&... args)
304 {
305 lock();
306
307 bool result = emplace_implementation(etl::forward<Args>(args)...);
308
309 unlock();
310
311 return result;
312 }
313#else
314 //*************************************************************************
318 //*************************************************************************
319 template <typename T1>
320 bool emplace_from_unlocked(const T1& value1)
321 {
322 return emplace_implementation(value1);
323 }
324
325 //*************************************************************************
329 //*************************************************************************
330 template <typename T1, typename T2>
331 bool emplace_from_unlocked(const T1& value1, const T2& value2)
332 {
333 return emplace_implementation(value1, value2);
334 }
335
336 //*************************************************************************
340 //*************************************************************************
341 template <typename T1, typename T2, typename T3>
342 bool emplace_from_unlocked(const T1& value1, const T2& value2, const T3& value3)
343 {
344 return emplace_implementation(value1, value2, value3);
345 }
346
347 //*************************************************************************
351 //*************************************************************************
352 template <typename T1, typename T2, typename T3, typename T4>
353 bool emplace_from_unlocked(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
354 {
355 return emplace_implementation(value1, value2, value3, value4);
356 }
357
358 //*************************************************************************
362 //*************************************************************************
363 bool emplace()
364 {
365 lock();
366
367 bool result = emplace_implementation();
368
369 unlock();
370
371 return result;
372 }
373
374 //*************************************************************************
378 //*************************************************************************
379 template <typename T1>
380 bool emplace(const T1& value1)
381 {
382 lock();
383
384 bool result = emplace_implementation(value1);
385
386 unlock();
387
388 return result;
389 }
390
391 //*************************************************************************
395 //*************************************************************************
396 template <typename T1, typename T2>
397 bool emplace(const T1& value1, const T2& value2)
398 {
399 lock();
400
401 bool result = emplace_implementation(value1, value2);
402
403 unlock();
404
405 return result;
406 }
407
408 //*************************************************************************
412 //*************************************************************************
413 template <typename T1, typename T2, typename T3>
414 bool emplace(const T1& value1, const T2& value2, const T3& value3)
415 {
416 lock();
417
418 bool result = emplace_implementation(value1, value2, value3);
419
420 unlock();
421
422 return result;
423 }
424
425 //*************************************************************************
429 //*************************************************************************
430 template <typename T1, typename T2, typename T3, typename T4>
431 bool emplace(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
432 {
433 lock();
434
435 bool result = emplace_implementation(value1, value2, value3, value4);
436
437 unlock();
438
439 return result;
440 }
441#endif
442
443 //*************************************************************************
446 //*************************************************************************
448 {
449 return pop_implementation(value);
450 }
451
452 //*************************************************************************
454 //*************************************************************************
455 bool pop(reference value)
456 {
457 lock();
458
459 bool result = pop_implementation(value);
460
461 unlock();
462
463 return result;
464 }
465
466 //*************************************************************************
469 //*************************************************************************
471 {
472 return pop_implementation();
473 }
474
475 //*************************************************************************
477 //*************************************************************************
478 bool pop()
479 {
480 lock();
481
482 bool result = pop_implementation();
483
484 unlock();
485
486 return result;
487 }
488
489 //*************************************************************************
492 //*************************************************************************
494 {
495 return front_implementation();
496 }
497
498 //*************************************************************************
501 //*************************************************************************
503 {
504 return front_implementation();
505 }
506
507 //*************************************************************************
511 //*************************************************************************
513 {
514#if ETL_CHECKING_EXTRA
515 lock();
516 if (!this->empty_from_unlocked())
517 {
518 reference inner_result = front_implementation();
519 unlock();
520 return inner_result;
521 }
522 else
523 {
524 unlock();
525 ETL_ASSERT_FAIL(ETL_ERROR(queue_spsc_locked_empty));
526 // fall through to return something to satisfy the compiler, even
527 // though this should never be reached due to undefined behaviour.
528 }
529#endif
530 lock();
531 reference result = front_implementation();
532 unlock();
533 return result;
534 }
535
536 //*************************************************************************
540 //*************************************************************************
542 {
543#if ETL_CHECKING_EXTRA
544 lock();
545 if (!this->empty_from_unlocked())
546 {
547 const_reference inner_result = front_implementation();
548 unlock();
549 return inner_result;
550 }
551 else
552 {
553 unlock();
554 ETL_ASSERT_FAIL(ETL_ERROR(queue_spsc_locked_empty));
555 // fall through to return something to satisfy the compiler, even
556 // though this should never be reached due to undefined behaviour.
557 }
558#endif
559 lock();
560 const_reference result = front_implementation();
561 unlock();
562 return result;
563 }
564
565 //*************************************************************************
567 //*************************************************************************
569 {
570 while (pop_implementation())
571 {
572 // Do nothing.
573 }
574 }
575
576 //*************************************************************************
578 //*************************************************************************
579 void clear()
580 {
581 lock();
582
583 if ETL_IF_CONSTEXPR (etl::is_trivially_destructible<T>::value)
584 {
585 this->write_index = 0;
586 this->read_index = 0;
587 this->current_size = 0;
588 }
589 else
590 {
591 while (pop_implementation())
592 {
593 // Do nothing.
594 }
595 }
596
597 unlock();
598 }
599
600 //*************************************************************************
602 //*************************************************************************
604 {
605 lock();
606
607 size_type result = this->available_implementation();
608
609 unlock();
610
611 return result;
612 }
613
614 //*************************************************************************
616 //*************************************************************************
617 bool full() const
618 {
619 lock();
620
621 size_type result = this->full_implementation();
622
623 unlock();
624
625 return result;
626 }
627
628 //*************************************************************************
630 //*************************************************************************
632 {
633 lock();
634
635 size_type result = this->size_implementation();
636
637 unlock();
638
639 return result;
640 }
641
642 //*************************************************************************
644 //*************************************************************************
645 bool empty() const
646 {
647 lock();
648
649 bool result = this->empty_implementation();
650
651 unlock();
652
653 return result;
654 }
655
656 protected:
657
658 //*************************************************************************
660 //*************************************************************************
661 iqueue_spsc_locked(T* p_buffer_, size_type max_size_, const etl::ifunction<void>& lock_, const etl::ifunction<void>& unlock_)
662 : base_t(max_size_)
663 , p_buffer(p_buffer_)
664 , lock(lock_)
665 , unlock(unlock_)
666 {
667 }
668
669 private:
670
671 //*************************************************************************
673 //*************************************************************************
674 bool push_implementation(const_reference value)
675 {
676 if (this->current_size != this->MAX_SIZE)
677 {
678 ::new (&p_buffer[this->write_index]) T(value);
679
680 this->write_index = this->get_next_index(this->write_index, this->MAX_SIZE);
681
682 ++this->current_size;
683
684 return true;
685 }
686
687 // Queue is full.
688 return false;
689 }
690
691#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT && !defined(ETL_QUEUE_LOCKED_FORCE_CPP03_IMPLEMENTATION)
692 //*************************************************************************
695 //*************************************************************************
696 bool push_implementation(rvalue_reference value)
697 {
698 if (this->current_size != this->MAX_SIZE)
699 {
700 ::new (&p_buffer[this->write_index]) T(etl::move(value));
701
702 this->write_index = this->get_next_index(this->write_index, this->MAX_SIZE);
703
704 ++this->current_size;
705
706 return true;
707 }
708
709 // Queue is full.
710 return false;
711 }
712#endif
713
714#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT && !defined(ETL_QUEUE_LOCKED_FORCE_CPP03_IMPLEMENTATION)
715 //*************************************************************************
718 //*************************************************************************
719 template <typename... Args>
720 bool emplace_implementation(Args&&... args)
721 {
722 if (this->current_size != this->MAX_SIZE)
723 {
724 ::new (&p_buffer[this->write_index]) T(etl::forward<Args>(args)...);
725
726 this->write_index = this->get_next_index(this->write_index, this->MAX_SIZE);
727
728 ++this->current_size;
729
730 return true;
731 }
732
733 // Queue is full.
734 return false;
735 }
736#else
737 //*************************************************************************
739 //*************************************************************************
740 bool emplace_implementation()
741 {
742 if (this->current_size != this->MAX_SIZE)
743 {
744 ::new (&p_buffer[this->write_index]) T();
745
746 this->write_index = this->get_next_index(this->write_index, this->MAX_SIZE);
747
748 ++this->current_size;
749
750 return true;
751 }
752
753 // Queue is full.
754 return false;
755 }
756
757 //*************************************************************************
759 //*************************************************************************
760 template <typename T1>
761 bool emplace_implementation(const T1& value1)
762 {
763 if (this->current_size != this->MAX_SIZE)
764 {
765 ::new (&p_buffer[this->write_index]) T(value1);
766
767 this->write_index = this->get_next_index(this->write_index, this->MAX_SIZE);
768
769 ++this->current_size;
770
771 return true;
772 }
773
774 // Queue is full.
775 return false;
776 }
777
778 //*************************************************************************
780 //*************************************************************************
781 template <typename T1, typename T2>
782 bool emplace_implementation(const T1& value1, const T2& value2)
783 {
784 if (this->current_size != this->MAX_SIZE)
785 {
786 ::new (&p_buffer[this->write_index]) T(value1, value2);
787
788 this->write_index = this->get_next_index(this->write_index, this->MAX_SIZE);
789
790 ++this->current_size;
791
792 return true;
793 }
794
795 // Queue is full.
796 return false;
797 }
798
799 //*************************************************************************
801 //*************************************************************************
802 template <typename T1, typename T2, typename T3>
803 bool emplace_implementation(const T1& value1, const T2& value2, const T3& value3)
804 {
805 if (this->current_size != this->MAX_SIZE)
806 {
807 ::new (&p_buffer[this->write_index]) T(value1, value2, value3);
808
809 this->write_index = this->get_next_index(this->write_index, this->MAX_SIZE);
810
811 ++this->current_size;
812
813 return true;
814 }
815
816 // Queue is full.
817 return false;
818 }
819
820 //*************************************************************************
822 //*************************************************************************
823 template <typename T1, typename T2, typename T3, typename T4>
824 bool emplace_implementation(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
825 {
826 if (this->current_size != this->MAX_SIZE)
827 {
828 ::new (&p_buffer[this->write_index]) T(value1, value2, value3, value4);
829
830 this->write_index = this->get_next_index(this->write_index, this->MAX_SIZE);
831
832 ++this->current_size;
833
834 return true;
835 }
836
837 // Queue is full.
838 return false;
839 }
840#endif
841
842 //*************************************************************************
845 //*************************************************************************
846 bool pop_implementation(reference value)
847 {
848 if (this->current_size == 0)
849 {
850 // Queue is empty
851 return false;
852 }
853
854#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT && !defined(ETL_QUEUE_LOCKABLE_FORCE_CPP03_IMPLEMENTATION)
855 value = etl::move(p_buffer[this->read_index]);
856#else
857 value = p_buffer[this->read_index];
858#endif
859
860 p_buffer[this->read_index].~T();
861
862 this->read_index = this->get_next_index(this->read_index, this->MAX_SIZE);
863
864 --this->current_size;
865
866 return true;
867 }
868
869 //*************************************************************************
872 //*************************************************************************
873 reference front_implementation()
874 {
875 return p_buffer[this->read_index];
876 }
877
878 //*************************************************************************
881 //*************************************************************************
882 const_reference front_implementation() const
883 {
884 return p_buffer[this->read_index];
885 }
886
887 //*************************************************************************
890 //*************************************************************************
891 bool pop_implementation()
892 {
893 if (this->current_size == 0)
894 {
895 // Queue is empty
896 return false;
897 }
898
899 p_buffer[this->read_index].~T();
900
901 this->read_index = this->get_next_index(this->read_index, this->MAX_SIZE);
902
903 --this->current_size;
904
905 return true;
906 }
907
908 // Disable copy construction and assignment.
909 iqueue_spsc_locked(const iqueue_spsc_locked&) ETL_DELETE;
910 iqueue_spsc_locked& operator=(const iqueue_spsc_locked&) ETL_DELETE;
911
912#if ETL_USING_CPP11
914 iqueue_spsc_locked& operator=(iqueue_spsc_locked&&) = delete;
915#endif
916
917 T* p_buffer;
918
919 const etl::ifunction<void>& lock;
920 const etl::ifunction<void>& unlock;
921 };
922
923 //***************************************************************************
932 //***************************************************************************
933 template <typename T, size_t SIZE, const size_t MEMORY_MODEL = etl::memory_model::MEMORY_MODEL_LARGE>
934 class queue_spsc_locked : public etl::iqueue_spsc_locked<T, MEMORY_MODEL>
935 {
936 private:
937
939
940 public:
941
942 typedef typename base_t::size_type size_type;
943
944 ETL_STATIC_ASSERT((SIZE <= etl::integral_limits<size_type>::max), "Size too large for memory model");
945
946 static ETL_CONSTANT size_type MAX_SIZE = size_type(SIZE);
947
948 //*************************************************************************
950 //*************************************************************************
951
953 : base_t(reinterpret_cast<T*>(buffer.raw), MAX_SIZE, lock_, unlock_)
954 {
955 }
956
957 //*************************************************************************
959 //*************************************************************************
961 {
963 }
964
965 private:
966
967 queue_spsc_locked(const queue_spsc_locked&) ETL_DELETE;
968 queue_spsc_locked& operator=(const queue_spsc_locked&) ETL_DELETE;
969
970#if ETL_USING_CPP11
972 queue_spsc_locked& operator=(queue_spsc_locked&&) = delete;
973#endif
974
977 };
978
979 template <typename T, size_t SIZE, const size_t MEMORY_MODEL>
981} // namespace etl
982
983#endif
Definition queue_spsc_locked.h:79
size_type available_from_unlocked() const
How much free space available in the queue.
Definition queue_spsc_locked.h:88
const size_type MAX_SIZE
Definition queue_spsc_locked.h:161
bool empty_implementation() const
Is the queue empty?
Definition queue_spsc_locked.h:192
size_type available_implementation() const
How much free space available in the queue.
Definition queue_spsc_locked.h:168
bool full_from_unlocked() const
Is the queue full?
Definition queue_spsc_locked.h:96
bool empty_from_unlocked() const
Is the queue empty?
Definition queue_spsc_locked.h:112
size_type max_size() const
How many items can the queue hold.
Definition queue_spsc_locked.h:128
size_type size_from_unlocked() const
How many items in the queue?
Definition queue_spsc_locked.h:104
size_type current_size
The current size of the queue.
Definition queue_spsc_locked.h:160
size_type write_index
Where to input new data.
Definition queue_spsc_locked.h:158
bool full_implementation() const
Is the queue full?
Definition queue_spsc_locked.h:176
etl::size_type_lookup< MEMORY_MODEL >::type size_type
The type used for determining the size of queue.
Definition queue_spsc_locked.h:83
size_type capacity() const
How many items can the queue hold.
Definition queue_spsc_locked.h:120
~iqueue_spsc_locked_base()
Destructor.
Definition queue_spsc_locked.h:209
static size_type get_next_index(size_type index, size_type maximum)
Calculate the next index.
Definition queue_spsc_locked.h:146
size_type read_index
Where to get the oldest data.
Definition queue_spsc_locked.h:159
size_type size_implementation() const
How many items in the queue?
Definition queue_spsc_locked.h:184
This is the base for all queue_spsc_locked that contain a particular type.
Definition queue_spsc_locked.h:224
bool emplace(const T1 &value1, const T2 &value2, const T3 &value3, const T4 &value4)
Definition queue_spsc_locked.h:431
bool emplace(const T1 &value1)
Definition queue_spsc_locked.h:380
bool pop_from_unlocked()
Definition queue_spsc_locked.h:470
bool emplace_from_unlocked(const T1 &value1)
Definition queue_spsc_locked.h:320
reference front_from_unlocked()
Definition queue_spsc_locked.h:493
bool emplace(const T1 &value1, const T2 &value2, const T3 &value3)
Definition queue_spsc_locked.h:414
bool emplace(const T1 &value1, const T2 &value2)
Definition queue_spsc_locked.h:397
bool emplace_from_unlocked(const T1 &value1, const T2 &value2)
Definition queue_spsc_locked.h:331
iqueue_spsc_locked(T *p_buffer_, size_type max_size_, const etl::ifunction< void > &lock_, const etl::ifunction< void > &unlock_)
The constructor that is called from derived classes.
Definition queue_spsc_locked.h:661
T & reference
A reference to the type used in the queue.
Definition queue_spsc_locked.h:232
bool pop()
Pop a value from the queue and discard.
Definition queue_spsc_locked.h:478
bool pop(reference value)
Pop a value from the queue.
Definition queue_spsc_locked.h:455
void clear()
Clear the queue.
Definition queue_spsc_locked.h:579
bool emplace_from_unlocked(const T1 &value1, const T2 &value2, const T3 &value3)
Definition queue_spsc_locked.h:342
reference front()
Definition queue_spsc_locked.h:512
T value_type
The type stored in the queue.
Definition queue_spsc_locked.h:231
const T & const_reference
A const reference to the type used in the queue.
Definition queue_spsc_locked.h:233
const_reference front_from_unlocked() const
Definition queue_spsc_locked.h:502
bool empty() const
Is the queue empty?
Definition queue_spsc_locked.h:645
size_type size() const
How many items in the queue?
Definition queue_spsc_locked.h:631
bool push_from_unlocked(const_reference value)
Push a value to the queue.
Definition queue_spsc_locked.h:242
bool emplace()
Definition queue_spsc_locked.h:363
base_t::size_type size_type
The type used for determining the size of the queue.
Definition queue_spsc_locked.h:237
bool emplace_from_unlocked(const T1 &value1, const T2 &value2, const T3 &value3, const T4 &value4)
Definition queue_spsc_locked.h:353
const_reference front() const
Definition queue_spsc_locked.h:541
bool full() const
Is the queue full?
Definition queue_spsc_locked.h:617
void clear_from_unlocked()
Clear the queue from the ISR.
Definition queue_spsc_locked.h:568
bool push(const_reference value)
Push a value to the queue.
Definition queue_spsc_locked.h:250
size_type available() const
How much free space available in the queue.
Definition queue_spsc_locked.h:603
bool pop_from_unlocked(reference value)
Definition queue_spsc_locked.h:447
Definition queue_spsc_locked.h:935
queue_spsc_locked(const etl::ifunction< void > &lock_, const etl::ifunction< void > &unlock_)
Default constructor.
Definition queue_spsc_locked.h:952
~queue_spsc_locked()
Destructor.
Definition queue_spsc_locked.h:960
Definition memory.h:2728
ETL_EXCEPTION_CONSTEXPR exception(string_type reason_, string_type, numeric_type)
Constructor.
Definition exception.h:81
Definition function.h:54
Definition integral_limits.h:518
Definition queue_spsc_locked.h:68
bitset_ext
Definition absolute.h:40
Definition memory_model.h:50