1 #include "artdaq/DAQdata/Globals.hh"
2 #define TRACE_NAME (app_name + "_BoardReaderApp").c_str() // NOLINT
4 #include "artdaq-core/Utilities/ExceptionHandler.hh"
5 #include "artdaq/Application/BoardReaderApp.hh"
7 #include <boost/lexical_cast.hpp>
13 : fragment_receiver_ptr_(nullptr)
24 external_request_status_ =
true;
30 TLOG(TLVL_DEBUG + 32) <<
"Initializing first deleting old instance " <<
static_cast<void*
>(fragment_receiver_ptr_.get());
31 fragment_receiver_ptr_.reset(
nullptr);
32 fragment_receiver_ptr_ = std::make_unique<BoardReaderCore>(*this);
33 TLOG(TLVL_DEBUG + 32) <<
"Initializing new BoardReaderCore at " <<
static_cast<void*
>(fragment_receiver_ptr_.get()) <<
" with pset " << pset.to_string();
34 external_request_status_ = fragment_receiver_ptr_->initialize(pset, timeout, timestamp);
35 if (!external_request_status_)
37 report_string_ =
"Error initializing ";
38 report_string_.append(app_name +
" ");
39 report_string_.append(
"with ParameterSet = \"" + pset.to_string() +
"\".");
42 TLOG(TLVL_DEBUG + 32) <<
"do_initialize(fhicl::ParameterSet, uint64_t, uint64_t): "
43 <<
"Done initializing.";
44 return external_request_status_;
54 fragment_receiver_ptr_->SetStartTransitionTimeout(timeout);
55 external_request_status_ =
true;
57 boost::thread::attributes attrs;
58 attrs.set_stack_size(4096 * 2000);
63 snprintf(tname,
sizeof(tname) - 1,
"%d-FragOutput", my_rank);
64 tname[
sizeof(tname) - 1] =
'\0';
65 auto handle = fragment_output_thread_.native_handle();
66 pthread_setname_np(handle, tname);
68 snprintf(tname,
sizeof(tname) - 1,
"%d-FragInput", my_rank);
69 tname[
sizeof(tname) - 1] =
'\0';
70 handle = fragment_input_thread_.native_handle();
71 pthread_setname_np(handle, tname);
73 catch (
const boost::exception& e)
75 std::stringstream exception_string;
76 exception_string <<
"Caught boost::exception starting Fragment Processing threads: " << boost::diagnostic_information(e) <<
", errno=" << errno;
78 ExceptionHandler(ExceptionHandlerRethrow::yes, exception_string.str());
81 auto start_wait = std::chrono::steady_clock::now();
82 while (!fragment_receiver_ptr_->GetSenderThreadActive() || !fragment_receiver_ptr_->GetReceiverThreadActive())
84 if (TimeUtils::GetElapsedTime(start_wait) > timeout)
86 TLOG(TLVL_ERROR) <<
"Timeout occurred waiting for BoardReaderCore threads to start. Timeout = " << timeout <<
" s, Time waited = " << TimeUtils::GetElapsedTime(start_wait) <<
" s,"
87 <<
" Receiver ready: " << std::boolalpha << fragment_receiver_ptr_->GetReceiverThreadActive() <<
", Sender ready: " << fragment_receiver_ptr_->GetSenderThreadActive();
88 external_request_status_ =
false;
95 if (external_request_status_)
97 external_request_status_ = fragment_receiver_ptr_->start(
id, timeout, timestamp);
100 if (!external_request_status_)
102 report_string_ =
"Error starting ";
103 report_string_.append(app_name +
" ");
104 report_string_.append(
"for run number ");
105 report_string_.append(boost::lexical_cast<std::string>(
id.run()));
106 report_string_.append(
", timeout ");
107 report_string_.append(boost::lexical_cast<std::string>(timeout));
108 report_string_.append(
", timestamp ");
109 report_string_.append(boost::lexical_cast<std::string>(timestamp));
110 report_string_.append(
".");
113 return external_request_status_;
119 external_request_status_ = fragment_receiver_ptr_->stop(timeout, timestamp);
120 if (!external_request_status_)
122 report_string_ =
"Error stopping ";
123 report_string_.append(app_name +
".");
126 if (fragment_input_thread_.joinable())
128 TLOG(TLVL_DEBUG + 32) <<
"Joining fragment input (Generator) thread";
129 fragment_input_thread_.join();
131 if (fragment_output_thread_.joinable())
133 TLOG(TLVL_DEBUG + 32) <<
"Joining fragment output (Sender) thread";
134 fragment_output_thread_.join();
137 TLOG(TLVL_DEBUG + 32) <<
"BoardReader Stopped. Getting run statistics";
138 int number_of_fragments_sent = -1;
139 if (fragment_receiver_ptr_)
141 number_of_fragments_sent = fragment_receiver_ptr_->GetFragmentsProcessed();
143 TLOG(TLVL_DEBUG + 32) <<
"do_stop(uint64_t, uint64_t): "
144 <<
"Number of fragments sent = " << number_of_fragments_sent
147 return external_request_status_;
153 external_request_status_ = fragment_receiver_ptr_->pause(timeout, timestamp);
154 if (!external_request_status_)
156 report_string_ =
"Error pausing ";
157 report_string_.append(app_name +
".");
160 if (fragment_input_thread_.joinable()) fragment_input_thread_.join();
161 if (fragment_output_thread_.joinable()) fragment_output_thread_.join();
162 int number_of_fragments_sent = fragment_receiver_ptr_->GetFragmentsProcessed();
163 TLOG(TLVL_DEBUG + 32) <<
"do_pause(uint64_t, uint64_t): "
164 <<
"Number of fragments sent = " << number_of_fragments_sent
167 return external_request_status_;
177 external_request_status_ =
true;
179 boost::thread::attributes attrs;
180 attrs.set_stack_size(4096 * 2000);
185 snprintf(tname,
sizeof(tname) - 1,
"%d-FragOutput", my_rank);
186 tname[
sizeof(tname) - 1] =
'\0';
187 auto handle = fragment_output_thread_.native_handle();
188 pthread_setname_np(handle, tname);
191 snprintf(tname,
sizeof(tname) - 1,
"%d-FragInput", my_rank);
192 tname[
sizeof(tname) - 1] =
'\0';
193 handle = fragment_input_thread_.native_handle();
194 pthread_setname_np(handle, tname);
196 catch (
const boost::exception& e)
198 std::stringstream exception_string;
199 exception_string <<
"Caught boost::exception starting Fragment Processing threads: " << boost::diagnostic_information(e) <<
", errno=" << errno;
201 ExceptionHandler(ExceptionHandlerRethrow::yes, exception_string.str());
204 auto start_wait = std::chrono::steady_clock::now();
205 while (!fragment_receiver_ptr_->GetSenderThreadActive() || !fragment_receiver_ptr_->GetReceiverThreadActive())
207 if (TimeUtils::GetElapsedTimeMicroseconds(start_wait) > timeout * 1000000)
209 TLOG(TLVL_ERROR) <<
"Timeout occurred waiting for BoardReaderCore threads to start. Timeout = " << timeout <<
" s, Time waited = " << TimeUtils::GetElapsedTime(start_wait) <<
" s,"
210 <<
" Receiver ready: " << std::boolalpha << fragment_receiver_ptr_->GetReceiverThreadActive() <<
", Sender ready: " << fragment_receiver_ptr_->GetSenderThreadActive();
211 external_request_status_ =
false;
218 if (external_request_status_)
220 external_request_status_ = fragment_receiver_ptr_->resume(timeout, timestamp);
222 if (!external_request_status_)
224 report_string_ =
"Error resuming ";
225 report_string_.append(app_name +
".");
227 return external_request_status_;
233 external_request_status_ = fragment_receiver_ptr_->shutdown(timeout);
236 if (fragment_input_thread_.joinable()) fragment_input_thread_.join();
237 if (fragment_output_thread_.joinable()) fragment_output_thread_.join();
238 if (!external_request_status_)
240 report_string_ =
"Error shutting down ";
241 report_string_.append(app_name +
".");
243 return external_request_status_;
249 external_request_status_ = fragment_receiver_ptr_->soft_initialize(pset, timeout, timestamp);
250 if (!external_request_status_)
252 report_string_ =
"Error soft-initializing ";
253 report_string_.append(app_name +
" ");
254 report_string_.append(
"with ParameterSet = \"" + pset.to_string() +
"\".");
256 return external_request_status_;
261 external_request_status_ = fragment_receiver_ptr_->reinitialize(pset, timeout, timestamp);
262 if (!external_request_status_)
264 report_string_ =
"Error reinitializing ";
265 report_string_.append(app_name +
" ");
266 report_string_.append(
"with ParameterSet = \"" + pset.to_string() +
"\".");
268 return external_request_status_;
273 TLOG(TLVL_DEBUG + 32) <<
"Booted state entry action called.";
279 fragment_receiver_ptr_.reset(
nullptr);
284 external_request_status_ = fragment_receiver_ptr_->metaCommand(command, arg);
285 if (!external_request_status_)
287 report_string_ =
"Error running meta-command on ";
288 report_string_.append(app_name +
" ");
289 report_string_.append(
"with command = \"" + command +
"\", arg = \"" + arg +
"\".");
291 return external_request_status_;
296 std::string resultString;
299 if (which ==
"transition_status")
301 if (report_string_.length() > 0) {
return report_string_; }
315 if (fragment_receiver_ptr_ !=
nullptr)
317 resultString.append(fragment_receiver_ptr_->report(which));
321 resultString.append(
"This BoardReader has not yet been initialized and ");
322 resultString.append(
"therefore can not provide reporting.");
bool do_soft_initialize(fhicl::ParameterSet const &pset, uint64_t timeout, uint64_t timestamp) override
Soft-Initialize the BoardReaderCore.
bool do_resume(uint64_t timeout, uint64_t timestamp) override
Resume the BoardReaderCore.
bool do_stop(uint64_t timeout, uint64_t timestamp) override
Stop the BoardReaderCore.
bool do_meta_command(std::string const &command, std::string const &arg) override
Perform a user-defined command (passed to CommandableFragmentGenerator)
bool do_shutdown(uint64_t timeout) override
Shutdown the BoardReaderCore.
bool do_reinitialize(fhicl::ParameterSet const &pset, uint64_t timeout, uint64_t timestamp) override
Reinitialize the BoardReaderCore.
std::string report(std::string const &which) const override
If which is "transition_status", report the status of the last transition. Otherwise pass through to ...
void send_fragments()
Main working loop of the BoardReaderCore, pt. 2.
BoardReaderApp()
BoardReaderApp Constructor.
void BootedEnter() override
Action taken upon entering the "Booted" state.
void receive_fragments()
Main working loop of the BoardReaderCore.
bool do_start(art::RunID id, uint64_t timeout, uint64_t timestamp) override
Start the BoardReaderCore.
bool do_initialize(fhicl::ParameterSet const &pset, uint64_t timeout, uint64_t timestamp) override
Initialize the BoardReaderCore.
bool do_pause(uint64_t timeout, uint64_t timestamp) override
Pause the BoardReaderCore.