pw_work_queue#
The pw_work_queue
module contains utilities for deferring work to be
executed by another thread.
Warning
This module is still under construction, the API is not yet stable.
WorkQueue#
The pw::work_queue::WorkQueue
class enables threads and interrupts to
enqueue work as a pw::work_queue::WorkItem
for execution by the work queue.
The entire API is thread and interrupt safe.
Queue Sizing#
Pigweed AI summary: The number of work requests that can be queued is limited by the internal queue size of the pw::work_queue::WorkQueue. The user must set this size appropriately for the application. The queue size can be set by either specifying the size of the queue_storage buffer in the constructor or by using the pw::work_queue::WorkQueueWithBuffer helper. If the queue is full, it will not accept any further work.
The number of outstanding work requests is limited based on the
pw::work_queue::WorkQueue
’s internal queue size. This must be set
appropriately for the application by the user.
The queue size is set trough either through the size of the queue_storage
buffer passed into the constructor or by using the templated
pw::work_queue::WorkQueueWithBuffer
helper.
Note
While the queue is full, the queue will not accept further work.
Cooperative Thread Cancellation#
Pigweed AI summary: The pw::thread::ThreadCore class is designed to be executed as a single thread and includes a RequestStop() API for cooperative cancellation. This API should be used before joining the thread to ensure a clean shutdown. Once stop has been requested, the queue will no longer accept further work.
The class is a pw::thread::ThreadCore
, meaning it should be executed as a
single thread. In order to facilitate clean shutdown, it provides a
RequestStop()
API for cooperative cancellation which should be invoked
before joining the thread.
Note
Once stop has been requested the queue will no longer accept further work.
C++#
-
class pw::work_queue::WorkQueue#
-
Status PushWork(WorkItem work_item)#
Enqueues a work_item for execution by the work queue thread.
Returns:
Ok - Success, entry was enqueued for execution.
FailedPrecondition - the work queue is shutting down, entries are no longer permitted.
ResourceExhausted - internal work queue is full, entry was not enqueued.
-
void CheckPushWork(WorkItem work_item)#
Queue work for execution. Crash if the work cannot be queued due to a full queue or a stopped worker thread.
This call is recommended where possible since it saves error handling code at the callsite; and in many practical cases, it is a bug if the work queue is full (and so a crash is useful to detect the problem).
Precondition: The queue must not overflow, i.e. be full.
Precondition: The queue must not have been requested to stop, i.e. it must not be in the process of shutting down.
-
void RequestStop()#
Locks the queue to prevent further work enqueing, finishes outstanding work, then shuts down the worker thread.
The WorkQueue cannot be resumed after stopping as the ThreadCore thread returns and may be joined. It must be reconstructed for re-use after the thread has been joined.
-
Status PushWork(WorkItem work_item)#
Example#
Pigweed AI summary: This code snippet includes the use of a work queue and a detached thread in C++. The work queue is used to execute a long running processing task on behalf of an interrupt handler, instead of executing it directly in the interrupt. The work queue is started as a detached thread that runs continuously.
#include "pw_thread/detached_thread.h"
#include "pw_work_queue/work_queue.h"
pw::work_queue::WorkQueueWithBuffer<10> work_queue;
pw::thread::Options& WorkQueueThreadOptions();
void SomeLongRunningProcessing();
void SomeInterruptHandler() {
// Instead of executing the long running processing task in the interrupt,
// the work_queue executes it on the interrupt's behalf.
work_queue.CheckPushWork(SomeLongRunningProcessing);
}
int main() {
// Start up the work_queue as a detached thread which runs forever.
pw::thread::DetachedThread(WorkQueueThreadOptions(), work_queue);
}