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 maximal number of worker objects allowed inside this pool.
133 * @return Maximal worker capacity, with range [1, 10], 2 by default
134 */
135 inline size_t capacity();
136
137 /**
138 * Returns the number of currently existing worker objects in this pool.
139 * @return Worker count, with range [0, capacity()]
140 */
141 inline size_t size();
142
143 /**
144 * Defines the maximal number of worker objects existing concurrently.
145 * @param workers Maximal number of worker objects to be allowed inside this pool, with range [capacity(), 10]
146 * @return True, if succeeded
147 */
148 bool setCapacity(const size_t workers);
149
150 /**
151 * Returns a scoped object holding the real worker if available.
152 * 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.
153 * @return Object holding the worker if available, otherwise the object will be empty
154 */
156
157 /**
158 * Returns a scoped object holding the real worker if a given condition is 'True' and if a worker is available.
159 * 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>
160 * This function allows to apply something like:
161 * @code
162 * // we invoke the following function in a single-core manner for small images (< 400 * 400 pixels),
163 * // and in a multi-core manner for large images
164 * invokeMulticoreFunction(frame, WorkerPool::get().conditionalScopedWorker(frame.pixels() >= 400u * 400u)());
165 * @endcode
166 * @param condition True, to get a scoped worker with real worker object (if available); False, to get an empty scoped worker
167 * @return Object holding the worker if available, otherwise the object will be empty
168 */
169 inline ScopedWorker conditionalScopedWorker(const bool condition);
170
171 private:
172
173 /**
174 * Creates a new worker pool and initializes the maximal worker capacity to 2.
175 */
176 WorkerPool() = default;
177
178 /**
179 * Destructs a worker pool.
180 */
182
183 /**
184 * Tries to lock a worker to be used for individual worker.
185 * Beware: This worker object must be unlocked after usage.
186 * @return Worker object if available, otherwise nullptr
187 * @see unlock().
188 */
190
191 /**
192 * Unlocks a previously locked worker object to make it available for other users.
193 * Beware: To not use an unlocked worker object anymore.
194 * @param worker The worker to be unlocked
195 */
196 void unlock(Worker* worker);
197
198 private:
199
200 /// Vector holding the currently not-used worker objects.
202
203 /// Vector holding the currently used worker objects.
205
206 /// Maximal pool capacity, with range [1, infinity)
207 size_t capacity_ = 2;
208
209 /// Lock for the entire pool.
211};
212
214{
215 *this = std::move(object);
216}
217
219 worker_(worker)
220{
221 // nothing to do here
222}
223
228
230{
231 return worker_;
232}
233
235{
236 if (worker_ != nullptr)
237 {
238 WorkerPool::get().unlock(worker_);
239 worker_ = nullptr;
240 }
241}
242
244{
245 if (this != &object)
246 {
247 release();
248
249 worker_ = object.worker_;
250 object.worker_ = nullptr;
251 }
252
253 return *this;
254}
255
257{
258 return worker_;
259}
260
261inline WorkerPool::ScopedWorker::operator bool() const
262{
263 return worker_ != nullptr;
264}
265
266inline size_t WorkerPool::capacity()
267{
268 const ScopedLock scopedLock(lock_);
269
270 return capacity_;
271}
272
273inline size_t WorkerPool::size()
274{
275 const ScopedLock scopedLock(lock_);
276
277 return usedWorkers_.size() + freeWorkers_.size();
278}
279
281{
282 if (condition)
283 {
284 return scopedWorker();
285 }
286 else
287 {
288 return ScopedWorker();
289 }
290}
291
292}
293
294#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:135
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
size_t size() const
Returns the size of this vector.
Definition StaticVector.h:340
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:243
ScopedWorker(const ScopedWorker &scopedWorker)=delete
Disabled copy constructor.
Worker * operator()() const
Returns the internal worker object.
Definition WorkerPool.h:256
ScopedWorker & operator=(const ScopedWorker &scopedWorker)=delete
Disabled copy operator.
Worker * worker() const
Returns the internal worker object.
Definition WorkerPool.h:229
~ScopedWorker()
Destructs a scoped worker object and unlocks the internal worker object automatically.
Definition WorkerPool.h:224
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:234
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:201
size_t capacity()
Returns the maximal number of worker objects allowed inside this pool.
Definition WorkerPool.h:266
size_t capacity_
Maximal pool capacity, with range [1, infinity)
Definition WorkerPool.h:207
Lock lock_
Lock for the entire pool.
Definition WorkerPool.h:210
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:273
Workers usedWorkers_
Vector holding the currently used worker objects.
Definition WorkerPool.h:204
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:280
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