|
Embedded Artistry Framework
Embedded Systems C++ Framework
|
Group of worker threads that enables asynchronous processing. More...
|
Classes | |
| class | embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond > |
| Base class for dispatch queues. More... | |
| class | embutil::InterruptQueue< TLockType, TSize > |
| IRQ safe dispatch queue (For running application-level (bottom-half) interrupt handlers) More... | |
Typedefs | |
| template<typename TFunc = std::function<void()>, typename TLock = std::mutex, typename TCond = std::condition_variable> | |
| using | embutil::DynamicDispatchQueue = DispatchQueue_Base< 0, 0, TFunc, TLock, TCond > |
| Dispatch queue class supporting dynamic sizes and dynamic memory allocation. More... | |
| template<const size_t TSize, const size_t TThreadCount = 1, typename TFunc = stdext::inplace_function<void()>, typename TLock = std::mutex, typename TCond = std::condition_variable> | |
| using | embutil::StaticDispatchQueue = DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond > |
| Dispatch queue specializatoin using only static memory allocation. More... | |
| using | embutil::IRQBottomHalfOp_t = stdext::inplace_function< void(), 96 > |
| using | embutil::IRQDispatcherFunc_t = stdext::inplace_function< void(const IRQBottomHalfOp_t &)> |
Group of worker threads that enables asynchronous processing.
| class embutil::DispatchQueue_Base |
Base class for dispatch queues.
This templated base class supports both static and dynamic dispatch queue implementations.
This class is not intended to be used directly in a dispatch queue declaration. Instead, use one of the specializations:
DynamicDispatchQueueStaticDispatchQueueUsers interact with a dispatch queue using the dispatch() APIs. The dispatch queue can accept any functor: functions, function pointers, lambdas. The client passes a functor to the dispatch() operation, which returns immediately to the client. The functor will be executed asynchronously on the next available dispatch thread.
Dispatch queues are used when an operation needs to run on a separate thread, but you don't want to use explicit thread management. They support asynchronous processing models. A common usage mode is to have the operation call dispatch() to carry out the next step in a processing chain.
Dispatch queues cannot be copied or moved.
| TSize | The size of the storage queue. When TSize is 0, dynamic memory allocation will be used. Otherwise static memory types are used and the maximum number of operations is limited to TSize. |
| TThreadCount | The number of threads to use with the dispatch queue. |
| TFunc | The type representing a dispatch function prototype. Defaults to any functor which can be represented by void(void). |
| TLock | Type to use for the lock. Can be overriden if a custom mutex/lock should be used. |
| TCond | Type to use for the condition variable. Can be overridden if a custom condition variable implementation should be used. |
Public Types | |
| using | DispatchFunc_t = TFunc |
| Public alias for the dispatch functor type. More... | |
Public Member Functions | |
| DispatchQueue_Base (size_t thread_count=1) noexcept | |
| Create an unnamed dispatch queue. More... | |
| DispatchQueue_Base (const char *name, size_t thread_count=1) noexcept | |
| Create a dispatch queue with a C-string name. More... | |
| DispatchQueue_Base (const std::string &name, size_t thread_count=1) noexcept | |
| Create a dispatch queue with a std::string name. More... | |
| DispatchQueue_Base (const std::string_view &name, size_t thread_count=1) noexcept | |
| Create a dispatch queue with a std::string name. More... | |
| ~DispatchQueue_Base () noexcept | |
| Default destructor. More... | |
| DispatchQueue_Base (const DispatchQueue_Base &)=delete | |
| Deleted copy constructor. More... | |
| const DispatchQueue_Base & | operator= (const DispatchQueue_Base &)=delete |
| Deleted copy assignment operator. More... | |
| DispatchQueue_Base (DispatchQueue_Base &&)=delete | |
| Deleted move constructor. More... | |
| DispatchQueue_Base & | operator= (DispatchQueue_Base &&)=delete |
| Deleted move assignment operator. More... | |
| void | dispatch (const TFunc &op) noexcept |
| Dispatch an operation. More... | |
| void | dispatch (TFunc &&op) noexcept |
| auto | getBoundDispatch () noexcept |
| Get a std::bind object for the instance's dispatch(const&) function. More... | |
| auto | getBoundMoveDispatch () noexcept |
| Get a std::bind object for the instance's dispatch(&&) function. More... | |
| size_t | queue_size () const noexcept |
| Get the current size of the operation queue. More... | |
| constexpr size_t | capacity () const noexcept |
| Get the capacity of the operation queue. More... | |
| constexpr size_t | thread_count () const noexcept |
| Get the number of threads used by this dispatch queue. More... | |
Private Types | |
| using | TVecType = typename std::conditional<(TSize==0), std::vector< std::thread >, etl::vector< std::thread, TThreadCount > >::type |
| Type definition for the thread storage vector. More... | |
| using | TQueueType = typename std::conditional<(TSize==0), std::queue< TFunc >, embutil::StaticFunctionQueue< TSize > >::type |
| Type definition for the operation storage queue. More... | |
Private Member Functions | |
| void | dispatch_thread_handler () noexcept |
| Worker thread handler. More... | |
Private Attributes | |
| const std::string_view | name_ |
| Name of the dispatch queue. More... | |
| TLock | lock_ |
| Instance of the lock used to protect the operation queue. More... | |
| TVecType | threads_ |
| Vector of threads which handle dispatch operations. More... | |
| TQueueType | q_ |
| The operation queue instance. More... | |
| TCond | cv_ |
| The condition variable which is used to notify dispatch threads. More... | |
| std::atomic< bool > | quit_ = false |
| Flag used to signal to threads that it is time to shutdown the queue. More... | |
| using embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::DispatchFunc_t = TFunc |
Public alias for the dispatch functor type.
|
private |
Type definition for the operation storage queue.
If TSize is 0, std::queue will be used (dynamic memory mode). Otherwise a StaticFunctionQueue of size TSize is used.
|
private |
Type definition for the thread storage vector.
If TSize is 0, std::vector will be used (dynamic memory mode). Otherwise an etl::vector of size TSize is used.
|
inlineexplicitnoexcept |
Create an unnamed dispatch queue.
Constucts a dispatch queue with a generic name.
| thread_count | Optional parameter that determines the number of threads associated with this queue. thread_count cannot exceed TThreadCount. |
References embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::dispatch_thread_handler(), embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::thread_count(), and embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::threads_.
|
inlineexplicitnoexcept |
Create a dispatch queue with a C-string name.
| thread_count | Optional parameter that determines the number of threads associated with this queue. thread_count cannot exceed TThreadCount. |
| name | The name of the dispatch queue. |
References embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::dispatch_thread_handler(), embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::thread_count(), and embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::threads_.
|
inlineexplicitnoexcept |
Create a dispatch queue with a std::string name.
| name | The name of the dispatch queue. |
| thread_count | Optional parameter that determines the number of threads associated with this queue. thread_count cannot exceed TThreadCount. |
References embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::dispatch_thread_handler(), embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::thread_count(), and embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::threads_.
|
inlineexplicitnoexcept |
Create a dispatch queue with a std::string name.
| name | The name of the dispatch queue. |
| thread_count | Optional parameter that determines the number of threads associated with this queue. thread_count cannot exceed TThreadCount. |
References embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::dispatch_thread_handler(), embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::thread_count(), and embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::threads_.
|
inlinenoexcept |
Default destructor.
The destructor notifies dispatch threads that it is time to quit. We must wait for threads to exit before destroying the class to prevent race conditions and memory faults. Once all threads are joined, the object is destructed.
This function is marked noexcept because we want the program to terminate if an exception results from this call.
References embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::cv_, embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::lock_, embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::quit_, and embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::threads_.
|
delete |
Deleted copy constructor.
|
delete |
Deleted move constructor.
|
inlinenoexcept |
Get the capacity of the operation queue.
References embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::q_.
|
inlinenoexcept |
Dispatch an operation.
This call adds the operation to the function queue and notifies worker threads that new work is available.
The dispatch call returns immediately. Processing happens asynchronously whenever a worker thread is available for processing the operation.
This function is marked noexcept because we want the program to terminate if an exception results from this call. It's possible that the queue might throw on push(), for example.
| op | The operation to dispatch to a worker thread. |
References assert, embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::cv_, embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::lock_, and embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::q_.
Referenced by embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::getBoundDispatch(), and embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::getBoundMoveDispatch().
|
inlinenoexcept |
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
References assert, embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::cv_, embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::lock_, and embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::q_.
|
inlineprivatenoexcept |
Worker thread handler.
Worker threads all utilize the same operational flow:
This function is marked noexcept because we want the program to terminate if an exception results from this call. We can't guarantee that ops or the queue won't have exceptions.
References embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::cv_, embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::lock_, embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::q_, and embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::quit_.
Referenced by embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::DispatchQueue_Base().
|
inlinenoexcept |
Get a std::bind object for the instance's dispatch(const&) function.
If you need to get the dispatch(const&) variant for another class, use this function to avoid making your code messy with an insane std::bind call.
References embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::dispatch().
|
inlinenoexcept |
Get a std::bind object for the instance's dispatch(&&) function.
If you need to get the dispatch(&&) variant for another class, use this function to avoid making your code messy with a stupid std::bind call.
References embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::dispatch().
|
delete |
Deleted copy assignment operator.
|
delete |
Deleted move assignment operator.
|
inlinenoexcept |
Get the current size of the operation queue.
References embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::q_.
|
inlinenoexcept |
Get the number of threads used by this dispatch queue.
References embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::threads_.
Referenced by embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::DispatchQueue_Base().
|
private |
The condition variable which is used to notify dispatch threads.
Referenced by embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::dispatch(), embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::dispatch_thread_handler(), and embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::~DispatchQueue_Base().
|
private |
Instance of the lock used to protect the operation queue.
Referenced by embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::dispatch(), embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::dispatch_thread_handler(), and embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::~DispatchQueue_Base().
|
private |
Name of the dispatch queue.
|
private |
The operation queue instance.
Referenced by embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::capacity(), embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::dispatch(), embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::dispatch_thread_handler(), and embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::queue_size().
|
private |
Flag used to signal to threads that it is time to shutdown the queue.
Referenced by embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::dispatch_thread_handler(), and embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::~DispatchQueue_Base().
|
private |
Vector of threads which handle dispatch operations.
Referenced by embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::DispatchQueue_Base(), embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::thread_count(), and embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::~DispatchQueue_Base().
| class embutil::InterruptQueue |
IRQ safe dispatch queue (For running application-level (bottom-half) interrupt handlers)
This dispatch queue can queue operations from a context which cannot acquire a mutex The function queue is fully serial, so each operation will execute in order.
This queue uses only static memory to avoid the potential for dynamic memory allocations in an IRQ context
This queue represents the bottom-half handler of an IRQ system. To avoid operations impacting the IRQ latency, this queue forwards interrupt operations to a standard dispatch queue for execution.
TDisableOp and TEnableOp are functions which enable/disable interrupts. TDisableOp must be an operation which returns a value that can be passed into TEnableOp. TDisableOp's return is used to restore the proper value once interrupts are re-enabled.
| TLockType | The type of lock to use for protecting the queue. Must meet the requirements of a basic lockable type. |
| TSize | The maximum number of operations to store in the queue. |

