ROOT
master
Reference Guide
Loading...
Searching...
No Matches
worker.cxx
Go to the documentation of this file.
1
/*
2
* Project: RooFit
3
* Authors:
4
* PB, Patrick Bos, Netherlands eScience Center, p.bos@esciencecenter.nl
5
* IP, Inti Pelupessy, Netherlands eScience Center, i.pelupessy@esciencecenter.nl
6
*
7
* Copyright (c) 2021, CERN
8
*
9
* Redistribution and use in source and binary forms,
10
* with or without modification, are permitted according to the terms
11
* listed in LICENSE (http://roofit.sourceforge.net/license.txt)
12
*/
13
14
#include "
RooFit/MultiProcess/worker.h
"
15
16
#include "
RooFit/MultiProcess/JobManager.h
"
17
#include "
RooFit/MultiProcess/types.h
"
18
#include "
RooFit/MultiProcess/Messenger.h
"
19
#include "
RooFit/MultiProcess/Job.h
"
20
#include "
RooFit/MultiProcess/util.h
"
21
#include "
RooFit/MultiProcess/ProcessTimer.h
"
22
#include "
RooFit/MultiProcess/Config.h
"
23
24
#include <string>
25
#include <unistd.h>
// getpid, pid_t
26
#include <cassert>
27
#include <cerrno>
// EINTR
28
#include <csignal>
// sigprocmask etc
29
30
namespace
RooFit
{
31
namespace
MultiProcess {
32
33
static
bool
worker_loop_running
=
false
;
34
35
bool
is_worker_loop_running
()
36
{
37
return
worker_loop_running
;
38
}
39
40
/// \brief The worker processes' event loop
41
///
42
/// Asks the queue process for tasks, polls for incoming messages from other
43
/// processes and handles them.
44
void
worker_loop
()
45
{
46
assert
(
JobManager::instance
()->process_manager().is_worker());
47
worker_loop_running
=
true
;
48
Q2W
message_q2w
;
49
50
// use a flag to not ask twice
51
bool
dequeue_acknowledged
=
true
;
52
53
Poller
poller
;
54
std::size_t
mw_sub_index
;
55
56
std::tie(
poller
,
mw_sub_index
) =
JobManager::instance
()->messenger().create_worker_poller();
57
58
// The SIGTERM handler was set in the ProcessManager after forking to the queue and worker
59
// processes; it wakes up any poll through the self-pipe, so no signal blocking is needed here.
60
while
(!
ProcessManager::sigterm_received
()) {
61
try
{
// watch for error from poll (which is called inside receive functions) caused by SIGTERM from master
62
63
// try to dequeue a task
64
if
(
dequeue_acknowledged
) {
// don't ask twice
65
JobManager::instance
()->messenger().send_from_worker_to_queue(
W2Q::dequeue
);
66
dequeue_acknowledged
=
false
;
67
}
68
69
// wait for handshake from queue or update from the master-worker channel
70
auto
poll_result
=
poller
.poll(-1);
71
// because the poller may now have a waiting update from master over the master-worker
72
// channel, but the queue channel could be first in the poll_result vector, and during
73
// handling of a new task it is possible we need to already receive the updated state,
74
// we have to then flip this boolean so that in the for loop when we reach the
75
// master-worker channel's result, we can skip it (otherwise we will hang there,
76
// because no more updated state will be coming):
77
bool
skip_sub
=
false
;
78
// then process incoming messages from the channels
79
for
(
auto
readable_index
:
poll_result
) {
80
// message comes from the master-worker channel (first element):
81
if
(
readable_index
==
mw_sub_index
) {
82
if
(!
skip_sub
) {
83
auto
job_id =
JobManager::instance
()->messenger().receive_from_master_on_worker<std::size_t>();
84
JobManager::get_job_object
(job_id)->update_state();
85
}
86
}
else
{
// from queue channel
87
message_q2w
=
JobManager::instance
()->messenger().receive_from_queue_on_worker<
Q2W
>();
88
switch
(
message_q2w
) {
89
case
Q2W::dequeue_rejected
: {
90
dequeue_acknowledged
=
true
;
91
break
;
92
}
93
case
Q2W::dequeue_accepted
: {
94
dequeue_acknowledged
=
true
;
95
auto
job_id =
JobManager::instance
()->messenger().receive_from_queue_on_worker<std::size_t>();
96
auto
state_id =
JobManager::instance
()->messenger().receive_from_queue_on_worker<
State
>();
97
auto
task_id =
JobManager::instance
()->messenger().receive_from_queue_on_worker<
Task
>();
98
99
// while loop, because multiple jobs may have updated state coming
100
while
(state_id !=
JobManager::get_job_object
(job_id)->get_state_id()) {
101
skip_sub
=
true
;
102
auto
job_id_for_state
=
103
JobManager::instance
()->messenger().receive_from_master_on_worker<std::size_t>();
104
JobManager::get_job_object
(
job_id_for_state
)->update_state();
105
}
106
if
(
RooFit::MultiProcess::Config::getTimingAnalysis
())
ProcessTimer::start_timer
(
"worker:eval_task:"
+ std::to_string(task_id));
107
JobManager::get_job_object
(job_id)->evaluate_task(task_id);
108
if
(
RooFit::MultiProcess::Config::getTimingAnalysis
())
ProcessTimer::end_timer
(
"worker:eval_task:"
+ std::to_string(task_id));
109
JobManager::get_job_object
(job_id)->send_back_task_result_from_worker(task_id);
110
111
break
;
112
}
113
}
114
}
115
}
116
117
}
catch
(
ppoll_error_t
&) {
118
// SIGTERM received (benign signal interruptions are retried inside
119
// Channel::wait), so exit the loop
120
break
;
121
}
122
}
123
124
if
(
RooFit::MultiProcess::Config::getTimingAnalysis
())
125
ProcessTimer::write_file
();
126
127
worker_loop_running
=
false
;
128
}
129
130
}
// namespace MultiProcess
131
}
// namespace RooFit
JobManager.h
Job.h
Messenger.h
ProcessTimer.h
TRangeDynCast
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Definition
TCollection.h:359
ROOT::Detail::TRangeCast
Definition
TCollection.h:312
RooFit::MultiProcess::Config::getTimingAnalysis
static bool getTimingAnalysis()
Definition
Config.cxx:87
RooFit::MultiProcess::JobManager::instance
static JobManager * instance()
Definition
JobManager.cxx:49
RooFit::MultiProcess::JobManager::get_job_object
static Job * get_job_object(std::size_t job_object_id)
Definition
JobManager.cxx:132
RooFit::MultiProcess::Poller
Waits for input on a set of registered Channels.
Definition
Poller.h:34
RooFit::MultiProcess::ProcessManager::sigterm_received
static bool sigterm_received()
Definition
ProcessManager.cxx:92
RooFit::MultiProcess::ProcessTimer::write_file
static void write_file()
Definition
ProcessTimer.cxx:141
RooFit::MultiProcess::ProcessTimer::start_timer
static void start_timer(std::string section_name)
Definition
ProcessTimer.cxx:55
RooFit::MultiProcess::ProcessTimer::end_timer
static void end_timer(std::string section_name)
Definition
ProcessTimer.cxx:71
RooFit::MultiProcess::ppoll_error_t
Thrown when a blocking wait on a Channel is interrupted, e.g.
Definition
Channel.h:31
RooFit::MultiProcess::worker_loop
void worker_loop()
The worker processes' event loop.
Definition
worker.cxx:44
RooFit::MultiProcess::is_worker_loop_running
bool is_worker_loop_running()
Definition
worker.cxx:35
RooFit::MultiProcess::Task
std::size_t Task
Definition
types.h:22
RooFit::MultiProcess::W2Q::dequeue
@ dequeue
RooFit::MultiProcess::Q2W
Q2W
Definition
Messenger_decl.h:137
RooFit::MultiProcess::Q2W::dequeue_rejected
@ dequeue_rejected
RooFit::MultiProcess::Q2W::dequeue_accepted
@ dequeue_accepted
RooFit::MultiProcess::worker_loop_running
static bool worker_loop_running
Definition
worker.cxx:33
RooFit::MultiProcess::State
std::size_t State
Definition
types.h:23
RooFit
The namespace RooFit contains mostly switches that change the behaviour of functions of PDFs (or othe...
Definition
CodegenImpl.h:73
Config.h
types.h
util.h
worker.h
roofit
multiprocess
src
worker.cxx
ROOTmaster - Reference Guide Generated on Sun Sep 13 2026 05:45:37 (GVA Time) using Doxygen 1.10.0