Logo ROOT  
Reference Guide
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{
73 fTaskContainer = other.fTaskContainer;
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.
Definition: TTaskGroup.hxx:21
void Run(const std::function< void(void)> &closure)
Add to the group an item of work which will be ran asynchronously.
Definition: TTaskGroup.cxx:108
void Wait()
Wait until all submitted items of work are completed.
Definition: TTaskGroup.cxx:123
void Cancel()
Cancel all submitted tasks immediately.
Definition: TTaskGroup.cxx:91
TTaskGroup & operator=(TTaskGroup &&other)
Definition: TTaskGroup.cxx:71
std::atomic< bool > fCanRun
Definition: TTaskGroup.hxx:32
tbb::task_group * CastToTG(void *p)
Definition: TTaskGroup.cxx:40
void function(const Char_t *name_, T fun, const Char_t *docstring=0)
Definition: RExports.h:150
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