distortos  v0.4.0
object-oriented C++ RTOS for microcontrollers
MessageQueue.hpp
Go to the documentation of this file.
1 
12 #ifndef INCLUDE_DISTORTOS_MESSAGEQUEUE_HPP_
13 #define INCLUDE_DISTORTOS_MESSAGEQUEUE_HPP_
14 
24 
25 namespace distortos
26 {
27 
30 #define DISTORTOS_MESSAGEQUEUE_EMPLACE_SUPPORTED __GNUC_PREREQ(4, 9)
31 
44 template<typename T>
46 {
47 public:
48 
51 
54 
57 
60  std::unique_ptr<ValueStorage[], internal::MessageQueueBase::ValueStorageUniquePointer::deleter_type>;
61 
72  MessageQueue(EntryStorageUniquePointer&& entryStorageUniquePointer,
73  ValueStorageUniquePointer&& valueStorageUniquePointer, const size_t maxElements) :
74  messageQueueBase_{std::move(entryStorageUniquePointer),
75  {valueStorageUniquePointer.release(), valueStorageUniquePointer.get_deleter()},
76  sizeof(*valueStorageUniquePointer.get()), maxElements}
77  {
78 
79  }
80 
87  ~MessageQueue();
88 
89 #if DISTORTOS_MESSAGEQUEUE_EMPLACE_SUPPORTED == 1
90 
110  template<typename... Args>
111  int emplace(const uint8_t priority, Args&&... args)
112  {
113  const internal::SemaphoreWaitFunctor semaphoreWaitFunctor;
114  return emplaceInternal(semaphoreWaitFunctor, priority, std::forward<Args>(args)...);
115  }
116 
117 #endif // DISTORTOS_MESSAGEQUEUE_EMPLACE_SUPPORTED == 1
118 
135  int pop(uint8_t& priority, T& value)
136  {
137  const internal::SemaphoreWaitFunctor semaphoreWaitFunctor;
138  return popInternal(semaphoreWaitFunctor, priority, value);
139  }
140 
156  int push(const uint8_t priority, const T& value)
157  {
158  const internal::SemaphoreWaitFunctor semaphoreWaitFunctor;
159  return pushInternal(semaphoreWaitFunctor, priority, value);
160  }
161 
178  int push(const uint8_t priority, T&& value)
179  {
180  const internal::SemaphoreWaitFunctor semaphoreWaitFunctor;
181  return pushInternal(semaphoreWaitFunctor, priority, std::move(value));
182  }
183 
184 #if DISTORTOS_MESSAGEQUEUE_EMPLACE_SUPPORTED == 1
185 
203  template<typename... Args>
204  int tryEmplace(const uint8_t priority, Args&&... args)
205  {
206  const internal::SemaphoreTryWaitFunctor semaphoreTryWaitFunctor;
207  return emplaceInternal(semaphoreTryWaitFunctor, priority, std::forward<Args>(args)...);
208  }
209 
230  template<typename... Args>
231  int tryEmplaceFor(const TickClock::duration duration, const uint8_t priority, Args&&... args)
232  {
233  const internal::SemaphoreTryWaitForFunctor semaphoreTryWaitForFunctor {duration};
234  return emplaceInternal(semaphoreTryWaitForFunctor, priority, std::forward<Args>(args)...);
235  }
236 
259  template<typename Rep, typename Period, typename... Args>
260  int tryEmplaceFor(const std::chrono::duration<Rep, Period> duration, const uint8_t priority, Args&&... args)
261  {
262  return tryEmplaceFor(std::chrono::duration_cast<TickClock::duration>(duration), priority,
263  std::forward<Args>(args)...);
264  }
265 
286  template<typename... Args>
287  int tryEmplaceUntil(const TickClock::time_point timePoint, const uint8_t priority, Args&&... args)
288  {
289  const internal::SemaphoreTryWaitUntilFunctor semaphoreTryWaitUntilFunctor {timePoint};
290  return emplaceInternal(semaphoreTryWaitUntilFunctor, priority, std::forward<Args>(args)...);
291  }
292 
314  template<typename Duration, typename... Args>
315  int tryEmplaceUntil(const std::chrono::time_point<TickClock, Duration> timePoint, const uint8_t priority,
316  Args&&... args)
317  {
318  return tryEmplaceUntil(std::chrono::time_point_cast<TickClock::duration>(timePoint), priority,
319  std::forward<Args>(args)...);
320  }
321 
322 #endif // DISTORTOS_MESSAGEQUEUE_EMPLACE_SUPPORTED == 1
323 
338  int tryPop(uint8_t& priority, T& value)
339  {
340  const internal::SemaphoreTryWaitFunctor semaphoreTryWaitFunctor;
341  return popInternal(semaphoreTryWaitFunctor, priority, value);
342  }
343 
361  int tryPopFor(const TickClock::duration duration, uint8_t& priority, T& value)
362  {
363  const internal::SemaphoreTryWaitForFunctor semaphoreTryWaitForFunctor {duration};
364  return popInternal(semaphoreTryWaitForFunctor, priority, value);
365  }
366 
387  template<typename Rep, typename Period>
388  int tryPopFor(const std::chrono::duration<Rep, Period> duration, uint8_t& priority, T& value)
389  {
390  return tryPopFor(std::chrono::duration_cast<TickClock::duration>(duration), priority, value);
391  }
392 
410  int tryPopUntil(const TickClock::time_point timePoint, uint8_t& priority, T& value)
411  {
412  const internal::SemaphoreTryWaitUntilFunctor semaphoreTryWaitUntilFunctor {timePoint};
413  return popInternal(semaphoreTryWaitUntilFunctor, priority, value);
414  }
415 
435  template<typename Duration>
436  int tryPopUntil(const std::chrono::time_point<TickClock, Duration> timePoint, uint8_t& priority, T& value)
437  {
438  return tryPopUntil(std::chrono::time_point_cast<TickClock::duration>(timePoint), priority, value);
439  }
440 
454  int tryPush(const uint8_t priority, const T& value)
455  {
456  const internal::SemaphoreTryWaitFunctor semaphoreTryWaitFunctor;
457  return pushInternal(semaphoreTryWaitFunctor, priority, value);
458  }
459 
474  int tryPush(const uint8_t priority, T&& value)
475  {
476  const internal::SemaphoreTryWaitFunctor semaphoreTryWaitFunctor;
477  return pushInternal(semaphoreTryWaitFunctor, priority, std::move(value));
478  }
479 
496  int tryPushFor(const TickClock::duration duration, const uint8_t priority, const T& value)
497  {
498  const internal::SemaphoreTryWaitForFunctor semaphoreTryWaitForFunctor {duration};
499  return pushInternal(semaphoreTryWaitForFunctor, priority, value);
500  }
501 
521  template<typename Rep, typename Period>
522  int tryPushFor(const std::chrono::duration<Rep, Period> duration, const uint8_t priority, const T& value)
523  {
524  return tryPushFor(std::chrono::duration_cast<TickClock::duration>(duration), priority, value);
525  }
526 
544  int tryPushFor(const TickClock::duration duration, const uint8_t priority, T&& value)
545  {
546  const internal::SemaphoreTryWaitForFunctor semaphoreTryWaitForFunctor {duration};
547  return pushInternal(semaphoreTryWaitForFunctor, priority, std::move(value));
548  }
549 
570  template<typename Rep, typename Period>
571  int tryPushFor(const std::chrono::duration<Rep, Period> duration, const uint8_t priority, T&& value)
572  {
573  return tryPushFor(std::chrono::duration_cast<TickClock::duration>(duration), priority, std::move(value));
574  }
575 
592  int tryPushUntil(const TickClock::time_point timePoint, const uint8_t priority, const T& value)
593  {
594  const internal::SemaphoreTryWaitUntilFunctor semaphoreTryWaitUntilFunctor {timePoint};
595  return pushInternal(semaphoreTryWaitUntilFunctor, priority, value);
596  }
597 
616  template<typename Duration>
617  int tryPushUntil(const std::chrono::time_point<TickClock, Duration> timePoint, const uint8_t priority,
618  const T& value)
619  {
620  return tryPushUntil(std::chrono::time_point_cast<TickClock::duration>(timePoint), priority, value);
621  }
622 
640  int tryPushUntil(const TickClock::time_point timePoint, const uint8_t priority, T&& value)
641  {
642  const internal::SemaphoreTryWaitUntilFunctor semaphoreTryWaitUntilFunctor {timePoint};
643  return pushInternal(semaphoreTryWaitUntilFunctor, priority, std::move(value));
644  }
645 
665  template<typename Duration>
666  int tryPushUntil(const std::chrono::time_point<TickClock, Duration> timePoint, const uint8_t priority, T&& value)
667  {
668  return tryPushUntil(std::chrono::time_point_cast<TickClock::duration>(timePoint), priority, std::move(value));
669  }
670 
671 private:
672 
673 #if DISTORTOS_MESSAGEQUEUE_EMPLACE_SUPPORTED == 1
674 
693  template<typename... Args>
694  int emplaceInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, uint8_t priority, Args&&... args);
695 
696 #endif // DISTORTOS_MESSAGEQUEUE_EMPLACE_SUPPORTED == 1
697 
713  int popInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, uint8_t& priority, T& value);
714 
729  int pushInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, uint8_t priority, const T& value);
730 
746  int pushInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, uint8_t priority, T&& value);
747 
750 };
751 
752 template<typename T>
754 {
755  uint8_t priority;
756  T value;
757  while (tryPop(priority, value) == 0);
758 }
759 
760 #if DISTORTOS_MESSAGEQUEUE_EMPLACE_SUPPORTED == 1
761 
762 template<typename T>
763 template<typename... Args>
764 int MessageQueue<T>::emplaceInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, const uint8_t priority,
765  Args&&... args)
766 {
767  const auto emplaceFunctor = internal::makeBoundQueueFunctor(
768  [&args...](void* const storage)
769  {
770  new (storage) T{std::forward<Args>(args)...};
771  });
772  return messageQueueBase_.push(waitSemaphoreFunctor, priority, emplaceFunctor);
773 }
774 
775 #endif // DISTORTOS_MESSAGEQUEUE_EMPLACE_SUPPORTED == 1
776 
777 template<typename T>
778 int MessageQueue<T>::popInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, uint8_t& priority, T& value)
779 {
780  const internal::SwapPopQueueFunctor<T> swapPopQueueFunctor {value};
781  return messageQueueBase_.pop(waitSemaphoreFunctor, priority, swapPopQueueFunctor);
782 }
783 
784 template<typename T>
785 int MessageQueue<T>::pushInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, const uint8_t priority,
786  const T& value)
787 {
788  const internal::CopyConstructQueueFunctor<T> copyConstructQueueFunctor {value};
789  return messageQueueBase_.push(waitSemaphoreFunctor, priority, copyConstructQueueFunctor);
790 }
791 
792 template<typename T>
793 int MessageQueue<T>::pushInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, const uint8_t priority,
794  T&& value)
795 {
796  const internal::MoveConstructQueueFunctor<T> moveConstructQueueFunctor {std::move(value)};
797  return messageQueueBase_.push(waitSemaphoreFunctor, priority, moveConstructQueueFunctor);
798 }
799 
800 } // namespace distortos
801 
802 #endif // INCLUDE_DISTORTOS_MESSAGEQUEUE_HPP_
int tryPopUntil(const std::chrono::time_point< TickClock, Duration > timePoint, uint8_t &priority, T &value)
Tries to pop oldest element with highest priority from the queue until a given time point...
Definition: MessageQueue.hpp:436
int tryPushFor(const TickClock::duration duration, const uint8_t priority, const T &value)
Tries to push the element to the queue for a given duration of time.
Definition: MessageQueue.hpp:496
constexpr BoundQueueFunctor< F > makeBoundQueueFunctor(F &&boundFunctor)
Helper factory function to make BoundQueueFunctor object with deduced template arguments.
Definition: BoundQueueFunctor.hpp:79
int push(const uint8_t priority, const T &value)
Pushes the element to the queue.
Definition: MessageQueue.hpp:156
int pop(const SemaphoreFunctor &waitSemaphoreFunctor, uint8_t &priority, const QueueFunctor &functor)
Implementation of pop() using type-erased functor.
Definition: MessageQueueBase.cpp:157
int tryPop(uint8_t &priority, T &value)
Tries to pop oldest element with highest priority from the queue.
Definition: MessageQueue.hpp:338
SemaphoreTryWaitFunctor class header.
int tryEmplaceUntil(const std::chrono::time_point< TickClock, Duration > timePoint, const uint8_t priority, Args &&... args)
Tries to emplace the element in the queue until a given time point.
Definition: MessageQueue.hpp:315
int emplaceInternal(const internal::SemaphoreFunctor &waitSemaphoreFunctor, uint8_t priority, Args &&... args)
Emplaces the element in the queue.
Definition: MessageQueue.hpp:764
int tryPopFor(const std::chrono::duration< Rep, Period > duration, uint8_t &priority, T &value)
Tries to pop oldest element with highest priority from the queue for a given duration of time...
Definition: MessageQueue.hpp:388
MessageQueue class is a message queue for thread-thread, thread-interrupt or interrupt-interrupt comm...
Definition: MessageQueue.hpp:45
int tryPopFor(const TickClock::duration duration, uint8_t &priority, T &value)
Tries to pop oldest element with highest priority from the queue for a given duration of time...
Definition: MessageQueue.hpp:361
int tryPush(const uint8_t priority, T &&value)
Tries to push the element to the queue.
Definition: MessageQueue.hpp:474
SemaphoreTryWaitFunctor class is a SemaphoreFunctor which calls Semaphore::tryWait() ...
Definition: SemaphoreTryWaitFunctor.hpp:24
~MessageQueue()
MessageQueue&#39;s destructor.
Definition: MessageQueue.hpp:753
int push(const SemaphoreFunctor &waitSemaphoreFunctor, uint8_t priority, const QueueFunctor &functor)
Implementation of push() using type-erased functor.
Definition: MessageQueueBase.cpp:163
MessageQueueBase class implements basic functionality of MessageQueue template class.
Definition: MessageQueueBase.hpp:31
internal::MessageQueueBase::ValueStorage< OperationCountingType > ValueStorage
type of uninitialized storage for value
Definition: MessageQueue.hpp:53
int push(const uint8_t priority, T &&value)
Pushes the element to the queue.
Definition: MessageQueue.hpp:178
int tryPushUntil(const TickClock::time_point timePoint, const uint8_t priority, T &&value)
Tries to push the element to the queue until a given time point.
Definition: MessageQueue.hpp:640
int emplace(const uint8_t priority, Args &&... args)
Emplaces the element in the queue.
Definition: MessageQueue.hpp:111
std::chrono::time_point< TickClock > time_point
basic time_point type of clock
Definition: TickClock.hpp:42
int tryEmplaceFor(const TickClock::duration duration, const uint8_t priority, Args &&... args)
Tries to emplace the element in the queue for a given duration of time.
Definition: MessageQueue.hpp:231
int tryPushFor(const TickClock::duration duration, const uint8_t priority, T &&value)
Tries to push the element to the queue for a given duration of time.
Definition: MessageQueue.hpp:544
int tryEmplaceFor(const std::chrono::duration< Rep, Period > duration, const uint8_t priority, Args &&... args)
Tries to emplace the element in the queue for a given duration of time.
Definition: MessageQueue.hpp:260
SemaphoreTryWaitUntilFunctor class header.
int tryPushUntil(const TickClock::time_point timePoint, const uint8_t priority, const T &value)
Tries to push the element to the queue until a given time point.
Definition: MessageQueue.hpp:592
Definition: SemaphoreTryWaitUntilFunctor.hpp:27
Definition: SwapPopQueueFunctor.hpp:32
CopyConstructQueueFunctor class header.
int popInternal(const internal::SemaphoreFunctor &waitSemaphoreFunctor, uint8_t &priority, T &value)
Pops oldest element with highest priority from the queue.
Definition: MessageQueue.hpp:778
BoundQueueFunctor class header.
int tryPush(const uint8_t priority, const T &value)
Tries to push the element to the queue.
Definition: MessageQueue.hpp:454
std::unique_ptr< ValueStorage[], internal::MessageQueueBase::ValueStorageUniquePointer::deleter_type > ValueStorageUniquePointer
unique_ptr (with deleter) to ValueStorage[]
Definition: MessageQueue.hpp:60
Top-level namespace of distortos project.
Definition: CopyConstructQueueFunctor.hpp:30
internal::MessageQueueBase messageQueueBase_
contained internal::MessageQueueBase object which implements whole functionality
Definition: MessageQueue.hpp:749
int pop(uint8_t &priority, T &value)
Pops oldest element with highest priority from the queue.
Definition: MessageQueue.hpp:135
internal::MessageQueueBase::EntryStorage EntryStorage
type of uninitialized storage for Entry with link
Definition: MessageQueue.hpp:50
typename std::aligned_storage< sizeof(T), alignof(T)>::type ValueStorage
Definition: MessageQueueBase.hpp:76
MessageQueueBase class header.
int tryPushFor(const std::chrono::duration< Rep, Period > duration, const uint8_t priority, T &&value)
Tries to push the element to the queue for a given duration of time.
Definition: MessageQueue.hpp:571
int tryPushFor(const std::chrono::duration< Rep, Period > duration, const uint8_t priority, const T &value)
Tries to push the element to the queue for a given duration of time.
Definition: MessageQueue.hpp:522
SemaphoreFunctor is a type-erased interface for functors which execute some action on semaphore (wait...
Definition: SemaphoreFunctor.hpp:34
SemaphoreTryWaitForFunctor class header.
std::chrono::duration< rep, period > duration
basic duration type of clock
Definition: TickClock.hpp:39
SwapPopQueueFunctor class header.
int tryEmplaceUntil(const TickClock::time_point timePoint, const uint8_t priority, Args &&... args)
Tries to emplace the element in the queue until a given time point.
Definition: MessageQueue.hpp:287
int tryPushUntil(const std::chrono::time_point< TickClock, Duration > timePoint, const uint8_t priority, T &&value)
Tries to push the element to the queue until a given time point.
Definition: MessageQueue.hpp:666
int tryPushUntil(const std::chrono::time_point< TickClock, Duration > timePoint, const uint8_t priority, const T &value)
Tries to push the element to the queue until a given time point.
Definition: MessageQueue.hpp:617
std::unique_ptr< EntryStorage[], void(&)(EntryStorage *)> EntryStorageUniquePointer
unique_ptr (with deleter) to EntryStorage[]
Definition: MessageQueueBase.hpp:67
int tryPopUntil(const TickClock::time_point timePoint, uint8_t &priority, T &value)
Tries to pop oldest element with highest priority from the queue until a given time point...
Definition: MessageQueue.hpp:410
internal::MessageQueueBase::EntryStorageUniquePointer EntryStorageUniquePointer
import EntryStorageUniquePointer type from internal::MessageQueueBase class
Definition: MessageQueue.hpp:56
SemaphoreWaitFunctor class header.
typename std::aligned_storage< sizeof(Entry), alignof(Entry)>::type EntryStorage
type of uninitialized storage for Entry
Definition: MessageQueueBase.hpp:64
MessageQueue(EntryStorageUniquePointer &&entryStorageUniquePointer, ValueStorageUniquePointer &&valueStorageUniquePointer, const size_t maxElements)
MessageQueue&#39;s constructor.
Definition: MessageQueue.hpp:72
int tryEmplace(const uint8_t priority, Args &&... args)
Tries to emplace the element in the queue.
Definition: MessageQueue.hpp:204
int pushInternal(const internal::SemaphoreFunctor &waitSemaphoreFunctor, uint8_t priority, const T &value)
Pushes the element to the queue.
Definition: MessageQueue.hpp:785
MoveConstructQueueFunctor class header.
SemaphoreTryWaitForFunctor class is a SemaphoreFunctor which calls Semaphore::tryWaitFor() with bound...
Definition: SemaphoreTryWaitForFunctor.hpp:26
SemaphoreWaitFunctor class is a SemaphoreFunctor which calls Semaphore::wait()
Definition: SemaphoreWaitFunctor.hpp:24
Definition: MoveConstructQueueFunctor.hpp:32