HDK
|
#include <UT_TaskExclusive.h>
Public Member Functions | |
UT_TaskExclusive () | |
void | execute (T &func, bool run_in_task_arena=true, bool use_spinlock=false) |
void | executeNoThread (T &func) |
void | reset () |
bool | hasRun () const |
This is a lock-free implementation for exclusive task execution. That is, a task which needs to be performed once (i.e. std::once). However, this construct will allow TBB to recycle blocked tasks so they can be used for other processing.
This can be used as an alternate to a lock. If code underneath a lock calls into TBB, this can lead to a deadlock since TBB can steal a child task to complete a parent task outside the lock. This typically requires a separate task arena. A lock will also block a thread, preventing it from participating in other tasks.
UT_TaskExclusive provides a good alternative, ensuring that only one thread will execute the functor, and all other threads which wait for the functor to finish will be allowed to participate in other computation (even to help computing parallel tasks in the functor).
The class is templated on a functor which is used to actually perform the execution. The template functor needs to have a operator()() method.
For example, given a single Object which has a deferredInitialize() method that may get called from multiple threads:
If you have multiple methods that should only be called one time, you can always create a nested object functor.
If the functor is likely to create further tbb tasks, you can ensure these tasks are run in their own task arena by setting run_in_task_arena
to true (the default).
Definition at line 85 of file UT_TaskExclusive.h.
|
inline |
Definition at line 88 of file UT_TaskExclusive.h.
|
inline |
Execute the compute task. This will guarantee the function has been run before the execute() function returns. However, no locking will be done.
If multiple threads try to call the function simultaneously, only one function will run, while the other will yield its cycles to other parallel tasks. When the first task completes, both threads will return.
If the functor is likely to create further tbb tasks, you can ensure these tasks are run in their own task arena by setting run_in_task_arena
to true (the default). The primary reason for having a separate task arena is that the if the functor creates further tasks, and one of these tasks is also dependent on the task exclusive, this can lead to a tbb deadlock (a tbb stack lock).
Definition at line 108 of file UT_TaskExclusive.h.
|
inline |
Executes the compute task in this thread without any locking or protection. Useful if the caller has already setup the appropriate lock.
Definition at line 245 of file UT_TaskExclusive.h.
|
inline |
Test whether the function has been executed. This is thread-safe, but doesn't count on other threads which may be in the process of running it.
Definition at line 262 of file UT_TaskExclusive.h.
|
inline |
Resetting the exclusive task should only be done when there's no possibility that any threads are trying to execute or relying on the results of the computation.
Definition at line 257 of file UT_TaskExclusive.h.