Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TTaskGroup.cxx
Go to the documentation of this file.
1// @(#)root/thread:$Id$
2// Author: Danilo Piparo August 2017
3
4/*************************************************************************
5 * Copyright (C) 1995-2017, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12#include "RConfigure.h"
13
14#include "ROOT/TTaskGroup.hxx"
15
16#ifdef R__USE_IMT
17#include "TROOT.h"
18#define TBB_PREVIEW_ISOLATED_TASK_GROUP 1
19#include "tbb/task_group.h"
20#include "tbb/task_arena.h"
21#include "ROOT/RTaskArena.hxx"
22#include "ROpaqueTaskArena.hxx"
23#endif
24
25#include <type_traits>
26#include <stdexcept>
27
28/**
29\class ROOT::Experimental::TTaskGroup
30\ingroup Parallelism
31\brief A class to manage the asynchronous execution of work items.
32
33A TTaskGroup represents concurrent execution of a group of tasks.
34Tasks may be dynamically added to the group as it is executing.
35Nesting TTaskGroup instances may result in a runtime overhead.
36*/
37
38namespace ROOT {
39
40namespace Internal {
41
42#ifdef R__USE_IMT
43tbb::isolated_task_group *CastToTG(void *p)
44{
45 return (tbb::isolated_task_group *)p;
46}
47#endif
48
49} // namespace Internal
50
51namespace Experimental {
52
53using namespace ROOT::Internal;
54
55// in the constructor and destructor the casts are present in order to be able
56// to be independent from the runtime used.
57// This leaves the door open for other TTaskGroup implementations.
58
60{
61#ifdef R__USE_IMT
63 throw std::runtime_error("Implicit parallelism not enabled. Cannot instantiate a TTaskGroup.");
64 }
66 fTaskContainer = ((void *)new tbb::isolated_task_group());
67#endif
68}
69
71{
72 *this = std::move(other);
73}
74
76{
78 fTaskContainer = other.fTaskContainer;
79 other.fTaskContainer = nullptr;
80 return *this;
81}
82
84{
85#ifdef R__USE_IMT
86 if (!fTaskContainer)
87 return;
88 Wait();
90#endif
91}
92
93/////////////////////////////////////////////////////////////////////////////
94/// Run operation in the internal task arena to implement work isolation, i.e.
95/// prevent stealing of work items spawned by ancestors.
96void TTaskGroup::ExecuteInIsolation(const std::function<void(void)> &operation)
97{
98#ifdef R__USE_IMT
99 fTaskArenaW->Access().execute([&] { operation(); });
100#else
101 operation();
102#endif
103}
104
105/////////////////////////////////////////////////////////////////////////////
106/// Cancel all submitted tasks immediately.
108{
109#ifdef R__USE_IMT
110 ExecuteInIsolation([&] { CastToTG(fTaskContainer)->cancel(); });
111#endif
112}
113
114/////////////////////////////////////////////////////////////////////////////
115/// Add to the group an item of work which will be ran asynchronously.
116/// Adding many small items of work to the TTaskGroup is not efficient,
117/// unless they run for long enough. If the work to be done is little, look
118/// try to express nested parallelism or resort to other constructs such as
119/// the TThreadExecutor.
120/// Trying to add a work item to the group while it is in waiting state
121/// makes the method block.
122void TTaskGroup::Run(const std::function<void(void)> &closure)
123{
124#ifdef R__USE_IMT
125 ExecuteInIsolation([&] { CastToTG(fTaskContainer)->run(closure); });
126#else
127 closure();
128#endif
129}
130
131/////////////////////////////////////////////////////////////////////////////
132/// Wait until all submitted items of work are completed. This method
133/// is blocking.
135{
136#ifdef R__USE_IMT
137 ExecuteInIsolation([&] { CastToTG(fTaskContainer)->wait(); });
138#endif
139}
140} // namespace Experimental
141} // namespace ROOT
winID h TVirtualViewer3D TVirtualGLPainter p
A class to manage the asynchronous execution of work items.
std::shared_ptr< ROOT::Internal::RTaskArenaWrapper > fTaskArenaW
void ExecuteInIsolation(const std::function< void(void)> &operation)
Run operation in the internal task arena to implement work isolation, i.e.
void Run(const std::function< void(void)> &closure)
Add to the group an item of work which will be ran asynchronously.
void Wait()
Wait until all submitted items of work are completed.
void Cancel()
Cancel all submitted tasks immediately.
TTaskGroup & operator=(TTaskGroup &&other)
std::shared_ptr< ROOT::Internal::RTaskArenaWrapper > GetGlobalTaskArena(unsigned maxConcurrency=0)
Factory function returning a shared pointer to the instance of the global RTaskArenaWrapper.
tbb::isolated_task_group * CastToTG(void *p)
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
Bool_t IsImplicitMTEnabled()
Returns true if the implicit multi-threading in ROOT is enabled.
Definition TROOT.cxx:570