00001 #ifndef artdaq_Application_CommandableFragmentGenerator_hh
00002 #define artdaq_Application_CommandableFragmentGenerator_hh
00003
00004
00005 #include <arpa/inet.h>
00006 #include <netinet/in.h>
00007 #include <sys/types.h>
00008 #include <sys/socket.h>
00009 #include <unistd.h>
00010
00011 #include <atomic>
00012 #include <condition_variable>
00013 #include <mutex>
00014 #include <queue>
00015 #include <chrono>
00016 #include <array>
00017 #include <list>
00018
00019 #include "fhiclcpp/fwd.h"
00020 #include "fhiclcpp/ParameterSet.h"
00021
00022 #include "artdaq/DAQdata/Globals.hh"
00023 #include "artdaq-core/Data/Fragment.hh"
00024 #include "artdaq-core/Generators/FragmentGenerator.hh"
00025 #include "artdaq-utilities/Plugins/MetricManager.hh"
00026 #include "artdaq/DAQrate/RequestReceiver.hh"
00027
00028 namespace artdaq
00029 {
00033 enum class RequestMode
00034 {
00035 Single,
00036 Buffer,
00037 Window,
00038 Ignored
00039 };
00040
00083 class CommandableFragmentGenerator : public FragmentGenerator
00084 {
00085 public:
00086
00092 CommandableFragmentGenerator();
00093
00128 explicit CommandableFragmentGenerator(const fhicl::ParameterSet& ps);
00129
00135 virtual ~CommandableFragmentGenerator();
00136
00137
00144 void joinThreads();
00145
00151 bool getNext(FragmentPtrs& output) override final;
00152
00153
00159 void applyRequestsIgnoredMode(artdaq::FragmentPtrs& frags);
00160
00166 void applyRequestsSingleMode(artdaq::FragmentPtrs& frags);
00167
00173 void applyRequestsBufferMode(artdaq::FragmentPtrs& frags);
00174
00180 void applyRequestsWindowMode(artdaq::FragmentPtrs& frags);
00181
00187 bool applyRequests(FragmentPtrs& output);
00188
00196 bool sendEmptyFragment(FragmentPtrs& frags, size_t sequenceId, std::string desc);
00197
00204 void sendEmptyFragments(FragmentPtrs& frags, std::map<Fragment::sequence_id_t, Fragment::timestamp_t>& requests);
00205
00209 void startDataThread();
00210
00214 void startMonitoringThread();
00215
00220 void getDataLoop();
00221
00226 bool waitForDataBufferReady();
00227
00232 bool dataBufferIsTooLarge();
00233
00237 void getDataBufferStats();
00238
00244 void checkDataBuffer();
00245
00249 void getMonitoringDataLoop();
00250
00255 std::vector<Fragment::fragment_id_t> fragmentIDs() override
00256 {
00257 return fragment_ids_;
00258 }
00259
00260
00261
00262
00263
00278 void StartCmd(int run, uint64_t timeout, uint64_t timestamp);
00279
00289 void StopCmd(uint64_t timeout, uint64_t timestamp);
00290
00300 void PauseCmd(uint64_t timeout, uint64_t timestamp);
00301
00310 void ResumeCmd(uint64_t timeout, uint64_t timestamp);
00311
00322 std::string ReportCmd(std::string const& which = "");
00323
00328 virtual std::string metricsReportingInstanceName() const
00329 {
00330 return instance_name_for_metrics_;
00331 }
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00353 bool exception() const { return exception_.load(); }
00354
00355
00362 virtual bool metaCommand(std::string const& command, std::string const& arg);
00363
00364 protected:
00365
00366
00367
00368
00369
00370
00371
00372
00373
00378 int run_number() const { return run_number_; }
00383 int subrun_number() const { return subrun_number_; }
00388 uint64_t timeout() const { return timeout_; }
00393 uint64_t timestamp() const { return timestamp_; }
00394
00399 bool should_stop() const { return should_stop_.load(); }
00400
00405 bool check_stop();
00406
00411 int board_id() const { return board_id_; }
00412
00418 int fragment_id() const;
00419
00424 size_t ev_counter() const { return ev_counter_.load(); }
00425
00432 size_t ev_counter_inc(size_t step = 1, bool force = false);
00433
00438 void set_exception(bool exception) { exception_.store(exception); }
00439
00444 void metricsReportingInstanceName(std::string const& name)
00445 {
00446 instance_name_for_metrics_ = name;
00447 }
00448
00453 std::string printMode_();
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463 std::mutex mutex_;
00464
00465 private:
00466
00467
00468
00469
00470 struct sockaddr_in si_data_;
00471 std::unique_ptr<RequestReceiver> requestReceiver_;
00472
00473 RequestMode mode_;
00474 Fragment::timestamp_t windowOffset_;
00475 Fragment::timestamp_t windowWidth_;
00476 Fragment::timestamp_t staleTimeout_;
00477 Fragment::type_t expectedType_;
00478 size_t maxFragmentCount_;
00479 bool uniqueWindows_;
00480 bool missing_request_;
00481 std::chrono::steady_clock::time_point missing_request_time_;
00482 std::chrono::steady_clock::time_point last_window_send_time_;
00483 bool last_window_send_time_set_;
00484 std::set<Fragment::sequence_id_t> windows_sent_ooo_;
00485 size_t missing_request_window_timeout_us_;
00486 size_t window_close_timeout_us_;
00487
00488 bool useDataThread_;
00489 size_t sleep_on_no_data_us_;
00490 std::atomic<bool> data_thread_running_;
00491 boost::thread dataThread_;
00492
00493 std::condition_variable dataCondition_;
00494 std::atomic<int> dataBufferDepthFragments_;
00495 std::atomic<size_t> dataBufferDepthBytes_;
00496 int maxDataBufferDepthFragments_;
00497 size_t maxDataBufferDepthBytes_;
00498
00499 bool useMonitoringThread_;
00500 boost::thread monitoringThread_;
00501 int64_t monitoringInterval_;
00502 std::chrono::steady_clock::time_point lastMonitoringCall_;
00503 bool isHardwareOK_;
00504
00505 FragmentPtrs dataBuffer_;
00506 FragmentPtrs newDataBuffer_;
00507 std::mutex dataBufferMutex_;
00508
00509 std::vector<artdaq::Fragment::fragment_id_t> fragment_ids_;
00510
00511
00512
00513
00514 int run_number_, subrun_number_;
00515
00516
00517
00518
00519 uint64_t timeout_;
00520
00521
00522
00523
00524
00525
00526
00527 uint64_t timestamp_;
00528
00529 std::atomic<bool> should_stop_, exception_, force_stop_;
00530 std::string latest_exception_report_;
00531 std::atomic<size_t> ev_counter_;
00532
00533 int board_id_;
00534 std::string instance_name_for_metrics_;
00535
00536
00537
00538
00539 int sleep_on_stop_us_;
00540
00541 protected:
00542
00543
00544
00545
00546
00547 virtual bool getNext_(FragmentPtrs& output) = 0;
00548
00549
00550
00551
00552
00553 virtual bool checkHWStatus_();
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565 virtual void start() = 0;
00566
00567
00568
00569 virtual void stopNoMutex() = 0;
00570
00571
00572
00573
00574
00575 virtual void stop() = 0;
00576
00577
00578
00579 virtual void pauseNoMutex();
00580
00581
00582
00583
00584 virtual void pause();
00585
00586
00587
00588
00589
00590 virtual void resume();
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600 virtual std::string report();
00601
00602 virtual std::string reportSpecific(std::string const&);
00603
00604 };
00605 }
00606
00607 #endif