Threading

Detailed Description

Namespaces

 maxon::details
 
 maxon
 

Classes

class  ConditionVariableInterface
 
class  JobInterface
 
class  JobStatusInterface
 
class  JobResultInterface< RESULTVALUETYPE >
 
class  JobResultInterface< Result< RESULTVALUETYPE > >
 
class  JobResultInterface< Result< void > >
 
class  JobResultInterface< void >
 
class  JobResultRef< RESULTVALUETYPE >
 
class  JobInterfaceTemplate< IMPLEMENTATION, RESULTVALUETYPE >
 
class  JobRef
 
class  JobResultRef< Result< RESULTVALUETYPE > >
 
class  JobBarrierInterface
 
class  JobBarrierInterfaceTemplate< IMPLEMENTATION >
 
class  JobBarrierRef
 
class  JobGroupInterface
 
class  JobGroupRef
 
class  StaticJobArray< T >
 
class  StaticJobGroupInterface< T >
 
class  StaticJobGroupRef< T >
 
class  JobQueueInterface
 
class  ServiceIOJobQueueInterface
 
class  SerialJobQueueInterface
 
class  JobQueueRef
 
class  ServiceIOJobQueueRef
 
class  SerialJobQueueRef
 
class  LazyInit
 
class  ParallelFor
 
class  ParallelImage
 
struct  Spinlock
 
struct  RWSpinlock
 
class  ScopedLock
 
class  ScopedLockPair
 
class  ScopedReadLock
 
class  ScopedWriteLock
 
class  ThreadInterface
 
class  ThreadResultRef< RESULTVALUETYPE >
 
class  ThreadInterfaceTemplate< IMPLEMENTATION >
 
class  ThreadRefTemplate< INTERFACE >
 
class  ThreadResultRef< Result< RESULTVALUETYPE > >
 
class  LockedResourceHelper< ENTRY >
 
class  LockedResourceMap< HASHTYPE, ENTRY >
 

Macros

#define DISABLE_IF_LOOP_TYPE_IS_INT(TYPE, ...)
 
#define StackHasEnoughSpace(size)
 
#define StackAlloc(onStack, cnt, TYPE)
 
#define StackFree(ptr, onStack)
 

Typedefs

using ThreadRef = ThreadRefTemplate< ThreadInterface >
 

Enumerations

enum  JOBGROUPFLAGS {
  DEFAULT,
  ENQUEUEING_THREAD_WAITS,
  FINALIZE_ON_WAIT,
  THREAD_AFFINITY
}
 
enum  STATICJOBGROUPFLAGS {
  DEFAULT,
  ENQUEUEING_THREAD_WAITS,
  THREAD_AFFINITY
}
 
enum  STATICJOBARRAYFLAGS {
  DEFAULT,
  INITIALIZE_LATER
}
 
enum  JOBQUEUETYPE {
  MAINTHREAD,
  NONE,
  LOWESTPRIORITY,
  LOWPRIORITY,
  NORMALPRIORITY,
  SERVICEIO,
  THREADLESS
}
 
enum  JOBQUEUEMODE {
  DEFAULT,
  SPIN_ON_IDLE,
  SLEEP_ON_IDLE,
  DETACH_THREADS,
  PSEUDO_THREADS
}
 
enum  PARALLELFORFLAGS {
  INITTHREADED_FINALIZETHREADED,
  INITTHREADED_FINALIZESYNC,
  INITSYNC_FINALIZETHREADED,
  INITSYNC_FINALIZESYNC,
  NOINIT_NOFINALIZE,
  INITTHREADEDWITHSYNC_FINALIZESYNC
}
 

Functions

template<typename FN >
auto ExecuteOnMainThread (FN &&fn, Bool wait=true) -> decltype(fn())
 
JOBOPTIONFLAGS GetJobOptions () const
 
const CharGetName () const
 
 JobInterface (const JobInterfaceJumpTablePOD &jmpTable)
 
 ~JobInterface ()
 
 JobInterface (JobInterface &&src)
 
JobInterfaceoperator= (JobInterface &&src)
 
Bool Wait (TimeValue timeout=TIMEVALUE_INFINITE, WAITMODE mode=WAITMODE::DEFAULT) const
 
Result< void > GetResult (TimeValue timeout=TIMEVALUE_INFINITE, WAITMODE mode=WAITMODE::DEFAULT) const
 
Result< void > MoveResult (TimeValue timeout=TIMEVALUE_INFINITE, WAITMODE mode=WAITMODE::DEFAULT)
 
void Cancel ()
 
