ALib C++ Library
Library Version: 2510 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
dedicatedworker.inl
Go to the documentation of this file.
1//==================================================================================================
2/// \file
3/// This header-file is part of module \alib_threadmodel of the \aliblong.
4///
5/// \emoji :copyright: 2013-2025 A-Worx GmbH, Germany.
6/// Published under \ref mainpage_license "Boost Software License".
7//==================================================================================================
8ALIB_EXPORT namespace alib { namespace threadmodel {
9class DWManager;
10
11//==================================================================================================
12/// \attention This class belongs to module \alib_threadmodel, which is not in a stable and
13/// consistent state, yet.
14/// Also this type is considered experimental.
15///
16/// This \alib{singletons;Singleton;singleton-class} manages worker threads of type
17/// \alib{threadmodel;DedicatedWorker}.
18/// Such threads are started by adding them to the singleton instance of this type and are stopped
19/// with removal.
20///
21/// \b %DedicatedWorkers use this type's \b PoolAllocator to create and dispose \alib{threadmodel;Job}
22/// objects and derived types are allowed to allocate resources in its \b %MonoAllocator.
23//==================================================================================================
24class DWManager : public singletons::Singleton<DWManager>
25 , public Lock
26
27{
28 friend class singletons::Singleton<DWManager>;
29
30 protected:
31 /// Mono allocator. Used for commands and by <b>DedicatedWorker</b>s.
33
34 /// Pool allocator. Used for command objects.
36
37 /// The list of workers.
39
40 private:
41 /// Constructor.
43
44 public:
45 /// Allows access to the singleton instances' allocator.
46 /// @return The monotonic allocator.
48
49 /// Allows access to the singleton instances' pool allocator.
50 /// @return The pool allocator.
52
53 /// Adds and starts a worker.
54 /// @param thread The thread to add.
55 ALIB_DLL void Add( DedicatedWorker& thread );
56
57 /// Remove a previously added worker.
58 /// The thread is stopped by invoking \alib{threadmodel;DedicatedWorker::ScheduleStop} using the given
59 /// priority. It is waited until it exits, and finally the thread is joined.<br>
60 /// With debug-compilations, an \alib warning is raised every second if the thread
61 /// does not stop.
62 /// @param thread The thread to remove.
63 /// @param stopPriority The priority passed to <b>DedicatedWorker::ScheduleStop</b>.
64 /// Use \b Lowest (the default) to ensure that all other commands are duly
65 /// executed before exiting.
66 /// @return \c true if the thread was found and removed, \c false otherwise.
67 ALIB_DLL bool Remove( DedicatedWorker& thread,
68 Priority stopPriority= Priority::Lowest );
69
70
71 #if DOXYGEN
72 /// Waits until all threads are idle.
73 /// @param timeout The maximum time to wait.
74 /// @param dbgWarnAfter The time after which a warning message will be printed to the
75 /// debug log if the timeout was reached.<br>
76 /// This parameter is only available in debug-compilations and thus
77 /// should be passed using macro \ref ALIB_DBG.
78 /// @return \c true if all threads are idle, \c false otherwise.
80 bool WaitForAllIdle( Ticks::Duration timeout,
81 Ticks::Duration dbgWarnAfter );
82 #else
83 ALIB_DLL bool WaitForAllIdle( Ticks::Duration timeout
84 ALIB_DBG(, Ticks::Duration dbgWarnAfter) );
85 bool WaitForAllIdle( Ticks::Duration::TDuration timeout
86 ALIB_DBG(, Ticks::Duration::TDuration dbgWarnAfter) )
87 { return WaitForAllIdle( Ticks::Duration(timeout)
88 ALIB_DBG(, Ticks::Duration(dbgWarnAfter) ) ); }
89
90 #endif
91
92
93 /// Stops execution and terminates all workers by invoking
94 /// \alib{threadmodel;DedicatedWorker::ScheduleStop}.<br>
95 /// After this method has been invoked, no further commands should be scheduled, even if
96 /// the given priority equals \b Lowest. This <b>should be assured</b> by the using code.
97 ///
98 /// With debug-compilations, an \alib warning is raised every second until all managed
99 /// threads stopped.
100 /// @param stopPriority The priority passed to <b>DedicatedWorker::ScheduleStop</b>.
101 /// Use \b Lowest (the default) to ensure that all other commands are duly
102 /// executed before exiting.
103 ALIB_DLL void RemoveAll(Priority stopPriority= Priority::Lowest);
104
105}; // class DWManager
106
107//==================================================================================================
108/// \attention
109/// This class is part of \b experimental module \alib_threadmodel and thus is experimental
110/// in respect to interface, functionality, and documentation.
111///
112///
113/// This class implements a worker thread that receives jobs from a private queue.
114/// Jobs can have a different \alib{threadmodel;Priority}, and thus may not be executed in the
115/// order of insertion.
116/// This concept comprises a very simple scheduling approach and should not be overused.
117/// In the end, any multithreading software has to be designed in a way that a job queue never
118/// grows to a high level, so that all jobs will be processed in a maximum time.
119///
120/// This class is virtual, and it is designed for inheritance: Using software has to derive custom
121/// types that provide the custom functionality.
122///
123/// Jobs are represented with the protected type \alib{threadmodel;Job}.
124///
125/// Derived custom types need to duly fulfill a certain contract of interaction.
126/// In short, the following rules are given:
127/// 1. Derived types define jobs by exposing a type derived from virtual class
128/// \alib{threadmodel;Job}.
129/// Preferably, the derived types are designed to be public inner types because they
130/// usually explicitly belong to the scope of an \b %DedicatedWorker.<br>
131/// A \b %Job - besides its inherited type-ID - contains input data to the \b %DedicatedWorker
132/// as well as output data to the requesting thread.
133/// (Both are optional, as can be seen, for example, with the very simple built-in type
134/// \alib{threadmodel::DedicatedWorker;JobTrigger} that has neither input nor output data.)
135/// <br><br>
136/// 2. The derived type exposes interface methods according to the different jobs available
137/// to be scheduled.
138/// Here, the \b %Job is constructed and returned to the caller, usually as a reference
139/// in its derived form.<br>
140/// Thus, the worker has knowledge of what is to be expected when extracting a job from its
141/// queue, and with that is able to safely cast the virtual type "up" to the according
142/// derived type.
143/// <br><br>
144/// 3. The \b %Jobs returned by the interface (usually) contain some sort of thread-safe acknowledge
145/// mechanics, for example, a \alib{threads;Promise} or a \alib{threads;Condition}
146/// that a caller can decide to wait on.
147/// <br><br>
148/// 4. Disposal of \b %Job instances has to be explicitly performed by the thread that schedules
149/// a job. There are two methods provided for doing it.
150/// The first is #DeleteJob, which performs instant deletion. This can be called \b after
151/// the job was processed. The latter has to be awaited, as described in the previous paragraph.
152/// The second is #DeleteJobDeferred, which covers the case that the caller decides not to wait
153/// for an acknowledgment.
154/// Here, the instance must not be deleted because the \b %DedicatedWorker will access it when
155/// it is extracted from the queue (or already is working on it).
156/// Thus, this second version schedules a deletion job and lets the worker do it.<br>
157/// The deletion job has a low priority of
158/// \alib{threadmodel;DedicatedWorker::Priority;DeferredDeletion}. Jobs scheduled with an
159/// even lower priority must not be deferred-deleted.
160/// \note A similar concept of deferred-deletion is provided with sibling type
161/// \alib{threadmodel;ThreadPool}.
162/// There, deferred-deletion has a huge negative impact on performance of the pool.
163/// With type \b %DedicatedWorker, the negative impact of deferred deletion is negligible.
164/// <br><br>
165///
166/// 5. The custom types \b %Job types have to likewise fulfill a few contractual rules.
167/// Those are given with the type's \alib{threadmodel;Job;reference documentation}.
168///
169/// ### Starting and Stopping: ###
170/// The class inherits type \alib{threads;Thread} as a protected base type. With that, the
171/// conventional methods to start and stop a thread are hidden.<br>
172/// Starting and stopping a \b %DedicatedWorker is instead performed by adding, respectively
173/// removing an instance of this type to singleton class \alib{threadmodel;DWManager}.
174///
175/// ### Triggering: ###
176/// This type implements abstract interface \alib{threadmodel;Triggered}.
177/// If this is considered useful by a derived type, then three things have to be performed:
178/// - The parameterless job \alib{threadmodel::DedicatedWorker;JobTrigger} has to be processed
179/// in the overridden method #process.
180/// - Field #triggerDuration has to be adjusted as required, or as an alternative, the method
181/// #triggerPeriod has to be overridden. The latter might allow more flexibility to
182/// adjust the trigger time dependent on certain custom states.
183/// - The instance of the custom \b %DedicatedWorker has to be registered by calling method
184/// \alib{threadmodel;Trigger::Add}.
185//==================================================================================================
187 , protected Triggered
188 , protected TCondition<DedicatedWorker>
189{
190 friend class DWManager;
192
193
194 protected:
195 friend class lang::Owner<DedicatedWorker&>; /// needed as we inherit TCondition
196
197 //==============================================================================================
198 // Fields
199 //==============================================================================================
200
201 /// Reference to \b %DWManager instance.
203
204 /// Statistical information: Point in time of last job execution.
205 /// In case no job was executed, yet, this is the creation time of the object.
207
208 /// Flag which is set when the stop-job was scheduled.
209 bool stopJobPushed = false;
210
211 /// Flag which is set when the stop-job was executed.
212 bool stopJobExecuted = false;
213
214 /// If this \b %DedicatedWorker is (in addition) attached to a \alib{threadmodel;DWManager} as a
215 /// triggered object, this duration is returned by overridden method
216 /// \alib{threadmodel;Triggered::triggerPeriod} to determine the interval between
217 /// scheduling two trigger jobs.<br>
218 /// Defaults to one second, which usually is changed by a derived type.
219 Ticks::Duration triggerDuration = Ticks::Duration::FromSeconds(1);
220
221 //==============================================================================================
222 // The queue
223 //==============================================================================================
224 /// Container element of the queue.
226 {
227 Job* job; ///< The job containing the pool-allocated shared data.
228 Priority priority; ///< The job's priority.
229 bool keepJob; ///< Flag which indicates whether the job should be deleted after
230 ///< execution.
231 };
232
233 /// The queue of jobs.
234 /// This is a simple list, instead of a 'real' priority queue.
235 /// This design decision was taken because there should never be too many jobs queued
236 /// and the naive iteration is more efficient than using a 'real' priority queue type.
238
239 /// The current number of jobs in the queue.
241
242 /// Mandatory method needed and invoked by templated base type \alib{threads;TCondition}.
243 /// @return \c true if field #queue is not empty, \c false otherwise.
244 bool isConditionMet() { return length > 0; }
245
246 /// Pushes the given \p{jobInfo} into the priority queue that this class implements.
247 /// When invoked, the thread-manager as well as this instance are both locked.
248 /// @param jobInfo The job, the priority, and a flag if this job is to be deleted
249 /// automatically.
251 void pushAndRelease(QueueElement&& jobInfo);
252
253 /// Moves the job of highest priority out of the queue.
254 /// Blocks the thread until a job is available.
255 /// @return The job with the highest priority.
256 std::pair<Job*, bool> pop();
257
258 //==============================================================================================
259 // Inner Job types
260 //==============================================================================================
261 /// The stop job sent by method #ScheduleStop.
262 struct JobStop : Job
263 {
264 /// Constructor.
265 JobStop() : Job( typeid(JobStop) ) {}
266 };
267
268 /// The job sent by method #DeleteJobDeferred.
270 {
271 /// The job to be deleted.
273
274 /// Constructor.
275 /// @param job The job that is scheduled to be deleted.
277 : Job( typeid(JobDeleter) )
278 , JobToDelete( job ) {}
279
280 /// Overrides the parent function as necessary.
281 /// @return The sizeof this derived type.
282 virtual size_t SizeOf() override { return sizeof(JobDeleter); }
283 };
284
285 /// The job sent if (optional) trigger-interface \alib{threadmodel;Triggered::trigger}
286 /// is invoked.
288 {
289 /// Constructor.
290 JobTrigger() : Job( typeid(JobTrigger) ) {}
291 };
292
293 /// Pushes a custom job into the priority queue.<br>
294 /// This method is protected because derived types should provide dedicated "speaking"
295 /// interfaces for scheduling jobs.
296 /// Those are typically short inline methods, which/ are optimized out by C++ compilers.
297 /// @tparam TJob The job type as well as the job's shared data type.
298 /// @tparam TArgs Types of the variadic arguments \p{args} that construct \p{TJob}.
299 /// @param priority The priority of the job.
300 /// @param keepJob Denotes whether the job should be deleted after execution or not.
301 /// @param args Variadic arguments forwarded to the constructor of \p{TJob}.
302 /// @return The shared data. Deletion of the object is the responsibility of the caller and
303 /// is to be done by either invoking \alib{threadmodel:DedicatedWorker;DeleteJob}
304 /// or \alib{threadmodel:DedicatedWorker;DeleteJobDeferred}.
305 template<typename TJob, typename... TArgs>
306 [[nodiscard]]
307 TJob& schedule( Priority priority,
308 bool keepJob,
309 TArgs&&... args )
310 {
312 TJob* job= manager.GetPoolAllocator()().New<TJob>( std::forward<TArgs>(args)... );
314 ALIB_ASSERT_ERROR( job->SizeOf()==sizeof(TJob), "MGTHR",
315 "Error in DedicatedWorker::schedule: Job size mismatch. Expected {} "
316 "while virtual method SizeOf returns {}.\n"
317 "Override this method for job-type <{}>",
318 sizeof(TJob), job->SizeOf(), &typeid(*job) )
319
321 || GetState() == State::Running, "MGTHR",
322 "Error in DedicatedWorker::schedule: Job pushed while this thread was not started, yet. "
323 "State: ", GetState() )
324
325 pushAndRelease( {job, priority, keepJob} );
326 return *job;
327 }
328
329 /// Pushes a custom job into the priority queue.<br>
330 /// The job is returned to the caller to be able to await results.
331 /// It is the responsibility of the caller to pass the job to either method
332 /// #DeleteJob or #DeleteJobDeferred for disposal.
333 /// @tparam TJob The job type to create and schedule.
334 /// @tparam TArgs Types of the variadic arguments \p{args} that construct \p{TJob}.
335 /// @param priority The priority of the job.
336 /// @param args Variadic arguments forwarded to the constructor of \p{TJob}.
337 /// @return The scheduled job.
338 template<typename TJob, typename... TArgs>
339 TJob& Schedule( Priority priority, TArgs&&... args )
340 { return schedule<TJob, TArgs...>( priority, true, std::forward<TArgs>(args)... ); }
341
342 /// Pushes a custom job into the priority queue.
343 /// In contrast to the sibling method #Schedule, the job is not returned by this method.
344 /// Instead, it is scheduled for automatic disposal after execution.
345 /// @tparam TJob The job type to create and schedule.
346 /// @tparam TArgs Types of the variadic arguments \p{args} that construct \p{TJob}.
347 /// @param priority The priority of the job.
348 /// @param args Variadic arguments forwarded to the constructor of \p{TJob}.
349 template<typename TJob, typename... TArgs>
350 void ScheduleVoid( Priority priority, TArgs&&... args )
351 { (void) schedule<TJob, TArgs...>( priority, false, std::forward<TArgs>(args)... ); }
352
353
354 //==============================================================================================
355 // Triggered interface implementation
356 //==============================================================================================
357 /// Return the sleep time, between two trigger events.
358 /// Precisely, this method is called after #trigger has been executed and defines the
359 /// next sleep time.
360 /// @return The desired sleep time between two trigger events.
361 virtual Ticks::Duration triggerPeriod() override { return triggerDuration; }
362
363 /// Schedules \alib{threadmodel::DedicatedWorker;JobTrigger} need to implement this function and
364 /// perform their trigger actions here.
365 virtual void trigger() override
366 { (void) schedule<JobTrigger>( Priority::Low, false ); }
367
368 //==============================================================================================
369 // Protected virtual execution methods
370 //==============================================================================================
371 /// This implementation of method \alib{threads;Thread::Run} constitutes a very simple loop
372 /// that waits for jobs in the #queue and passes them to likewise virtual method #process.
373 /// The (only) condition to continuing the loop is that the flag #stopJobExecuted is \c false.
374 /// This flag will be set by the internal job type \alib{threadmodel::DedicatedWorker;JobStop}
375 /// which is pushed with the method #ScheduleStop.
377 virtual void Run() override;
378
379
380 /// This virtual method is called during thread execution (method #Run) for each job
381 /// extracted from the internal job-queue.<br>
382 /// While this default-implementation is empty, internally, before a call to this method,
383 /// the following jobs are already detected and processed:
384 /// - \alib{threadmodel::DedicatedWorker;JobStop}, which signals flag #stopJobExecuted, and
385 /// this way lets calling method #Run leave its loop, and
386 /// - \alib{threadmodel::DedicatedWorker;JobDeleter}, which deletes the given other job.
387 /// (See method #DeleteJobDeferred.)
388 ///
389 /// A derived type may decide to call this parent method before or after checking for its own
390 /// jobs. If the call returns \c true, then the job was processed.
391 ///
392 /// It is also allowed to implement a custom processing, for example, with \b %JobStop and thus
393 /// not to call this version for the internal jobs covered by the custom version.
394 ///
395 /// It is important that overridden versions do return the \c true if the job was processed
396 /// and \c false if not.
397 /// @param vjob The job to process.
398 /// @return \c true if the job was processed, \c false if not.
399 virtual bool process(Job& vjob) { (void)vjob; return false; }
400
401 public:
402 #if ALIB_DEBUG
403 /// The maximum number of jobs in the queue at any time.
404 /// Available only with debug-compilations.
406 #endif
407
408
409 //==============================================================================================
410 // Construction/Destruction
411 //==============================================================================================
412 /// Constructor taking a thread name that is passed to parent class \alib{threads;Thread}.
413 /// @param threadName The name of this thread.
414 DedicatedWorker(const character* threadName)
415 : Thread ( threadName )
416#if ALIB_STRINGS
417 , Triggered ( threadName )
418#endif
419 , TCondition ( ALIB_DBG(threadName) )
420 , manager { DWManager::GetSingleton() }
421 , statLastJobExecution(lang::Initialization::Nulled )
422 , length {0}
424 {}
425
426 /// Destructor.
428 {
429 #if ALIB_STRINGS
430 ALIB_ASSERT_WARNING( Load() == 0, "MGTHR",
431 "DedicatedWorker \"{}\" destructed, while job-queue is not empty.", GetName() )
432 #else
433 ALIB_ASSERT_WARNING( Load() == 0, "MGTHR",
434 "DedicatedWorker destructed, while job-queue is not empty.")
435 #endif
436 }
437
438 using Thread::GetName;
439
440 //==============================================================================================
441 // Load/Stop
442 //==============================================================================================
443 /// Returns the current number of jobs in the queue.
444 /// @return The number of jobs to process, including any currently processed one.
445 int Load() const { return length; }
446
447 /// Returns the state of the internal flag, which is set with the invocation of #ScheduleStop.
448 /// @return \c true, if the #ScheduleStop was called, \c false otherwise.
450
451 /// Returns the state of the internal flag, which is set with the execution of #ScheduleStop.
452 /// @return \c true, if the #ScheduleStop was processed, \c false otherwise.
454
455
456 //==============================================================================================
457 // Job Interface
458 //==============================================================================================
459 /// Schedules a stop job into this thread's job queue.
460 /// When this job is processed from the queue, this thread will exit.
461 /// @param priority The priority of the job. Use \b Lowest if it is assured that no
462 /// other jobs will be pushed.
463 void ScheduleStop(Priority priority)
464 {
465 stopJobPushed= true;
466 (void) schedule<JobStop>( priority, false );
467 }
468
469 /// Deletes a data object previously received via method #schedule, one of its siblings, or
470 /// scheduling methods of derived types.
471 ///
472 /// The latter might have names that do not contain the term "schedule" but still internally
473 /// create and return data objects. Any object returned needs to be deleted.
474 ///
475 /// \attention
476 /// Deletion of data objects must not be done by the caller of a schedule-method before
477 /// the job is processed by this \b %DedicatedWorker.
478 /// For example, if a derived type's interface returns an job instance of type
479 /// \alib{threadmodel;JPromise}, then such a result must only be deleted once the promise is
480 /// fulfilled.
481 /// <p>
482 /// This can be cumbersome in case the calling thread is just not interested in
483 /// the result. For this case, the alternative method # DeleteJobDeferred is given.
484 ///
485 /// @param job The job returned when scheduling a command.
486 void DeleteJob(Job& job)
487 {
489 auto size= job.SizeOf();
490 job.~Job();
491 manager.GetPoolAllocator().free(&job, size);
492 }
493
494 /// Same as #DeleteJob but schedules the deletion to be performed. Scheduling is
495 /// done with \alib{threadmodel;Priority;Priority::DeferredDeletion}.<br>
496 /// This assures that the job deletion is performed \b after the job execution.
497 ///
498 /// This method is useful when the thread that schedules a job with this \b %DedicatedWorker is
499 /// not interested in the result, i.e., does not perform an asynchronous wait.
500 /// Custom jobs where this is rather usually the case, should be exposed in two versions,
501 /// one that returns a result and another that does not.
502 /// With the second, the derived \b %DedicatedWorker would delete the given shared data
503 /// with processing the job.
504 /// If this is offered, then this method does not need to be called (and cannot be called
505 /// because the caller does not receive any data).
506 /// @param job The job object to delete.
508 { (void) schedule<JobDeleter>( Priority::DeferredDeletion, false, &job ); }
509
510}; // class DedicatedWorker
511
512
513} // namespace alib[::threadmodel]
514
515/// Type alias in namespace \b alib.
517
518/// Type alias in namespace \b alib.
520
521} // namespace [alib]
522
523#if ALIB_ENUMRECORDS
525#endif
526
MonoAllocator ma
Mono allocator. Used for commands and by DedicatedWorkers.
ALIB_DLL void RemoveAll(Priority stopPriority=Priority::Lowest)
ALIB_DLL DWManager()
Constructor.
ALIB_DLL void Add(DedicatedWorker &thread)
ALIB_DLL bool Remove(DedicatedWorker &thread, Priority stopPriority=Priority::Lowest)
PoolAllocator pool
Pool allocator. Used for command objects.
List< MonoAllocator, DedicatedWorker * > workers
The list of workers.
ALIB_DLL bool WaitForAllIdle(Ticks::Duration timeout, Ticks::Duration dbgWarnAfter)
virtual ALIB_DLL void Run() override
virtual Ticks::Duration triggerPeriod() override
friend class DWManager
Type alias in namespace alib.
TJob & schedule(Priority priority, bool keepJob, TArgs &&... args)
bool stopJobPushed
Flag which is set when the stop-job was scheduled.
ALIB_DLL void pushAndRelease(QueueElement &&jobInfo)
DWManager & manager
needed as we inherit TCondition
int length
The current number of jobs in the queue.
List< HeapAllocator, QueueElement > queue
void ScheduleVoid(Priority priority, TArgs &&... args)
TJob & Schedule(Priority priority, TArgs &&... args)
bool stopJobExecuted
Flag which is set when the stop-job was executed.
DedicatedWorker(const character *threadName)
virtual const character * GetName() const
Definition thread.inl:241
Triggered(const String &pName)
Definition trigger.inl:44
@ Running
The thread's Run method is currently processed.
Definition thread.inl:141
@ Started
Method Start was invoked but not running, yet.
Definition thread.inl:140
Thread(const character *pName=A_CHAR(""))
Definition thread.inl:181
virtual const character * GetName() const
Definition thread.inl:241
#define ALIB_DLL
Definition alib.inl:496
#define ALIB_ENUMS_ASSIGN_RECORD(TEnum, TRecord)
#define ALIB_ASSERT_WARNING(cond, domain,...)
Definition alib.inl:1050
#define ALIB_EXPORT
Definition alib.inl:488
#define ALIB_DBG(...)
Definition alib.inl:836
#define ALIB_ASSERT_ERROR(cond, domain,...)
Definition alib.inl:1049
#define ALIB_CALLER_PRUNED
Definition alib.inl:1007
#define ALIB_LOCK_WITH(lock)
Definition alib.inl:1322
#define ALIB_STRINGS
Definition alib.inl:239
Priority
Possible priorities of jobs assigned to an DedicatedWorker.
Definition jobs.inl:171
threads::Lock Lock
Type alias in namespace alib.
Definition lock.inl:132
monomem::TPoolAllocator< MonoAllocator > PoolAllocator
monomem::TMonoAllocator< lang::HeapAllocator > MonoAllocator
threads::Thread Thread
Type alias in namespace alib.
Definition thread.inl:389
alib::variables::Priority Priority
Type alias in namespace alib.
threadmodel::DWManager DWManager
Type alias in namespace alib.
time::Ticks Ticks
Type alias in namespace alib.
Definition ticks.inl:109
characters::character character
Type alias in namespace alib.
containers::List< TAllocator, T, TRecycling > List
Type alias in namespace alib.
Definition list.inl:746
threadmodel::DedicatedWorker DedicatedWorker
Type alias in namespace alib.
Job * job
The job containing the pool-allocated shared data.
virtual size_t SizeOf()
Definition jobs.inl:97
Job(const std::type_info &id)
Definition jobs.inl:65
virtual ~Job()=default
Protected destructor.
TCondition(const character *dbgName)