Public Member Functions | |
| InterruptQueue () noexcept | |
| ~InterruptQueue () noexcept | |
| Destroy an interupt queue and kill the thread. More... | |
| InterruptQueue (const InterruptQueue &)=delete | |
| Deleted copy constructor. More... | |
| const InterruptQueue & | operator= (const InterruptQueue &)=delete |
| Deleted copy assignment operator. More... | |
| InterruptQueue (InterruptQueue &&)=delete | |
| Deleted move constructor. More... | |
| InterruptQueue & | operator= (InterruptQueue &&)=delete |
| Deleted move assignment operator. More... | |
| void | dispatch (const IRQBottomHalfOp_t &op) noexcept |
| Dispatch an operation to the thread via copy Adds the operation to the queue. More... | |
| void | dispatch (IRQBottomHalfOp_t &&op) noexcept |
| Dispatch an operation to the thread via move Adds the operation to the queue. More... | |
| auto | getBoundDispatch () noexcept |
| size_t | queue_size () const noexcept |
| Return the current number of enqueued operations. More... | |
| constexpr size_t | capacity () const noexcept |
| Return the capacity of the queue. More... | |
| constexpr size_t | thread_count () const noexcept |
| Return the number of threads associated with the interrupt queue (always 1) More... | |
Private Member Functions | |
| bool | wait_and_pop (IRQBottomHalfOp_t &op) noexcept |
| Convenience function which waits for the queue and pops off of it without requiring excessive locks/unlocks. More... | |
| void | dispatch_thread_handler (void) noexcept |
| Thread handler for dispatch queue threads Sleeps until there is an operation in the thread (or quit_ is set) Processes operations from queue. More... | |
Private Attributes | |
| std::thread | thread_ |
| embvm::VirtualEventFlag * | flags_ |
| etl::queue< IRQBottomHalfOp_t, TSize > | q_ |
| TLockType | irq_lock_ |
Static Private Attributes | |
| static constexpr uint32_t | WORK_READY_FLAG = (1 << 0) |
| static constexpr uint32_t | QUIT_FLAG = (1 << 1) |
|
inlineexplicitnoexcept |
|
inlinenoexcept |
Destroy an interupt queue and kill the thread.
This function is marked noexcept because we want the program to terminate if an exception results from this call.
|
delete |
Deleted copy constructor.
|
delete |
Deleted move constructor.
|
inlinenoexcept |
Return the capacity of the queue.
|
inlinenoexcept |
Dispatch an operation to the thread via copy Adds the operation to the queue.
This function is marked noexcept because we want the program to terminate if an exception results from this call. It's possible that pushing to the queue would trigger an exception depending on the underlying type, for example.
Referenced by embutil::InterruptQueue< std::mutex >::getBoundDispatch().
|
inlinenoexcept |
Dispatch an operation to the thread via move Adds the operation to the queue.
This function is marked noexcept because we want the program to terminate if an exception results from this call. It's possible that pushing to the queue would trigger an exception depending on the underlying type, for example.
|
inlineprivatenoexcept |
Thread handler for dispatch queue threads Sleeps until there is an operation in the thread (or quit_ is set) Processes operations from queue.
This function is marked noexcept because we want the program to terminate if an exception results from this call.
Referenced by embutil::InterruptQueue< std::mutex >::InterruptQueue().
|
inlinenoexcept |
Referenced by BlinkySimulatorHWPlatform::init_(), and FWDemoSimulatorHWPlatform::init_().
|
delete |
Deleted copy assignment operator.
|
delete |
Deleted move assignment operator.
|
inlinenoexcept |
Return the current number of enqueued operations.
|
inlinenoexcept |
Return the number of threads associated with the interrupt queue (always 1)
|
inlineprivatenoexcept |
Convenience function which waits for the queue and pops off of it without requiring excessive locks/unlocks.
Using a reference parameter to receive the result is used to transfer ownership out of the queue in order to avoid the exception safety issues of returning data by-value: if the copy constructor of a by-value return throws, then the data has been removed from the queue, but is lost, whereas with this approach, the potentially problematic copy is performed prior to modifying the queue (see Herb Sutter's Guru Of The Week #8 for a discussion of the issues).4
This function is marked noexcept because we want the program to terminate if an exception results from this call.
Referenced by embutil::InterruptQueue< std::mutex >::dispatch_thread_handler().
|
private |
|
private |
|
private |
|
staticprivate |
|
private |
|
staticprivate |
| using embutil::DynamicDispatchQueue = typedef DispatchQueue_Base<0, 0, TFunc, TLock, TCond> |
Dispatch queue class supporting dynamic sizes and dynamic memory allocation.
This dispatch queue contains a dynamicly sized queue and configurable thread count. The function queue is fully serial, so each operation will execute in order.
To use this queue as a serial queue, use a thread count of 1. With multiple threads, operations will be executed as soon as a thread is available.
DynamicDispatchQueue<>.| TFunc | The type representing a dispatch function prototype. Defaults to any functor which can be represented by void(void). |
| TLock | Type to use for the lock. Can be overriden if a custom mutex/lock should be used. |
| TCond | Type to use for the condition variable. Can be overridden if a custom condition variable implementation should be used. |
| using embutil::IRQBottomHalfOp_t = typedef stdext::inplace_function<void(), 96> |
| using embutil::IRQDispatcherFunc_t = typedef stdext::inplace_function<void(const IRQBottomHalfOp_t&)> |
| using embutil::StaticDispatchQueue = typedef DispatchQueue_Base<TSize, TThreadCount, TFunc, TLock, TCond> |
Dispatch queue specializatoin using only static memory allocation.
This dispatch queue type uses a staticly sized queue and configurable thread count. The function queue is fully serial, so each operation will execute in order.
To use this queue as a serial queue, use a thread count of 1. With multiple threads, operations will be executed as soon as a thread is available.
TSize = size of the underlying queue in bytes
| TSize | The size of the storage queue. When TSize is 0, dynamic memory allocation will be used. Otherwise static memory types are used and the maximum number of operations is limited to TSize. |
| TThreadCount | The number of threads to use with the dispatch queue. |
| TFunc | The type representing a dispatch function prototype. Defaults to any functor which can be represented by void(void). |
| TLock | Type to use for the lock. Can be overriden if a custom mutex/lock should be used. |
| TCond | Type to use for the condition variable. Can be overridden if a custom condition variable implementation should be used. |
1.8.15