Embedded Artistry Framework
Embedded Systems C++ Framework
Classes | Typedefs
Dispatch Queues

Group of worker threads that enables asynchronous processing. More...

Collaboration diagram for Dispatch Queues:

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 &)>
 

Detailed Description

Group of worker threads that enables asynchronous processing.


Class Documentation

◆ embutil::DispatchQueue_Base

class embutil::DispatchQueue_Base

template<const size_t TSize, const size_t TThreadCount, typename TFunc = stdext::inplace_function<void()>, typename TLock = std::mutex, typename TCond = std::condition_variable>
class embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >

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:

  • DynamicDispatchQueue
  • StaticDispatchQueue

Using a Dispatch Queue

Users 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.

static void increment(void)
{
count++;
}
q.dispatch(count);
q.dispatch([] { printf("Hello from a lambda!\n"); });

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.

Template Parameters
TSizeThe 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.
TThreadCountThe number of threads to use with the dispatch queue.
TFuncThe type representing a dispatch function prototype. Defaults to any functor which can be represented by void(void).
TLockType to use for the lock. Can be overriden if a custom mutex/lock should be used.
TCondType 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_Baseoperator= (const DispatchQueue_Base &)=delete
 Deleted copy assignment operator. More...
 
 DispatchQueue_Base (DispatchQueue_Base &&)=delete
 Deleted move constructor. More...
 