Bool IsCancelled () const
 
void CancelAndWait (WAITMODE mode=WAITMODE::DEFAULT)
 
JobInterfaceEnqueue (JobQueueInterface *queue=JOBQUEUE_CURRENT)
 
Result< void > AddSubJob (JobInterface *subJob)
 
template<typename JOB >
Result< void > AddSubJob (ResultMemT< JOB *> subJob)
 
template<typename JOBREF >
Result< void > AddSubJob (ResultMemT< JOBREF > &&subJob)
 
template<typename GROUP >
Result< void > AddSubGroup (GROUP *subGroup)
 
template<typename GROUP >
Result< void > AddSubGroup (ResultMemT< GROUP *> subGroup)
 
template<typename GROUP >
Result< void > AddSubGroup (ResultMemT< GROUP > subGroup)
 
JobGroupInterfaceGetJobGroup () const
 
ObservableFinishedBase< JobInterfaceObservableFinished ()
 
ObservableCancelledBase< JobInterfaceObservableCancelled ()
 
static Int GetCurrentWorkerThreadIndex ()
 
static Int GetCurrentThreadCount ()
 
static Bool IsCurrentJobCancelled (const JobInterface *optionalJob=nullptr)
 
static JobStatusInterfaceGetCurrentJob ()
 
String ToString (const FormatStatement *formatStatement) const
 
 MAXON_DISALLOW_COPY_AND_ASSIGN (JobInterface)
 
template<typename IMPLEMENTATION >
static IMPLEMENTATIONGetWorker (const JobInterface *job)
 
template<typename IMPLEMENTATION >
static void * DestructWorker (const JobInterface *self)
 
template<typename IMPLEMENTATION >
static const ErrorInterfaceRunWorker (const JobInterface *job)
 
template<typename T >
static const JobDependencyGroupInterface * GetWorkerDependencyGroupImpl (const JobInterface *job, std::false_type *)
 
template<typename T >
static const JobDependencyGroupInterface * GetWorkerDependencyGroupImpl (const JobInterface *job, std::true_type *)
 
template<typename IMPLEMENTATION >
static const JobDependencyGroupInterface * GetWorkerDependencyGroup (const JobInterface *job)
 
template<typename IMPLEMENTATION >
static void * GetWorkerOptions (const JobInterface *self, Int selector, void *param)
 
static CoreJobGroup & GetCoreJobGroup (JobGroupInterface *group)
 
Bool IsCancelled () const
 
Result< RESULTVALUETYPE > GetResult (TimeValue timeout=TIMEVALUE_INFINITE, WAITMODE mode=WAITMODE::DEFAULT) const
 
Result< RESULTVALUETYPE > MoveResult (TimeValue timeout=TIMEVALUE_INFINITE, WAITMODE mode=WAITMODE::DEFAULT)
 
ResultOk< void > SetResult (RESULTVALUETYPE &&value)
 
template<typename FN , typename... ARGS>
Result< void > Invoke (FN &&obj, ARGS &&... args)
 
Result< RESULTVALUETYPE > GetResult (TimeValue timeout=TIMEVALUE_INFINITE, WAITMODE mode=WAITMODE::DEFAULT) const
 
Result< RESULTVALUETYPE > MoveResult (TimeValue timeout=TIMEVALUE_INFINITE, WAITMODE mode=WAITMODE::DEFAULT)
 
template<typename R >
Result< void > SetResult (R &&value)
 
template<typename FN , typename... ARGS>
Result< void > Invoke (FN &&obj, ARGS &&... args)
 
template<typename R >
Result< void > SetResult (R &&resultOnly)
 
template<typename FN , typename... ARGS>
Result< void > Invoke (FN &&obj, ARGS &&... args)
 
ResultOk< void > SetResult ()
 
template<typename FN , typename... ARGS>
Result< void > Invoke (FN &&obj, ARGS &&... args)
 
template<typename... ARGS>
static ResultMemT< JobResultRef< RESULTVALUETYPE > > Create (ARGS &&... args)
 
 MAXON_DISALLOW_COPY_AND_ASSIGN (JobInterfaceTemplate)
 
 MAXON_DATATYPE (JobRef, "net.maxon.datatype.job")
 
enum maxon::JOBGROUPFLAGS MAXON_ENUM_FLAGS (JOBGROUPFLAGS)
 
enum maxon::STATICJOBGROUPFLAGS MAXON_ENUM_FLAGS (STATICJOBGROUPFLAGS)
 
