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