Ocean
Loading...
Searching...
No Matches
WorkerPool.h
Go to the documentation of this file.
1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8#ifndef META_OCEAN_BASE_WORKER_POOL_H
9#define META_OCEAN_BASE_WORKER_POOL_H
10
11#include "ocean/base/Base.h"
12#include "ocean/base/Lock.h"
15#include "ocean/base/Worker.h"
16
17namespace Ocean
18{
19
20/**
21 * This class implements a pool holding worker objects for individual use.
22 * @see Worker.
23 * @ingroup base
24 */
25class OCEAN_BASE_EXPORT WorkerPool : public Singleton<WorkerPool>
26{
27 friend class Singleton<WorkerPool>;
28 friend class ScopedWorker;
29
30 private:
31
32 /**
33 * Definition of a unique pointer holding a Worker object.
34 */
35 using UniqueWorker = std::unique_ptr<Worker>;
36
37 /**
38 * Definition of a static vector holding worker objects.
39 */
41
42 public:
43
44 /**
45 * Definition of scoped worker object.
46 */
47 class OCEAN_BASE_EXPORT ScopedWorker
48 {
49 public:
50
51 /**
52 * Creates an empty scoped worker object.
53 */
54 ScopedWorker() = default;
55
56 /**
57 * Move constructor.
58 * @param object The object to move
59 */
60 inline ScopedWorker(ScopedWorker&& object) noexcept;
61
62 /**
63 * Creates a new scoped worker object.
64 * @param worker The worker object of this scoped object.
65 */
66 explicit inline ScopedWorker(Worker* worker) noexcept;
67
68 /**
69 * Destructs a scoped worker object and unlocks the internal worker object automatically.
70 */
71 inline ~ScopedWorker();
72
73 /**
74 * Returns the internal worker object.
75 * Beware: Do not store this object outside this scoped object.
76 * The internal object will exist as long this scoped objects exist.
77 * @return Worker object of this scoped object
78 */
79 inline Worker* worker() const;
80
81 /**
82 * Explicitly releases the object and does not wait until the scope ends.
83 * The internal worker object will be returned to the worker pool and cannot be accessed anymore by this object.
84 */
85 inline void release();
86
87 /**
88 * Move a scoped worker object.
89 * @param object The object to move
90 * @return Reference to this object
91 */
92 inline ScopedWorker& operator=(ScopedWorker&& object) noexcept;
93
94 /**
95 * Returns the internal worker object.
96 * Beware: Do not store this object outside this scoped object.
97 * The internal object will exist as long this scoped objects exist.
98 * @return Worker object of this scoped object
99 */
100 inline Worker* operator()() const;
101
102 /**
103 * Returns whether this scoped objects holds an internal worker object.
104 * @return True, if so
105 */
106 explicit inline operator bool() const;
107
108 private:
109
110 /**
111 * Disabled copy constructor.
112 * @param scopedWorker Object which would be copied
113 */
114 ScopedWorker(const ScopedWorker& scopedWorker) = delete;
115
116 /**
117 * Disabled copy operator.
118 * @param scopedWorker Object which would be copied
119 * @return Reference to this object
120 */
121 ScopedWorker& operator=(const ScopedWorker& scopedWorker) = delete;
122
123 private:
124
125 /// Internal worker object.
126 Worker* worker_ = nullptr;
127 };
128
129 public:
130
131 /**
132 * Returns the highest capacity this pool can be configured with.
133 * @return The pool's storage capacity
134 */
135 static constexpr size_t maximalCapacity();
136
137 /**
138 * Returns the maximal number of worker objects allowed inside this pool.
139 * @return Maximal worker capacity, with range [1, maximalCapacity()], 2 by default
140 */
141 inline size_t capacity();
142
143 /**
144 * Returns the number of currently existing worker objects in this pool.
145 * @return Worker count, with range [0, capacity()]
146 */
147 inline size_t size();
148
149 /**
150 * Defines the maximal number of worker objects existing concurrently.
151 * @param workers Maximal number of worker objects to be allowed inside this pool, with range [capacity(), maximalCapacity()]
152 * @return True, if succeeded
153 */
154 bool setCapacity(const size_t workers);
155
156 /**
157 * Returns a scoped object holding the real worker if available.
158 * The scoped object guarantees the existence of the real worker (if available in the moment this function is called) as long as the scoped object exists.
159 * @return Object holding the worker if available, otherwise the object will be empty
160 */
162
163 /**
164 * Returns a scoped object holding the real worker if a given condition is 'True' and if a worker is available.
165 * The scoped object guarantees the existence of the real worker (if provided in the moment this function is called) as long as the scoped object exists.<br>
166 * This function allows to apply something like:
167 * @code
168 * // we invoke the following function in a single-core manner for small images (< 400 * 400 pixels),
169 * // and in a multi-core manner for large images
170 * invokeMulticoreFunction(frame, WorkerPool::get().conditionalScopedWorker(frame.pixels() >= 400u * 400u)());
171 * @endcode
172 * @param condition True, to get a scoped worker with real worker object (if available); False, to get an empty scoped worker
173 * @return Object holding the worker if available, otherwise the object will be empty
174 */
175 inline ScopedWorker conditionalScopedWorker(const bool condition);
176
177 private:
178
179 /**
180 * Creates a new worker pool and initializes the maximal worker capacity to 2.
181 */
182 WorkerPool() = default;
183
184 /**
185 * Destructs a worker pool.
186 */
188
189 /**
190 * Tries to lock a worker to be used for individual worker.
191 * Beware: This worker object must be unlocked after usage.
192 * @return Worker object if available, otherwise nullptr
193 * @see unlock().
194 */
196
197 /**
198 * Unlocks a previously locked worker object to make it available for other users.
199 * Beware: To not use an unlocked worker object anymore.
200 * @param worker The worker to be unlocked
201 */
202 void unlock(Worker* worker);
203
204 private:
205
206 /// Vector holding the currently not-used worker objects.
208
209 /// Vector holding the currently used worker objects.
211
212 /// Maximal pool capacity, with range [1, infinity)
213 size_t capacity_ = 2;
214
215 /// Lock for the entire pool.
217};
218
220{
221 *this = std::move(object);
222}
223
225 worker_(worker)
226{
227 // nothing to do here
228}
229
234
236{
237 return worker_;
238}
239
241{
242 if (worker_ != nullptr)
243 {
244 WorkerPool::get().unlock(worker_);
245 worker_ = nullptr;
246 }
247}
248
250{
251 if (this != &object)
252 {
253 release();
254
255 worker_ = object.worker_;
256 object.worker_ = nullptr;
257 }
258
259 return *this;
260}
261
263{
264 return worker_;
265}
266
267inline WorkerPool::ScopedWorker::operator bool() const
268{
269 return worker_ != nullptr;
270}
271
273{
274 return Workers::capacity();
275}
276
277inline size_t WorkerPool::capacity()
278{
279 const ScopedLock scopedLock(lock_);
280
281 return capacity_;
282}
283
284inline size_t WorkerPool::size()
285{
286 const ScopedLock scopedLock(lock_);
287
288 return usedWorkers_.size() + freeWorkers_.size();
289}
290
292{
293 if (condition)
294 {
295 return scopedWorker();
296 }
297 else
298 {
299 return ScopedWorker();
300 }
301}
302
303}
304
305#endif // META_OCEAN_BASE_WORKER_POOL_H
This class implements a recursive lock object.
Definition Lock.h:31
This class implements a scoped lock object for recursive lock objects.
Definition Lock.h:147
This template class is the base class for all singleton objects.
Definition Singleton.h:71
static WorkerPool & get()
Returns a reference to the unique object.
Definition Singleton.h:115
static constexpr size_t capacity()
Returns the capacity of this buffer.
Definition StaticBuffer.h:232
size_t size() const
Returns the size of this vector.
Definition StaticVector.h:390
This class implements a worker able to distribute function calls over different threads.
Definition Worker.h:33
Definition of scoped worker object.
Definition WorkerPool.h:48
ScopedWorker & operator=(ScopedWorker &&object) noexcept
Move a scoped worker object.
Definition WorkerPool.h:249
ScopedWorker(const ScopedWorker &scopedWorker)=delete
Disabled copy constructor.
Worker * operator()() const
Returns the internal worker object.
Definition WorkerPool.h:262
ScopedWorker & operator=(const ScopedWorker &scopedWorker)=delete
Disabled copy operator.
Worker * worker() const
Returns the internal worker object.
Definition WorkerPool.h:235
~ScopedWorker()
Destructs a scoped worker object and unlocks the internal worker object automatically.
Definition WorkerPool.h:230
ScopedWorker()=default
Creates an empty scoped worker object.
void release()
Explicitly releases the object and does not wait until the scope ends.
Definition WorkerPool.h:240
This class implements a pool holding worker objects for individual use.
Definition WorkerPool.h:26
bool setCapacity(const size_t workers)
Defines the maximal number of worker objects existing concurrently.
Workers freeWorkers_
Vector holding the currently not-used worker objects.
Definition WorkerPool.h:207
size_t capacity()
Returns the maximal number of worker objects allowed inside this pool.
Definition WorkerPool.h:277
static constexpr size_t maximalCapacity()
Returns the highest capacity this pool can be configured with.
Definition WorkerPool.h:272
size_t capacity_
Maximal pool capacity, with range [1, infinity)
Definition WorkerPool.h:213
Lock lock_
Lock for the entire pool.
Definition WorkerPool.h:216
ScopedWorker scopedWorker()
Returns a scoped object holding the real worker if available.
void unlock(Worker *worker)
Unlocks a previously locked worker object to make it available for other users.
~WorkerPool()
Destructs a worker pool.
Worker * lock()
Tries to lock a worker to be used for individual worker.
size_t size()
Returns the number of currently existing worker objects in this pool.
Definition WorkerPool.h:284
Workers usedWorkers_
Vector holding the currently used worker objects.
Definition WorkerPool.h:210
ScopedWorker conditionalScopedWorker(const bool condition)
Returns a scoped object holding the real worker if a given condition is 'True' and if a worker is ava...
Definition WorkerPool.h:291
WorkerPool()=default
Creates a new worker pool and initializes the maximal worker capacity to 2.
std::unique_ptr< Worker > UniqueWorker
Definition of a unique pointer holding a Worker object.
Definition WorkerPool.h:35
The namespace covering the entire Ocean framework.
Definition Accessor.h:15