enum maxon::STATICJOBARRAYFLAGS MAXON_ENUM_FLAGS (STATICJOBARRAYFLAGS)
 
enum maxon::JOBQUEUETYPE MAXON_ENUM_LIST (JOBQUEUETYPE)
 
enum maxon::JOBQUEUEMODE MAXON_ENUM_LIST (JOBQUEUEMODE)
 
enum maxon::PARALLELFORFLAGS MAXON_ENUM_FLAGS (PARALLELFORFLAGS)
 
template<typename... ARGS>
Result< void > ParallelInvoke (Bool parallel, ARGS &&... args)
 
 MAXON_DATATYPE (ThreadRef, "net.maxon.datatype.threadref")
 

Variables

RESULTVALUETYPE _result
 
Result< RESULTVALUETYPE > _result
 
static const Int JOBQUEUE_USEMAXIMUMTHREADS
 
static const JobQueueInterface::Current JOBQUEUE_CURRENT
 
static const JobQueueInterface::None JOBQUEUE_NONE
 
static const Int PARALLELFOR_DEFAULTGRANULARITY
 
static const Int PARALLELFOR_MINIMUMGRANULARITY
 
static const Int PARALLELFOR_USEMAXIMUMTHREADS
 
static const Int PARALLELFOR_DISABLETHREADING
 
static const Int PARALLELFOR_MAXIMUMDEPTH
 
Bool g_trackSpinlocks
 

Friends

class StrongRefHandler
 
template<typename >
struct ObservableFinishedBase
 
template<typename >
struct ObservableCancelledBase
 
class JobGroupInterface
 
template<typename >
class StaticJobGroupInterface
 
class TimerInterface
 
template<typename FN >
auto ExecuteOnMainThread (FN &&fn, Bool wait) -> decltype(fn())
 

Macro Definition Documentation

◆ DISABLE_IF_LOOP_TYPE_IS_INT

#define DISABLE_IF_LOOP_TYPE_IS_INT (   TYPE,
  ... 
)

◆ StackHasEnoughSpace

#define StackHasEnoughSpace (   size)

◆ StackAlloc

#define StackAlloc (   onStack,
  cnt,
  TYPE 
)

◆ StackFree

#define StackFree (   ptr,
  onStack 
)

Typedef Documentation

◆ ThreadRef

Reference to a thread (ThreadInterface).

Enumeration Type Documentation

◆ JOBGROUPFLAGS

enum JOBGROUPFLAGS
strong

Flags for enqueue options of a JobGroup.

Enumerator
DEFAULT 

Default case.

ENQUEUEING_THREAD_WAITS 

The enqueuing thread waits until the group has finished and might be used to execute jobs.

FINALIZE_ON_WAIT 

After Enqueue() further Add()s can be made which start the jobs ASAP. A following call to Wait() or GetResult() finalizes the group (no more jobs can be added). Can be useful if there is a lot of setup work before a job can be added.

THREAD_AFFINITY 

On Enqueue() each jobs is permanently assigned to a worker thread. This blocks load balancing and therefore slower and only useful for special cases.

◆ STATICJOBGROUPFLAGS

enum STATICJOBGROUPFLAGS
strong

Flags describing the ownership of a StaticJobGroup. You don't have to bother using anything other than DEFAULT.

Enumerator
DEFAULT 

Safe default case.

ENQUEUEING_THREAD_WAITS 

The enqueuing thread waits until the group has finished and might be used to execute jobs.

THREAD_AFFINITY 

On Enqueue() each jobs is permanently assigned to a worker thread. This blocks load balancing and therefore slower and only useful for special cases.

◆ STATICJOBARRAYFLAGS

enum STATICJOBARRAYFLAGS
strong

Initialization options for the StaticJobArray.

Enumerator
DEFAULT 

Default behaviour: Array is empty.

INITIALIZE_LATER 

Array consists of as many uninitialized elements as it has capacity. The caller will construct them later on (before it is added to the group).

◆ JOBQUEUETYPE

enum JOBQUEUETYPE
strong

Type of job queue.

Enumerator
MAINTHREAD 

Jobs are executed on the main thread whenever the event loop can spare some time: there is only one queue of this type: use GetMainThreadQueue() to access it.

NONE 

Jobs are not enqueued but executed in the current context.

LOWESTPRIORITY 

Use lowest priority threads (worker threads have lowest priority and will not idle when waiting for new jobs or waiting for a group to finish).

LOWPRIORITY 

Use low priority threads.

NORMALPRIORITY 

