blob: 7ae6efa5f697feac2e29f3755d8151b5ababd71b [file] [log] [blame]
Ewout van Bekkum04f12922021-08-05 19:34:52 -07001.. _module-pw_work_queue:
2
3=============
4pw_work_queue
5=============
6The ``pw_work_queue`` module contains utilities for deferring work to be
7executed by another thread.
8
9.. Warning::
10 This module is still under construction, the API is not yet stable.
11
12---------
13WorkQueue
14---------
15The ``pw::work_queue::WorkQueue`` class enables threads and interrupts to
16enqueue work as a ``pw::work_queue::WorkItem`` for execution by the work queue.
17
18The entire API is thread and interrupt safe.
19
20Queue Sizing
21============
22The number of outstanding work requests is limited based on the
23``pw::work_queue::WorkQueue``'s internal queue size. This must be set
24appropriately for the application by the user.
25
26The queue size is set trough either through the size of the ``queue_storage``
27buffer passed into the constructor or by using the templated
28``pw::work_queue::WorkQueueWithBuffer`` helper.
29
30.. Note:: While the queue is full, the queue will not accept further work.
31
32Cooperative Thread Cancellation
33===============================
34The class is a ``pw::thread::ThreadCore``, meaning it should be executed as a
35single thread. In order to facilitate clean shutdown, it provides a
36``RequestStop()`` API for cooperative cancellation which should be invoked
37before joining the thread.
38
39.. Note:: Once stop has been requested the queue will no longer accept further
40 work.
41
42C++
43===
44.. cpp:class:: pw::work_queue::WorkQueue
45
46 .. cpp:function:: Status PushWork(WorkItem work_item)
47
48 Enqueues a work_item for execution by the work queue thread.
49
50 Returns:
51
52 * **Ok** - Success, entry was enqueued for execution.
53 * **FailedPrecondition** - the work queue is shutting down, entries are no
54 longer permitted.
55 * **ResourceExhausted** - internal work queue is full, entry was not
56 enqueued.
57
58 .. cpp:function:: void CheckPushWork(WorkItem work_item)
59
60 Queue work for execution. Crash if the work cannot be queued due to a
61 full queue or a stopped worker thread.
62
63 This call is recommended where possible since it saves error handling code
64 at the callsite; and in many practical cases, it is a bug if the work
65 queue is full (and so a crash is useful to detect the problem).
66
67 **Precondition:** The queue must not overflow, i.e. be full.
68
69 **Precondition:** The queue must not have been requested to stop, i.e. it
70 must not be in the process of shutting down.
71
72 .. cpp:function:: void RequestStop()
73
74 Locks the queue to prevent further work enqueing, finishes outstanding
75 work, then shuts down the worker thread.
76
77 The WorkQueue cannot be resumed after stopping as the ThreadCore thread
78 returns and may be joined. It must be reconstructed for re-use after
79 the thread has been joined.
80
81Example
82-------
83
84.. code-block:: cpp
85
86 #include "pw_thread/detached_thread.h"
87 #include "pw_work_queue/work_queue.h"
88
89 pw::work_queue::WorkQueueWithBuffer<10> work_queue;
90
91 pw::thread::Options& WorkQueueThreadOptions();
92 void SomeLongRunningProcessing();
93
94 void SomeInterruptHandler() {
95 // Instead of executing the long running processing task in the interrupt,
96 // the work_queue executes it on the interrupt's behalf.
97 work_queue.CheckPushWork(SomeLongRunningProcessing);
98 }
99
100 int main() {
101 // Start up the work_queue as a detached thread which runs forever.
102 pw::thread::DetachedThread(WorkQueueThreadOptions(), work_queue);
103 }
104