DispatchQueue_Baseoperator= (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< boolquit_ = false
 Flag used to signal to threads that it is time to shutdown the queue. More...
 

Member Typedef Documentation

◆ DispatchFunc_t

template<const size_t TSize, const size_t TThreadCount, typename TFunc = stdext::inplace_function<void()>, typename TLock = std::mutex, typename TCond = std::condition_variable>
using embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::DispatchFunc_t = TFunc

Public alias for the dispatch functor type.

◆ TQueueType

template<const size_t TSize, const size_t TThreadCount, typename TFunc = stdext::inplace_function<void()>, typename TLock = std::mutex, typename TCond = std::condition_variable>
using embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::TQueueType = typename std::conditional<(TSize == 0), std::queue<TFunc>, embutil::StaticFunctionQueue<TSize> >::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.

◆ TVecType

template<const size_t TSize, const size_t TThreadCount, typename TFunc = stdext::inplace_function<void()>, typename TLock = std::mutex, typename TCond = std::condition_variable>
using embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::TVecType = typename std::conditional<(TSize == 0), std::vector<std::thread>, etl::vector<std::thread, TThreadCount> >::type
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.

Constructor & Destructor Documentation

◆ DispatchQueue_Base() [1/6]

template<const size_t TSize, const size_t TThreadCount, typename TFunc = stdext::inplace_function<void()>, typename TLock = std::mutex, typename TCond = std::condition_variable>
embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::DispatchQueue_Base ( size_t  thread_count = 1)
inlineexplicitnoexcept

Create an unnamed dispatch queue.

Constucts a dispatch queue with a generic name.

Parameters
thread_countOptional 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_.

◆ DispatchQueue_Base() [2/6]

template<const size_t TSize, const size_t TThreadCount, typename TFunc = stdext::inplace_function<void()>, typename TLock = std::mutex, typename TCond = std::condition_variable>
embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::DispatchQueue_Base ( const char *  name,
size_t  thread_count = 1 
)
inlineexplicitnoexcept

Create a dispatch queue with a C-string name.

Parameters
thread_countOptional parameter that determines the number of threads associated with this queue. thread_count cannot exceed TThreadCount.
nameThe 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_.

◆ DispatchQueue_Base() [3/6]

template<const size_t TSize, const size_t TThreadCount, typename TFunc = stdext::inplace_function<void()>, typename TLock = std::mutex, typename TCond = std::condition_variable>
embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::DispatchQueue_Base ( const std::string &  name,
size_t  thread_count = 1 
)
inlineexplicitnoexcept

Create a dispatch queue with a std::string name.

Parameters
nameThe name of the dispatch queue.
Note
DispatchQueue_Base() uses a std::string_view, so a std::string input must remain valid.
Parameters
thread_countOptional 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_.

◆ DispatchQueue_Base() [4/6]

template<const size_t TSize, const size_t TThreadCount, typename TFunc = stdext::inplace_function<void()>, typename TLock = std::mutex, typename TCond = std::condition_variable>
embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::DispatchQueue_Base ( const std::string_view &  name,
size_t  thread_count = 1 
)
inlineexplicitnoexcept

Create a dispatch queue with a std::string name.

Parameters
nameThe name of the dispatch queue.
Note
DispatchQueue_Base() uses a std::string_view, so the original std::string must remain valid.
Parameters
thread_countOptional 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_.

◆ ~DispatchQueue_Base()

template<const size_t TSize, const size_t TThreadCount, typename TFunc = stdext::inplace_function<void()>, typename TLock = std::mutex, typename TCond = std::condition_variable>
embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::~DispatchQueue_Base ( )
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_.

◆ DispatchQueue_Base() [5/6]

template<const size_t TSize, const size_t TThreadCount, typename TFunc = stdext::inplace_function<void()>, typename TLock = std::mutex, typename TCond = std::condition_variable>
embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::DispatchQueue_Base ( const DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond > &  )
delete

Deleted copy constructor.

◆ DispatchQueue_Base() [6/6]

template<const size_t TSize, const size_t TThreadCount, typename TFunc = stdext::inplace_function<void()>, typename TLock = std::mutex, typename TCond = std::condition_variable>
embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::DispatchQueue_Base ( DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond > &&  )
delete

Deleted move constructor.

Member Function Documentation

◆ capacity()

template<const size_t TSize, const size_t TThreadCount, typename TFunc = stdext::inplace_function<void()>, typename TLock = std::mutex, typename TCond = std::condition_variable>
constexpr size_t embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::capacity ( ) const
inlinenoexcept

Get the capacity of the operation queue.

Returns
the capacity of the queue

References embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::q_.

◆ dispatch() [1/2]

template<const size_t TSize, const size_t TThreadCount, typename TFunc = stdext::inplace_function<void()>, typename TLock = std::mutex, typename TCond = std::condition_variable>
void embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::dispatch ( const TFunc &  op)
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.

Parameters
opThe 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().

◆ dispatch() [2/2]

template<const size_t TSize, const size_t TThreadCount, typename TFunc = stdext::inplace_function<void()>, typename TLock = std::mutex, typename TCond = std::condition_variable>
void embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::dispatch ( TFunc &&  op)
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_.

◆ dispatch_thread_handler()

template<const size_t TSize, const size_t TThreadCount, typename TFunc = stdext::inplace_function<void()>, typename TLock = std::mutex, typename TCond = std::condition_variable>
void embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::dispatch_thread_handler ( )
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.

  • Threads sleep until there is work in the queue (or quit_ is set)
  • Whenever work is available, an operation is popped from the queue and processed locally by the worker thread.
  • When there is no longer any work available, the worker thread sleeps until notified

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().

◆ getBoundDispatch()

template<const size_t TSize, const size_t TThreadCount, typename TFunc = stdext::inplace_function<void()>, typename TLock = std::mutex, typename TCond = std::condition_variable>
auto embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::getBoundDispatch ( )
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.

Returns
std::bind construct which will map to the the dispatch(const&) function for this queue instance.

References embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::dispatch().

◆ getBoundMoveDispatch()

template<const size_t TSize, const size_t TThreadCount, typename TFunc = stdext::inplace_function<void()>, typename TLock = std::mutex, typename TCond = std::condition_variable>
auto embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::getBoundMoveDispatch ( )
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.

Returns
std::bind construct which will map to the the dispatch(&&) function for this queue instance.

References embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::dispatch().

◆ operator=() [1/2]

template<const size_t TSize, const size_t TThreadCount, typename TFunc = stdext::inplace_function<void()>, typename TLock = std::mutex, typename TCond = std::condition_variable>
const DispatchQueue_Base& embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::operator= ( const DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond > &  )
delete

Deleted copy assignment operator.

◆ operator=() [2/2]

template<const size_t TSize, const size_t TThreadCount, typename TFunc = stdext::inplace_function<void()>, typename TLock = std::mutex, typename TCond = std::condition_variable>
DispatchQueue_Base& embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::operator= ( DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond > &&  )
delete

Deleted move assignment operator.

◆ queue_size()

template<const size_t TSize, const size_t TThreadCount, typename TFunc = stdext::inplace_function<void()>, typename TLock = std::mutex, typename TCond = std::condition_variable>
size_t embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::queue_size ( ) const
inlinenoexcept

Get the current size of the operation queue.

Returns
the current number of enqueued operations.

References embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::q_.

◆ thread_count()

template<const size_t TSize, const size_t TThreadCount, typename TFunc = stdext::inplace_function<void()>, typename TLock = std::mutex, typename TCond = std::condition_variable>
constexpr size_t embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::thread_count ( ) const
inlinenoexcept

Get the number of threads used by this dispatch queue.

Returns
the number of threads associated with 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().

Member Data Documentation

◆ cv_

template<const size_t TSize, const size_t TThreadCount, typename TFunc = stdext::inplace_function<void()>, typename TLock = std::mutex, typename TCond = std::condition_variable>
TCond embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::cv_
private

◆ lock_

template<const size_t TSize, const size_t TThreadCount, typename TFunc = stdext::inplace_function<void()>, typename TLock = std::mutex, typename TCond = std::condition_variable>
TLock embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::lock_
private

◆ name_

template<const size_t TSize, const size_t TThreadCount, typename TFunc = stdext::inplace_function<void()>, typename TLock = std::mutex, typename TCond = std::condition_variable>
const std::string_view embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::name_
private

Name of the dispatch queue.

◆ q_

template<const size_t TSize, const size_t TThreadCount, typename TFunc = stdext::inplace_function<void()>, typename TLock = std::mutex, typename TCond = std::condition_variable>
TQueueType embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::q_
private

◆ quit_

template<const size_t TSize, const size_t TThreadCount, typename TFunc = stdext::inplace_function<void()>, typename TLock = std::mutex, typename TCond = std::condition_variable>
std::atomic<bool> embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::quit_ = false
private

◆ threads_

template<const size_t TSize, const size_t TThreadCount, typename TFunc = stdext::inplace_function<void()>, typename TLock = std::mutex, typename TCond = std::condition_variable>
TVecType embutil::DispatchQueue_Base< TSize, TThreadCount, TFunc, TLock, TCond >::threads_
private

◆ embutil::InterruptQueue

class embutil::InterruptQueue

template<typename TLockType, const size_t TSize = 32>
class embutil::InterruptQueue< TLockType, TSize >

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.

Template Parameters
TLockTypeThe type of lock to use for protecting the queue. Must meet the requirements of a basic lockable type.
TSizeThe maximum number of operations to store in the queue.
Inheritance diagram for embutil::InterruptQueue< TLockType, TSize >:
Inheritance graph

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 InterruptQueueoperator= (const InterruptQueue &)=delete
 Deleted copy assignment operator. More...
 
 InterruptQueue (InterruptQueue &&)=delete
 Deleted move constructor. More...
 
InterruptQueueoperator= (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::VirtualEventFlagflags_
 
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)
 

Constructor & Destructor Documentation

◆ InterruptQueue() [1/3]

template<typename TLockType, const size_t TSize = 32>
embutil::InterruptQueue< TLockType, TSize >::InterruptQueue ( )
inlineexplicitnoexcept

◆ ~InterruptQueue()

template<typename TLockType, const size_t TSize = 32>
embutil::InterruptQueue< TLockType, TSize >::~InterruptQueue ( )
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.

◆ InterruptQueue() [2/3]

template<typename TLockType, const size_t TSize = 32>
embutil::InterruptQueue< TLockType, TSize >::InterruptQueue ( const InterruptQueue< TLockType, TSize > &  )
delete

Deleted copy constructor.

◆ InterruptQueue() [3/3]

template<typename TLockType, const size_t TSize = 32>
embutil::InterruptQueue< TLockType, TSize >::InterruptQueue ( InterruptQueue< TLockType, TSize > &&  )
delete

Deleted move constructor.

Member Function Documentation

◆ capacity()

template<typename TLockType, const size_t TSize = 32>
constexpr size_t embutil::InterruptQueue< TLockType, TSize >::capacity ( ) const
inlinenoexcept

Return the capacity of the queue.

◆ dispatch() [1/2]

template<typename TLockType, const size_t TSize = 32>
void embutil::InterruptQueue< TLockType, TSize >::dispatch ( const IRQBottomHalfOp_t op)
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().

◆ dispatch() [2/2]

template<typename TLockType, const size_t TSize = 32>
void embutil::InterruptQueue< TLockType, TSize >::dispatch ( IRQBottomHalfOp_t &&  op)
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.

◆ dispatch_thread_handler()

template<typename TLockType, const size_t TSize = 32>
void embutil::InterruptQueue< TLockType, TSize >::dispatch_thread_handler ( void  )
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().

◆ getBoundDispatch()

template<typename TLockType, const size_t TSize = 32>
auto embutil::InterruptQueue< TLockType, TSize >::getBoundDispatch ( )
inlinenoexcept

◆ operator=() [1/2]

template<typename TLockType, const size_t TSize = 32>
const InterruptQueue& embutil::InterruptQueue< TLockType, TSize >::operator= ( const InterruptQueue< TLockType, TSize > &  )
delete

Deleted copy assignment operator.

◆ operator=() [2/2]

template<typename TLockType, const size_t TSize = 32>
InterruptQueue& embutil::InterruptQueue< TLockType, TSize >::operator= ( InterruptQueue< TLockType, TSize > &&  )
delete

Deleted move assignment operator.

◆ queue_size()

template<typename TLockType, const size_t TSize = 32>
size_t embutil::InterruptQueue< TLockType, TSize >::queue_size ( ) const
inlinenoexcept

Return the current number of enqueued operations.

◆ thread_count()

template<typename TLockType, const size_t TSize = 32>
constexpr size_t embutil::InterruptQueue< TLockType, TSize >::thread_count ( ) const
inlinenoexcept

Return the number of threads associated with the interrupt queue (always 1)

◆ wait_and_pop()

template<typename TLockType, const size_t TSize = 32>
bool embutil::InterruptQueue< TLockType, TSize >::wait_and_pop ( IRQBottomHalfOp_t op)
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.

Returns
false if the thread should exit, true otherwise

Referenced by embutil::InterruptQueue< std::mutex >::dispatch_thread_handler().

Member Data Documentation

◆ flags_

◆ irq_lock_

template<typename TLockType, const size_t TSize = 32>
TLockType embutil::InterruptQueue< TLockType, TSize >::irq_lock_
private

◆ q_

◆ QUIT_FLAG

template<typename TLockType, const size_t TSize = 32>
constexpr uint32_t embutil::InterruptQueue< TLockType, TSize >::QUIT_FLAG = (1 << 1)
staticprivate

◆ thread_

template<typename TLockType, const size_t TSize = 32>
std::thread embutil::InterruptQueue< TLockType, TSize >::thread_
private

◆ WORK_READY_FLAG

template<typename TLockType, const size_t TSize = 32>
constexpr uint32_t embutil::InterruptQueue< TLockType, TSize >::WORK_READY_FLAG = (1 << 0)
staticprivate

Typedef Documentation

◆ DynamicDispatchQueue

template<typename TFunc = std::function<void()>, typename TLock = std::mutex, typename TCond = std::condition_variable>
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.

Note
This queue is only safe to call from contexts which can aquire mutexes.
To instantiate with default TFunc type, use DynamicDispatchQueue<>.
Template Parameters
TFuncThe type representing a dispatch function prototype. Defaults to any functor which can be represented by void(void).
TLockType to use for the lock. Can be overriden if a custom mutex/lock should be used.
TCondType to use for the condition variable. Can be overridden if a custom condition variable implementation should be used.

◆ IRQBottomHalfOp_t

using embutil::IRQBottomHalfOp_t = typedef stdext::inplace_function<void(), 96>

◆ IRQDispatcherFunc_t

using embutil::IRQDispatcherFunc_t = typedef stdext::inplace_function<void(const IRQBottomHalfOp_t&)>

◆ StaticDispatchQueue

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 = 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

Note
This queue is only safe to call from contexts which can aquire mutexes.
Template Parameters
TSizeThe 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.
TThreadCountThe number of threads to use with the dispatch queue.
TFuncThe type representing a dispatch function prototype. Defaults to any functor which can be represented by void(void).
TLockType to use for the lock. Can be overriden if a custom mutex/lock should be used.
TCondType to use for the condition variable. Can be overridden if a custom condition variable implementation should be used.