Monado OpenXR Runtime
u_worker.hpp
Go to the documentation of this file.
1// Copyright 2022, Collabora, Ltd.
2// Copyright 2024-2025, NVIDIA CORPORATION.
3// SPDX-License-Identifier: BSL-1.0
4/*!
5 * @file
6 * @brief C++ wrappers for workers.
7 * @author Jakob Bornecrantz <jakob@collabora.com>
8 *
9 * @ingroup aux_util
10 */
11
12#pragma once
13
14#include "util/u_worker.h"
15
16#include <vector>
17#include <cassert>
18#include <functional>
19
20
21namespace xrt::auxiliary::util {
22
23class TaskCollection;
24class SharedThreadGroup;
25
26/*!
27 * Wrapper around @ref u_worker_thread_pool.
28 *
29 * @ingroup aux_util
30 */
32{
33private:
34 u_worker_thread_pool *mPool = nullptr;
35
36
37public:
39 {
40 u_worker_thread_pool_reference(&mPool, copy.mPool);
41 }
42
43 /*!
44 * Take a C thread pool as argument in case the pool is shared between
45 * different C++ components over C interfaces, or created externally.
46 */
48 {
50 }
51
52 /*!
53 * @copydoc u_worker_thread_pool_create
54 */
55 SharedThreadPool(uint32_t starting_worker_count, uint32_t thread_count, const char *prefix)
56 {
57 mPool = u_worker_thread_pool_create(starting_worker_count, thread_count, prefix);
58 }
59
61 {
62 u_worker_thread_pool_reference(&mPool, nullptr);
63 }
64
65 SharedThreadPool &
66 operator=(const SharedThreadPool &other)
67 {
68 if (this == &other) {
69 return *this;
70 }
71
72 u_worker_thread_pool_reference(&mPool, other.mPool);
73 return *this;
74 }
75
76 friend SharedThreadGroup;
77
78 // No default constructor.
79 SharedThreadPool() = delete;
80 // No move.
81 SharedThreadPool(SharedThreadPool &&) = delete;
82 // No move assign.
83 SharedThreadPool &
84 operator=(SharedThreadPool &&) = delete;
85};
86
87/*!
88 * Wrapper around @ref u_worker_group, use @ref TaskCollection to dispatch work.
89 *
90 * @ingroup aux_util
91 */
93{
94private:
95 u_worker_group *mGroup = nullptr;
96
97
98public:
100 {
101 mGroup = u_worker_group_create(stp.mPool);
102 }
103
105 {
106 u_worker_group_reference(&mGroup, nullptr);
107 }
108
109 /*!
110 * In-general it's recommended to use the TaskCollection helper,
111 * but some use cases requires direct access to the push function,
112 * so it's provided here.
113 */
114 void
116 {
117 u_worker_group_push(mGroup, f, data);
118 }
119
120 friend TaskCollection;
121
122 // No default constructor.
123 SharedThreadGroup() = delete;
124 // Do not move or copy the shared thread group.
125 SharedThreadGroup(SharedThreadGroup const &) = delete;
128 operator=(SharedThreadGroup const &) = delete;
130 operator=(SharedThreadGroup &&) = delete;
131};
132
133/*!
134 * Class to let users fall into a pit of success by
135 * being designed as a one shot dispatcher instance.
136 *
137 * @ingroup aux_util
138 */
140{
141public:
142 typedef std::function<void()> Functor;
143
144
145private:
146 static constexpr size_t kSize = 16;
147
148 Functor mFunctors[kSize] = {};
149 u_worker_group *mGroup = nullptr;
150
151
152public:
153 /*!
154 * Give all Functors when constructed, some what partially
155 * avoids use after leaving scope issues of function delegates.
156 */
157 TaskCollection(SharedThreadGroup const &stc, std::vector<Functor> const &funcs)
158 {
159 assert(funcs.size() <= kSize);
160
161 u_worker_group_reference(&mGroup, stc.mGroup);
162
163 for (size_t i = 0; i < kSize && i < funcs.size(); i++) {
164 mFunctors[i] = funcs[i];
165 u_worker_group_push(mGroup, &cCallback, &mFunctors[i]);
166 }
167 }
168
170 {
171 // Also unreferences the group.
172 waitAll();
173 }
174
175 /*!
176 * Waits for all given tasks to complete, also frees the group.
177 */
178 void
180 {
181 if (mGroup == nullptr) {
182 return;
183 }
185 u_worker_group_reference(&mGroup, nullptr);
186 }
187
188
189 // Do not move or copy the task collection.
190 TaskCollection(TaskCollection const &) = delete;
191 TaskCollection(TaskCollection &&) = delete;
193 operator=(TaskCollection const &) = delete;
195 operator=(TaskCollection &&) = delete;
196
197
198private:
199 static void
200 cCallback(void *data_ptr);
201};
202
203} // namespace xrt::auxiliary::util
Wrapper around u_worker_group, use TaskCollection to dispatch work.
Definition: u_worker.hpp:93
void push(u_worker_group_func_t f, void *data)
In-general it's recommended to use the TaskCollection helper, but some use cases requires direct acce...
Definition: u_worker.hpp:115
Wrapper around u_worker_thread_pool.
Definition: u_worker.hpp:32
SharedThreadPool(uint32_t starting_worker_count, uint32_t thread_count, const char *prefix)
Creates a new thread pool to be used by a worker group.
Definition: u_worker.hpp:55
SharedThreadPool(u_worker_thread_pool *uwtp)
Take a C thread pool as argument in case the pool is shared between different C++ components over C i...
Definition: u_worker.hpp:47
Class to let users fall into a pit of success by being designed as a one shot dispatcher instance.
Definition: u_worker.hpp:140
void waitAll()
Waits for all given tasks to complete, also frees the group.
Definition: u_worker.hpp:179
TaskCollection(SharedThreadGroup const &stc, std::vector< Functor > const &funcs)
Give all Functors when constructed, some what partially avoids use after leaving scope issues of func...
Definition: u_worker.hpp:157
void(* u_worker_group_func_t)(void *)
Function typedef for tasks.
Definition: u_worker.h:111
void u_worker_group_wait_all(struct u_worker_group *uwg)
Wait for all pushed tasks to be completed, "donates" this thread to the shared thread pool.
Definition: u_worker.c:545
struct u_worker_group * u_worker_group_create(struct u_worker_thread_pool *uwtp)
Create a new worker group.
Definition: u_worker.c:503
static void u_worker_thread_pool_reference(struct u_worker_thread_pool **dst, struct u_worker_thread_pool *src)
Standard Monado reference function.
Definition: u_worker.h:67
static void u_worker_group_reference(struct u_worker_group **dst, struct u_worker_group *src)
Standard Monado reference function.
Definition: u_worker.h:152
struct u_worker_thread_pool * u_worker_thread_pool_create(uint32_t starting_worker_count, uint32_t thread_count, const char *prefix)
Creates a new thread pool to be used by a worker group.
Definition: u_worker.c:419
void u_worker_group_push(struct u_worker_group *uwg, u_worker_group_func_t f, void *data)
Push a new task to worker group.
Definition: u_worker.c:517
A worker group where you submit tasks to.
Definition: u_worker.h:102
A worker pool, can shared between multiple groups worker pool.
Definition: u_worker.h:33
Worker and threading pool.