FWCore
Concurrency
src
WaitingTaskWithArenaHolder.cc
Go to the documentation of this file.
1
// -*- C++ -*-
2
//
3
// Package: Concurrency
4
// Class : WaitingTaskWithArenaHolder
5
//
6
// Original Author: W. David Dagenhart
7
// Created: 6 December 2017
8
9
#include "
FWCore/Concurrency/interface/WaitingTaskWithArenaHolder.h
"
10
#include "
FWCore/Concurrency/interface/WaitingTask.h
"
11
#include "
FWCore/Concurrency/interface/WaitingTaskHolder.h
"
12
#include "
FWCore/Utilities/interface/Likely.h
"
13
14
namespace
edm
{
15
16
WaitingTaskWithArenaHolder::WaitingTaskWithArenaHolder
() : m_task(nullptr) {}
17
18
// Note that the arena will be the one containing the thread
19
// that runs this constructor. This is the arena where you
20
// eventually intend for the task to be spawned.
21
WaitingTaskWithArenaHolder::WaitingTaskWithArenaHolder
(tbb::task_group& iGroup,
WaitingTask
* iTask)
22
: m_task(iTask), m_group(&iGroup), m_arena(
std
::make_shared<tbb::task_arena>(tbb::task_arena::attach())) {
23
m_task
->
increment_ref_count
();
24
}
25
26
WaitingTaskWithArenaHolder::WaitingTaskWithArenaHolder
(
WaitingTaskHolder
&& iTask)
27
: m_task(iTask.release_no_decrement()),
28
m_group(iTask.
group
()),
29
m_arena(
std
::make_shared<tbb::task_arena>(tbb::task_arena::attach())) {}
30
31
WaitingTaskWithArenaHolder::~WaitingTaskWithArenaHolder
() {
32
if
(
m_task
) {
33
doneWaiting
(std::exception_ptr{});
34
}
35
}
36
37
WaitingTaskWithArenaHolder::WaitingTaskWithArenaHolder
(
WaitingTaskWithArenaHolder
const
& iHolder)
38
: m_task(iHolder.m_task), m_group(iHolder.m_group), m_arena(iHolder.m_arena) {
39
if
(
LIKELY
(
m_task
!=
nullptr
)) {
40
m_task
->
increment_ref_count
();
41
}
42
}
43
44
WaitingTaskWithArenaHolder::WaitingTaskWithArenaHolder
(
WaitingTaskWithArenaHolder
&& iOther)
45
: m_task(iOther.m_task), m_group(iOther.m_group), m_arena(
std
::
move
(iOther.m_arena)) {
46
iOther.m_task =
nullptr
;
47
}
48
49
WaitingTaskWithArenaHolder
&
WaitingTaskWithArenaHolder::operator=
(
const
WaitingTaskWithArenaHolder
& iRHS) {
50
WaitingTaskWithArenaHolder
tmp
(iRHS);
51
std::swap
(
m_task
,
tmp
.m_task);
52
std::swap
(
m_group
,
tmp
.m_group);
53
std::swap
(
m_arena
,
tmp
.m_arena);
54
return
*
this
;
55
}
56
57
WaitingTaskWithArenaHolder
&
WaitingTaskWithArenaHolder::operator=
(
WaitingTaskWithArenaHolder
&& iRHS) {
58
WaitingTaskWithArenaHolder
tmp
(
std::move
(iRHS));
59
std::swap
(
m_task
,
tmp
.m_task);
60
std::swap
(
m_group
,
tmp
.m_group);
61
std::swap
(
m_arena
,
tmp
.m_arena);
62
return
*
this
;
63
}
64
65
// This spawns the task. The arena is needed to get the task spawned
66
// into the correct arena of threads. Use of the arena allows doneWaiting
67
// to be called from a thread outside the arena of threads that will manage
68
// the task. doneWaiting can be called from a non-TBB thread.
69
void
WaitingTaskWithArenaHolder::doneWaiting
(std::exception_ptr iExcept) {
70
if
(iExcept) {
71
m_task
->
dependentTaskFailed
(iExcept);
72
}
73
//enqueue can run the task before we finish
74
// doneWaiting and some other thread might
75
// try to reuse this object. Resetting
76
// before enqueue avoids problems
77
auto
task
=
m_task
;
78
m_task
=
nullptr
;
79
if
(0 ==
task
->decrement_ref_count()) {
80
// The enqueue call will cause a worker thread to be created in
81
// the arena if there is not one already.
82
m_arena
->enqueue([
task
=
task
,
group
=
m_group
]() {
83
group
->run([
task
]() {
84
TaskSentry
s
(
task
);
85
task
->execute();
86
});
87
});
88
}
89
}
90
91
// This next function is useful if you know from the context that
92
// m_arena (which is set when the constructor was executes) is the
93
// same arena in which you want to execute the doneWaiting function.
94
// It allows an optimization which avoids the enqueue step in the
95
// doneWaiting function.
96
//
97
// Be warned though that in general this function cannot be used.
98
// Spawning a task outside the correct arena could create a new separate
99
// arena with its own extra TBB worker threads if this function is used
100
// in an inappropriate context (and silently such that you might not notice
101
// the problem quickly).
102
103
WaitingTaskHolder
WaitingTaskWithArenaHolder::makeWaitingTaskHolderAndRelease
() {
104
WaitingTaskHolder
holder(*
m_group
,
m_task
);
105
m_task
->
decrement_ref_count
();
106
m_task
=
nullptr
;
107
return
holder;
108
}
109
110
bool
WaitingTaskWithArenaHolder::taskHasFailed
()
const
noexcept {
return
m_task
->
exceptionPtr
() !=
nullptr
; }
111
112
bool
WaitingTaskWithArenaHolder::hasTask
()
const
noexcept {
return
m_task
!=
nullptr
; }
113
114
}
// namespace edm
Likely.h
edm::WaitingTaskWithArenaHolder::operator=
WaitingTaskWithArenaHolder & operator=(const WaitingTaskWithArenaHolder &iRHS)
Definition:
WaitingTaskWithArenaHolder.cc:49
edm::WaitingTaskWithArenaHolder::WaitingTaskWithArenaHolder
WaitingTaskWithArenaHolder()
Definition:
WaitingTaskWithArenaHolder.cc:16
WaitingTaskHolder.h
edm
HLT enums.
Definition:
AlignableModifier.h:19
edm::WaitingTaskWithArenaHolder::m_task
WaitingTask * m_task
Definition:
WaitingTaskWithArenaHolder.h:87
edm::TaskSentry
Definition:
TaskBase.h:50
createJobs.tmp
tmp
align.sh
Definition:
createJobs.py:716
watchdog.const
const
Definition:
watchdog.py:83
edm::WaitingTaskWithArenaHolder::group
tbb::task_group * group() const
Definition:
WaitingTaskWithArenaHolder.h:83
edm::WaitingTaskWithArenaHolder::m_arena
std::shared_ptr< tbb::task_arena > m_arena
Definition:
WaitingTaskWithArenaHolder.h:89
edm::WaitingTaskWithArenaHolder
Definition:
WaitingTaskWithArenaHolder.h:34
alignCSCRings.s
s
Definition:
alignCSCRings.py:92
edm::WaitingTask::exceptionPtr
std::exception_ptr const * exceptionPtr() const
Returns exception thrown by dependent task.
Definition:
WaitingTask.h:51
std::swap
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
Definition:
DataFrameContainer.h:209
TrackValidation_cff.task
task
Definition:
TrackValidation_cff.py:253
edm::WaitingTaskWithArenaHolder::m_group
tbb::task_group * m_group
Definition:
WaitingTaskWithArenaHolder.h:88
edm::WaitingTaskWithArenaHolder::~WaitingTaskWithArenaHolder
~WaitingTaskWithArenaHolder()
Definition:
WaitingTaskWithArenaHolder.cc:31
edm::WaitingTask::dependentTaskFailed
void dependentTaskFailed(std::exception_ptr iPtr)
Called if waited for task failed.
Definition:
WaitingTask.h:59
WaitingTaskWithArenaHolder.h
edm::WaitingTaskHolder
Definition:
WaitingTaskHolder.h:32
edm::TaskBase::increment_ref_count
void increment_ref_count()
Definition:
TaskBase.h:41
WaitingTask.h
edm::TaskBase::decrement_ref_count
unsigned int decrement_ref_count()
Definition:
TaskBase.h:42
edm::WaitingTask
Definition:
WaitingTask.h:36
eostools.move
def move(src, dest)
Definition:
eostools.py:511
std
Definition:
JetResolutionObject.h:76
LIKELY
#define LIKELY(x)
Definition:
Likely.h:20
edm::WaitingTaskWithArenaHolder::makeWaitingTaskHolderAndRelease
WaitingTaskHolder makeWaitingTaskHolderAndRelease()
Definition:
WaitingTaskWithArenaHolder.cc:103
edm::WaitingTaskWithArenaHolder::taskHasFailed
bool taskHasFailed() const noexcept
Definition:
WaitingTaskWithArenaHolder.cc:110
watchdog.group
group
Definition:
watchdog.py:82
edm::WaitingTaskWithArenaHolder::hasTask
bool hasTask() const noexcept
Definition:
WaitingTaskWithArenaHolder.cc:112
edm::WaitingTaskWithArenaHolder::doneWaiting
void doneWaiting(std::exception_ptr iExcept)
Definition:
WaitingTaskWithArenaHolder.cc:69
Generated for CMSSW Reference Manual by
1.8.16