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#include "tbb/task_group.h"
19#include "tbb/task_arena.h"
20#endif
21
22#include <type_traits>
23#include <stdexcept>
24
25/**
26\class ROOT::Experimental::TTaskGroup
27\ingroup Parallelism
28\brief A class to manage the asynchronous execution of work items.
29
30A TTaskGroup represents concurrent execution of a group of tasks.
31Tasks may be dynamically added to the group as it is executing.
32Nesting TTaskGroup instances may result in a runtime overhead.
33*/
34
35namespace ROOT {
36
37namespace Internal {
38
39#ifdef R__USE_IMT
40tbb::task_group *CastToTG(void* p) {
41 return (tbb::task_group *) p;
42}
43
44#endif
45
46} // namespace Internal
47
48namespace Experimental {
49
50using namespace ROOT::Internal;
51
52// in the constructor and destructor the casts are present in order to be able
53// to be independent from the runtime used.
54// This leaves the door open for other TTaskGroup implementations.
55
57{
58#ifdef R__USE_IMT
60 throw std::runtime_error("Implicit parallelism not enabled. Cannot instantiate a TTaskGroup.");
61 }
62 fTaskContainer = ((void *)new tbb::task_group());
63#endif
64}
65
67{
68 *this = std::move(other);
69}
70
72{
74 other.fTaskContainer = nullptr;
75 fCanRun.store(other.fCanRun);
76 return *this;
77}
78
80{
81#ifdef R__USE_IMT
82 if (!fTaskContainer)
83 return;
84 Wait();
86#endif
87}
88
89/////////////////////////////////////////////////////////////////////////////
90/// Cancel all submitted tasks immediately.
92{
93#ifdef R__USE_IMT
94 fCanRun = false;
95 CastToTG(fTaskContainer)->cancel();
96 fCanRun = true;
97#endif
98}
99
100/////////////////////////////////////////////////////////////////////////////
101/// Add to the group an item of work which will be ran asynchronously.
102/// Adding many small items of work to the TTaskGroup is not efficient,
103/// unless they run for long enough. If the work to be done is little, look
104/// try to express nested parallelism or resort to other constructs such as
105/// the TThreadExecutor.
106/// Trying to add a work item to the group while it is in waiting state
107/// makes the method block.
108void TTaskGroup::Run(const std::function<void(void)> &closure)
109{
110#ifdef R__USE_IMT
111 while (!fCanRun)
112 /* empty */;
113
114 CastToTG(fTaskContainer)->run(closure);
115#else
116 closure();
117#endif
118}
119
120/////////////////////////////////////////////////////////////////////////////
121/// Wait until all submitted items of work are completed. This method
122/// is blocking.
124{
125#ifdef R__USE_IMT
126 fCanRun = false;
127 CastToTG(fTaskContainer)->wait();
128 fCanRun = true;
129#endif
130}
131} // namespace Experimental
132} // namespace ROOT
A class to manage the asynchronous execution of work items.
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::atomic< bool > fCanRun
tbb::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:558