The open source OpenXR runtime
1// Copyright 2022, Collabora, Ltd.
2// SPDX-License-Identifier: BSL-1.0
3/*!
4 * @file
5 * @brief Worker and threading pool.
6 * @author Jakob Bornecrantz <jakob@collabora.com>
7 *
8 * @ingroup aux_util
9 */
10
11#pragma once
12
13#include "xrt/xrt_defines.h"
14
15
16#ifdef __cplusplus
17extern "C" {
18#endif
19
20
21/*
22 *
23 * Worker thread pool.
24 *
25 */
26
27/*!
28 * A worker pool, can shared between multiple groups worker pool.
29 *
30 * @ingroup aux_util
31 */
32struct u_worker_thread_pool
33{
34 struct xrt_reference reference;
35};
36
37/*!
38 * Creates a new thread pool to be used by a worker group.
39 *
40 * @param starting_worker_count How many worker threads can be active at the
41 * same time without any "donated" threads.
42 * @param thread_count The number of threads to be created in total,
43 * this is the maximum threads that can be in
44 * flight at the same time.
45 * @param prefix Prefix to used when naming threads, used for
46 * tracing and debugging.
47 *
48 * @ingroup aux_util
49 */
50struct u_worker_thread_pool *
51u_worker_thread_pool_create(uint32_t starting_worker_count, uint32_t thread_count, const char *prefix);
52
53/*!
54 * Internal function, only called by reference.
55 *
56 * @ingroup aux_util
57 */
58void
59u_worker_thread_pool_destroy(struct u_worker_thread_pool *uwtp);
60
61/*!
62 * Standard Monado reference function.
63 *
64 * @ingroup aux_util
65 */
66static inline void
67u_worker_thread_pool_reference(struct u_worker_thread_pool **dst, struct u_worker_thread_pool *src)
68{
69 struct u_worker_thread_pool *old_dst = *dst;
70
71 if (old_dst == src) {
72 return;
73 }
74
75 if (src) {
76 xrt_reference_inc(&src->reference);
77 }
78
79 *dst = src;
80
81 if (old_dst) {
82 if (xrt_reference_dec_and_is_zero(&old_dst->reference)) {
83 u_worker_thread_pool_destroy(old_dst);
84 }
85 }
86}
87
88
89/*
90 *
91 * Worker group.
92 *
93 */
94
95/*!
96 * A worker group where you submit tasks to. Can share a thread pool with
97 * multiple groups. Also can "donate" a thread to the thread pool by waiting.
98 *
99 * @ingroup aux_util
100 */
101struct u_worker_group
102{
103 struct xrt_reference reference;
104};
105
106/*!
107 * Function typedef for tasks.
108 *
109 * @ingroup aux_util
110 */
111typedef void (*u_worker_group_func_t)(void *);
112
113/*!
114 * Create a new worker group.
115 *
116 * @ingroup aux_util
117 */
118struct u_worker_group *
119u_worker_group_create(struct u_worker_thread_pool *uwtp);
120
121/*!
122 * Push a new task to worker group.
123 *
124 * @ingroup aux_util
125 */
126void
127u_worker_group_push(struct u_worker_group *uwg, u_worker_group_func_t f, void *data);
128
129/*!
130 * Wait for all pushed tasks to be completed, "donates" this thread to the
131 * shared thread pool.
132 *
133 * @ingroup aux_util
134 */
135void
136u_worker_group_wait_all(struct u_worker_group *uwg);
137
138/*!
139 * Destroy a worker pool.
140 *
141 * @ingroup aux_util
142 */
143void
144u_worker_group_destroy(struct u_worker_group *uwg);
145
146/*!
147 * Standard Monado reference function.
148 *
149 * @ingroup aux_util
150 */
151static inline void
152u_worker_group_reference(struct u_worker_group **dst, struct u_worker_group *src)
153{
154 struct u_worker_group *old_dst = *dst;
155
156 if (old_dst == src) {
157 return;
158 }
159
160 if (src) {
161 xrt_reference_inc(&src->reference);
162 }
163
164 *dst = src;
165
166 if (old_dst) {
167 if (xrt_reference_dec_and_is_zero(&old_dst->reference)) {
168 u_worker_group_destroy(old_dst);
169 }
170 }
171}
172
173
174#ifdef __cplusplus
175}
176#endif