Use normal priority threads (You should rarely have to create a queue with normal priority. Most of the time low priority is sufficient: This makes sure that you don't interfere with really important tasks and if available you still get all cpu power).

SERVICEIO 

Queue is used for IO and priority is adapted accordingly. Spinning on idle is not allowed.

THREADLESS 

◆ JOBQUEUEMODE

enum JOBQUEUEMODE
strong

Options for the job queue.

Enumerator
DEFAULT 

Use default settings for the queue.

SPIN_ON_IDLE 

When there are no jobs threads will be spinning for a short moment before they go to sleep (low latency and highest performance but might unnecessary steals cycles from other threads).

SLEEP_ON_IDLE 

When there are no jobs threads will immediately go to sleep (results in higher latency).

DETACH_THREADS 

When there are no jobs the threads will immediately go to sleep and make themselves available to other queues (results in higher latency but less memory/resource usage).

PSEUDO_THREADS 

The workers behave like ordinary threads (JOBQUEUE_CURRENT points to the default queue and the threads don't have a worker thread index).

◆ PARALLELFORFLAGS

enum PARALLELFORFLAGS
strong

Flags controlling the threading of the init and finalize section of ParallelFor. The default case is INITTHREADED_FINALIZESYNC. Each worker thread will independently call the init section for its part of the loop and then execute the loop body. The init section of a thread might be executed after any another thread has almost executed the whole loop - there's no guarantee that all init sections have finished before the loop body is entered, you might even have worker threads that don't run the init, loop and finalize section because another thread has already done the whole work. After the loop has finished for each init section the corresponding finalize will be called synchronously one after another. There might be cases where you must make sure that the init section for all worker threads has finished before the loop is executed, for example because you also must initialize some global variables for each worker thread that will be utilized by nested ParallelFors or other sub-jobs. Depending on your needs you might specify INITSYNC_FINALIZETHREADED, INITSYNC_FINALIZESYNC or INITTHREADEDWITHSYNC_FINALIZESYNC. Please note that INITTHREADEDWITHSYNC_FINALIZESYNC is slower than INITTHREADED_FINALIZESYNC because of the additional synchronization after the init phase.

Enumerator
INITTHREADED_FINALIZETHREADED 

Init() and Finalize() calls are threaded.

INITTHREADED_FINALIZESYNC 

Init() is called threaded, Finalize() is called synchronously (default case).

INITSYNC_FINALIZETHREADED 

Init() is called synchronously, Finalize() is called threaded.

INITSYNC_FINALIZESYNC 

Init() and Finalize() are called synchronously.

NOINIT_NOFINALIZE 

no call to Init() or Finalize().

INITTHREADEDWITHSYNC_FINALIZESYNC 

Init() is called threaded but the parallel loop body won't start until Init() has finished for all threads, Finalize() is called synchronously.

Function Documentation

◆ ExecuteOnMainThread()

auto ExecuteOnMainThread ( FN &&  fn,
Bool  wait 
) -> decltype(fn())

Executes a lambda on the main thread and returns its result (if any). If the current thread is the main thread the lambda is executed directly. Otherwise a job will be enqueued and the function waits until it has finished. If the job does not return any values and can be executed asynchronously you might specify false as wait parameter. The job is always guaranteed to be executed and this method will only return an error if the lambda does.

Parameters
[in]fnLambda object with the code to be executed.
[in]waitTrue if the caller should wait until the lambda has been executed. False is only permitted for lambdas without return values.
Returns
Return value of the lambda.

◆ GetJobOptions()

JOBOPTIONFLAGS GetJobOptions ( ) const
Note
This method must not block. It can be called from any thread and this might happen concurrently.

◆ GetName()

const Char* GetName ( void  ) const
Note
This method must not block. It can be called from any thread and this might happen concurrently.

◆ JobInterface() [1/2]

JobInterface ( const JobInterfaceJumpTablePOD &  jmpTable)
explicit

Initializes the JobInterface including the jump table to the implementation methods.

Parameters
[in]jmpTableJump table of the implementation class.

◆ ~JobInterface()

◆ JobInterface() [2/2]

Move constructor is just for use with BaseArray (JobGroupInterface::Add())

◆ operator=()

JobInterface& operator= ( JobInterface &&  src)

Move assignment operator is just for use with BaseArray (JobGroupInterface::Add()).

◆ Wait()

Bool Wait ( TimeValue  timeout = TIMEVALUE_INFINITE,
WAITMODE  mode = WAITMODE::DEFAULT 
) const

Waits until this job has been executed. As long as a job hasn't been started it is considered not to have finished yet. Once it has run this will return immediately.

Wait() might execute other jobs in the current queue until the one you are waiting for has finished or is timed out. Therefore you must never lock a shared resource another job might use as well and then wait. For one this could dead-lock and conceptually this would result in single-threaded performance.

If you call Wait() from within an enqueued job you must have enqueued what you are waiting for. Otherwise Wait() will immediately return false because this would lead to a deadlock. The same applies if a job tries to wait for itself.

Instead of waiting for a job to start some action after it has finished you can subscribe to ObservableFinished(). This cannot dead-lock, is more efficient and can even be used to run the observer in a different queue. For example you can run a job and register an observer for it that will run on the main thread's queue and updates the UI. THREADSAFE.

Parameters
[in]timeoutMaximum wait interval (or TIMEVALUE_INFINITE for no time-out).
[in]modeWAITMODE::DEFAULT by default. WAITMODE::RETURN_ON_CANCEL means that Wait() will return if the caller has been cancelled even if the condition has not been set yet.
Returns
True if successful, false if you try to wait inside an enqueued job.

◆ GetResult() [1/3]

Result<void> GetResult ( TimeValue  timeout = TIMEVALUE_INFINITE,
WAITMODE  mode = WAITMODE::DEFAULT 
) const

Waits until this job has been executed and returns the result. THREADSAFE.

Parameters
[in]timeoutMaximum wait interval (or TIMEVALUE_INFINITE for no time-out).
[in]modeWAITMODE::DEFAULT by default. WAITMODE::RETURN_ON_CANCEL means that Wait() will return if the caller has been cancelled even if the condition has not been set yet.
Returns
OK on success.

◆ MoveResult() [1/3]

Result<void> MoveResult ( TimeValue  timeout = TIMEVALUE_INFINITE,
WAITMODE  mode = WAITMODE::DEFAULT 
)

Waits until this job has been executed and returns the result via std::move.

Note
You may only use MoveResult() if you can ensure that nobody else will ask for the result of the job. THREADSAFE.
Parameters
[in]timeoutMaximum wait interval (or TIMEVALUE_INFINITE for no time-out).
[in]modeWAITMODE::DEFAULT by default. WAITMODE::RETURN_ON_CANCEL means that Wait() will return if the caller has been cancelled even if the condition has not been set yet.
Returns
OK on success.

◆ Cancel()

void Cancel ( )

Asks the job to cancel execution. If the job is a part of a group the whole group will be cancelled. Cancellation of a job does not affect its finish observers. The call will not wait for the job to cancel. THREADSAFE.

◆ IsCancelled() [1/2]

Bool IsCancelled ( ) const

Checks if the job should stop. THREADSAFE.

Returns
True if the job has been asked to cancel.

◆ CancelAndWait()

void CancelAndWait ( WAITMODE  mode = WAITMODE::DEFAULT)

Asks the job to cancel execution and waits until it has finished. If the job is a part of a group the whole group will be cancelled. Cancellation of a job does not affect its finish observers. THREADSAFE.

Parameters
[in]modeWAITMODE::DEFAULT by default.

◆ Enqueue()

Enqueues this job (will add a reference and remove it when the object is no longer needed). THREADSAFE.

Parameters
[in]queueThe queue, use JOBQUEUE_CURRENT for the current queue.
Returns
Always this pointer (for concatenation).

◆ AddSubJob() [1/3]

Result<void> AddSubJob ( JobInterface subJob)

Adds a job to this job's group (see JobGroup). The caller must belong to a group. THREADSAFE.

Parameters
[in]subJobJob (nullptr will return error).
Returns
OK on success.

◆ AddSubJob() [2/3]

Result<void> AddSubJob ( ResultMemT< JOB *>  subJob)

Adds a job to this job's group (see JobGroup). The caller must belong to a group. THREADSAFE.

Parameters
[in]subJobJob (nullptr will return error).
Returns
OK on success.

◆ AddSubJob() [3/3]

Result<void> AddSubJob ( ResultMemT< JOBREF > &&  subJob)

Adds a job to this job's group (see JobGroup). The caller must belong to a group. THREADSAFE.

Parameters
[in]subJobJob (encapsulated in a ResultMemT directly returned from creation).
Returns
OK on success.

◆ AddSubGroup() [1/3]

Result<void> AddSubGroup ( GROUP *  subGroup)

Adds a subgroup to this job's group. The caller must belong to a group. THREADSAFE.

Parameters
[in]subGroupJob group (nullptr will return error).
Returns
OK on success.

◆ AddSubGroup() [2/3]

Result<void> AddSubGroup ( ResultMemT< GROUP *>  subGroup)

Adds a subgroup to this job's group. The caller must belong to a group. THREADSAFE.

Parameters
[in]subGroupJob group (encapsulated in a ResultMemT directly returned from creation).
Returns
OK on success.

◆ AddSubGroup() [3/3]

Result<void> AddSubGroup ( ResultMemT< GROUP >  subGroup)

Adds a subgroup to this job's group. The caller must belong to a group. THREADSAFE.

Parameters
[in]subGroupJob group (encapsulated in a ResultMemT directly returned from creation).
Returns
OK on success.

◆ GetJobGroup()

JobGroupInterface* GetJobGroup ( ) const

Returns the group a job belongs to. THREADSAFE.

Returns
JobGroup this job belongs to or nullptr if it's not part of a group.

◆ ObservableFinished()

ObservableFinishedBase<JobInterface> ObservableFinished ( )

ObservableFinished is an observable that is triggered after this job has been executed. THREADSAFE.

Returns
Custom observable.

◆ ObservableCancelled()

ObservableCancelledBase<JobInterface> ObservableCancelled ( )

ObservableCancelled is an observable that is triggered when this job is cancelled. THREADSAFE.

Returns
Custom observable.

◆ GetCurrentWorkerThreadIndex()

static Int GetCurrentWorkerThreadIndex ( )
static

Returns the index of the internal worker thread which is running this job. If the job is not running as part of a worker thread 0 is returned to make sure you can safely use this as index to an array with thread local data. THREADSAFE.

Returns
Index between 0 and the number of threads used for the queue - 1.

◆ GetCurrentThreadCount()

static Int GetCurrentThreadCount ( )
static

Returns the number of worker threads for the current job context. This might be different from the actual CPU core or thread count. THREADSAFE.

Returns
Number of worker threads, guaranteed to be > 0.

◆ IsCurrentJobCancelled()

static Bool IsCurrentJobCancelled ( const JobInterface optionalJob = nullptr)
static

Checks if the currently running job (or thread) should stop. Works for jobs and threads. THREADSAFE.

Parameters
[in]optionalJobOptional job which should also be checked for cancellation.
Returns
True if the job has been asked to cancel.

◆ GetCurrentJob()

static JobStatusInterface* GetCurrentJob ( )
static

Returns a pointer to the currently running job which can be used to check if it's cancelled. Works for jobs and threads.

Returns
Currently running job. Can be nullptr if called from an alien thread.

◆ ToString()

String ToString ( const FormatStatement formatStatement) const

Returns a readable string of the content.

Parameters
[in]formatStatementNullptr or additional formatting instruction. Currently no additional formatting instructions are supported.
Returns
The converted result.

◆ MAXON_DISALLOW_COPY_AND_ASSIGN() [1/2]

MAXON_DISALLOW_COPY_AND_ASSIGN ( JobInterface  )
private

◆ GetWorker()

static IMPLEMENTATION& GetWorker ( const JobInterface job)
staticprivate

◆ DestructWorker()

static void* DestructWorker ( const JobInterface self)
staticprivate

◆ RunWorker()

static const ErrorInterface* RunWorker ( const JobInterface job)
staticprivate

◆ GetWorkerDependencyGroupImpl() [1/2]

static const JobDependencyGroupInterface* GetWorkerDependencyGroupImpl ( const JobInterface job,
std::false_type *   
)
staticprivate

◆ GetWorkerDependencyGroupImpl() [2/2]

static const JobDependencyGroupInterface* GetWorkerDependencyGroupImpl ( const JobInterface job,
std::true_type *   
)
staticprivate

◆ GetWorkerDependencyGroup()

static const JobDependencyGroupInterface* GetWorkerDependencyGroup ( const JobInterface job)
staticprivate

◆ GetWorkerOptions()

static void* GetWorkerOptions ( const JobInterface self,
Int  selector,
void *  param 
)
staticprivate

◆ GetCoreJobGroup()

static CoreJobGroup& GetCoreJobGroup ( JobGroupInterface group)
staticprivate

◆ IsCancelled() [2/2]

Bool IsCancelled ( ) const

Checks if the job should stop. THREADSAFE.

Returns
True if the job has been asked to cancel.

◆ GetResult() [2/3]

Result<RESULTVALUETYPE> GetResult ( TimeValue  timeout = TIMEVALUE_INFINITE,
WAITMODE  mode = WAITMODE::DEFAULT 
) const

Waits until this job has been executed and returns the result. THREADSAFE.

Parameters
[in]timeoutMaximum wait interval (or TIMEVALUE_INFINITE for no time-out).
[in]modeWAITMODE::DEFAULT by default. WAITMODE::RETURN_ON_CANCEL means that Wait() will return if the caller has been cancelled even if the condition has not been set yet.
Returns
Result value on success.

◆ MoveResult() [2/3]

Result<RESULTVALUETYPE> MoveResult ( TimeValue  timeout = TIMEVALUE_INFINITE,
WAITMODE  mode = WAITMODE::DEFAULT 
)

Waits until this job has been executed and returns the result via std::move.

Note
You may only use MoveResult() if you can ensure that nobody else will ask for the result of the job. THREADSAFE.
Parameters
[in]timeoutMaximum wait interval (or TIMEVALUE_INFINITE for no time-out).
[in]modeWAITMODE::DEFAULT by default. WAITMODE::RETURN_ON_CANCEL means that Wait() will return if the caller has been cancelled even if the condition has not been set yet.
Returns
Result value on success.

◆ SetResult() [1/4]

ResultOk<void> SetResult ( RESULTVALUETYPE &&  value)
protected

Sets the result value returned by GetResult().

Returns
OK on success.

◆ Invoke() [1/4]

Result<void> Invoke ( FN &&  obj,
ARGS &&...  args 
)
protected

◆ GetResult() [3/3]

Result<RESULTVALUETYPE> GetResult ( TimeValue  timeout = TIMEVALUE_INFINITE,
WAITMODE  mode = WAITMODE::DEFAULT 
) const

Waits until this job has been executed and returns the result. THREADSAFE.

Parameters
[in]timeoutMaximum wait interval (or TIMEVALUE_INFINITE for no time-out).
[in]modeWAITMODE::DEFAULT by default. WAITMODE::RETURN_ON_CANCEL means that Wait() will return if the caller has been cancelled even if the condition has not been set yet.
Returns
Result value on success.

◆ MoveResult() [3/3]

Result<RESULTVALUETYPE> MoveResult ( TimeValue  timeout = TIMEVALUE_INFINITE,
WAITMODE  mode = WAITMODE::DEFAULT 
)

Waits until this job has been executed and returns the result via std::move.

Note
You may only use MoveResult() if you can ensure that nobody else will ask for the result of the job. THREADSAFE.
Parameters
[in]timeoutMaximum wait interval (or TIMEVALUE_INFINITE for no time-out).
[in]modeWAITMODE::DEFAULT by default. WAITMODE::RETURN_ON_CANCEL means that Wait() will return if the caller has been cancelled even if the condition has not been set yet.
Returns
Result value on success.

◆ SetResult() [2/4]

Result<void> SetResult ( R &&  value)
protected

Sets the result value returned by GetResult().

Returns
OK on success.

◆ Invoke() [2/4]

Result<void> Invoke ( FN &&  obj,
ARGS &&...  args 
)
protected

◆ SetResult() [3/4]

Result<void> SetResult ( R &&  resultOnly)
protected

Sets the result value returned by GetResult() (in this specialisation the Result<void> is just forwarded).

Returns
OK on success.

◆ Invoke() [3/4]

Result<void> Invoke ( FN &&  obj,
ARGS &&...  args 
)
protected

◆ SetResult() [4/4]

ResultOk<void> SetResult ( )
protected

Sets the result value returned by GetResult() (in this specialisiation just a dummy because it's void).

Returns
OK on success.

◆ Invoke() [4/4]

Result<void> Invoke ( FN &&  obj,
ARGS &&...  args 
)
protected

◆ Create()

static ResultMemT<JobResultRef<RESULTVALUETYPE> > Create ( ARGS &&...  args)
static

Creates the job.

Parameters
[in]argsArguments for the construcor.
Template Parameters
ARGSParameter types.
Returns
JobRef on success, OutOfMemoryerror on failure.

◆ MAXON_DISALLOW_COPY_AND_ASSIGN() [2/2]

MAXON_DISALLOW_COPY_AND_ASSIGN ( JobInterfaceTemplate< IMPLEMENTATION, RESULTVALUETYPE >  )
private

◆ MAXON_DATATYPE() [1/2]

maxon::MAXON_DATATYPE ( JobRef  ,
"net.maxon.datatype.job"   
)

◆ MAXON_ENUM_FLAGS() [1/4]

enum maxon::JOBGROUPFLAGS maxon::MAXON_ENUM_FLAGS ( JOBGROUPFLAGS  )

◆ MAXON_ENUM_FLAGS() [2/4]

enum maxon::STATICJOBGROUPFLAGS maxon::MAXON_ENUM_FLAGS ( STATICJOBGROUPFLAGS  )

◆ MAXON_ENUM_FLAGS() [3/4]

enum maxon::STATICJOBARRAYFLAGS maxon::MAXON_ENUM_FLAGS ( STATICJOBARRAYFLAGS  )

◆ MAXON_ENUM_LIST() [1/2]

enum maxon::JOBQUEUETYPE maxon::MAXON_ENUM_LIST ( JOBQUEUETYPE  )

◆ MAXON_ENUM_LIST() [2/2]

enum maxon::JOBQUEUEMODE maxon::MAXON_ENUM_LIST ( JOBQUEUEMODE  )

◆ MAXON_ENUM_FLAGS() [4/4]

enum maxon::PARALLELFORFLAGS maxon::MAXON_ENUM_FLAGS ( PARALLELFORFLAGS  )

◆ ParallelInvoke()

Result<void> maxon::ParallelInvoke ( Bool  parallel,
ARGS &&...  args 
)

Executes multiple functions in parallel and waits until they have finished. The parallel flag should be used for recursive code and set to false once the work item size is so small it wouldn't make sense to parallelize it any further. Please note that using ParallelInvoke() to parallelize a recursive algorithm is handy but will never perform as good as using a parallelized non-recursive algorithm because of the required synchronization at each recursion level. Execution of the parallel code is guaranteed - even under low memory conditions. If the lambdas do not return Result<void> the routine will return OK.

Parameters
[in]parallelTrue for parallel execution, false if amount of work has become very small.
[in]argsCallable objects, usually lambdas.
Template Parameters
ARGSParameter types.
Returns
OK on success. Will only return an error if a lambda returns one via Result<void>. Please note that you'll receive an AggregatedError here that contains the errors created in the lambda and not the errors directly.

◆ MAXON_DATATYPE() [2/2]

maxon::MAXON_DATATYPE ( ThreadRef  ,
"net.maxon.datatype.threadref"   
)

Variable Documentation

◆ _result [1/2]

RESULTVALUETYPE _result
private

◆ _result [2/2]

Result<RESULTVALUETYPE> _result
private

◆ JOBQUEUE_USEMAXIMUMTHREADS

const Int JOBQUEUE_USEMAXIMUMTHREADS
static

◆ JOBQUEUE_CURRENT

const JobQueueInterface::Current JOBQUEUE_CURRENT
static

Equivalent to calling GetDestinationQueue(), you just save a function call.

◆ JOBQUEUE_NONE

const JobQueueInterface::None JOBQUEUE_NONE
static

For notifications and timer jobs: Executes them immediately on the current thread.

◆ PARALLELFOR_DEFAULTGRANULARITY

const Int PARALLELFOR_DEFAULTGRANULARITY
static

◆ PARALLELFOR_MINIMUMGRANULARITY

const Int PARALLELFOR_MINIMUMGRANULARITY
static

◆ PARALLELFOR_USEMAXIMUMTHREADS

const Int PARALLELFOR_USEMAXIMUMTHREADS
static

◆ PARALLELFOR_DISABLETHREADING

const Int PARALLELFOR_DISABLETHREADING
static

◆ PARALLELFOR_MAXIMUMDEPTH

const Int PARALLELFOR_MAXIMUMDEPTH
static

◆ g_trackSpinlocks

Bool g_trackSpinlocks

Friends

◆ StrongRefHandler

friend class StrongRefHandler
friend

◆ ObservableFinishedBase

friend struct ObservableFinishedBase
friend

◆ ObservableCancelledBase

friend struct ObservableCancelledBase
friend

◆ JobGroupInterface

friend class JobGroupInterface
friend

◆ StaticJobGroupInterface

friend class StaticJobGroupInterface
friend

◆ TimerInterface

friend class TimerInterface
friend

◆ ExecuteOnMainThread

auto ExecuteOnMainThread ( FN &&  fn,
Bool  wait 
) -> decltype(fn())
friend

Executes a lambda on the main thread and returns its result (if any). If the current thread is the main thread the lambda is executed directly. Otherwise a job will be enqueued and the function waits until it has finished. If the job does not return any values and can be executed asynchronously you might specify false as wait parameter. The job is always guaranteed to be executed and this method will only return an error if the lambda does.

Parameters
[in]fnLambda object with the code to be executed.
[in]waitTrue if the caller should wait until the lambda has been executed. False is only permitted for lambdas without return values.
Returns
Return value of the lambda.