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 <thread>
00016 #include <chrono>
00017 #include <array>
00018 #include <list>
00019
00020 #include "fhiclcpp/fwd.h"
00021 #include "fhiclcpp/ParameterSet.h"
00022 #include "artdaq-core/Data/Fragment.hh"
00023 #include "artdaq-core/Generators/FragmentGenerator.hh"
00024 #include "artdaq-utilities/Plugins/MetricManager.hh"
00025 #include "artdaq/DAQrate/detail/RequestMessage.hh"
00026 #include "artdaq/DAQdata/Globals.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
00142 bool getNext(FragmentPtrs& output) override final;
00143
00149 bool applyRequests(FragmentPtrs& output);
00150
00154 void setupRequestListener();
00155
00163 bool sendEmptyFragment(FragmentPtrs& frags, size_t sequenceId, std::string desc);
00164
00170 void sendEmptyFragments(FragmentPtrs& frags);
00171
00175 void startDataThread();
00176
00180 void startMonitoringThread();
00181
00185 void startRequestReceiverThread();
00186
00191 void getDataLoop();
00192
00197 bool dataBufferIsTooLarge();
00198
00202 void getDataBufferStats();
00203
00209 void checkDataBuffer();
00210
00214 void getMonitoringDataLoop();
00215
00219 void receiveRequestsLoop();
00220
00225 std::vector<Fragment::fragment_id_t> fragmentIDs() override
00226 {
00227 return fragment_ids_;
00228 }
00229
00230
00231
00232
00233
00248 void StartCmd(int run, uint64_t timeout, uint64_t timestamp);
00249
00259 void StopCmd(uint64_t timeout, uint64_t timestamp);
00260
00270 void PauseCmd(uint64_t timeout, uint64_t timestamp);
00271
00280 void ResumeCmd(uint64_t timeout, uint64_t timestamp);
00281
00292 std::string ReportCmd(std::string const& which = "");
00293
00298 virtual std::string metricsReportingInstanceName() const
00299 {
00300 return instance_name_for_metrics_;
00301 }
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00323 bool exception() const { return exception_.load(); }
00324
00325 protected:
00326
00327
00328
00329
00330
00331
00332
00333
00334
00339 int run_number() const { return run_number_; }
00344 int subrun_number() const { return subrun_number_; }
00349 uint64_t timeout() const { return timeout_; }
00354 uint64_t timestamp() const { return timestamp_; }
00355
00360 bool should_stop() const { return should_stop_.load(); }
00361
00366 bool check_stop();
00367
00372 int board_id() const { return board_id_; }
00373
00379 int fragment_id() const;
00380
00385 size_t ev_counter() const { return ev_counter_.load(); }
00386
00393 size_t ev_counter_inc(size_t step = 1, bool force = false);
00394
00399 void set_exception(bool exception) { exception_.store(exception); }
00400
00405 void metricsReportingInstanceName(std::string const& name)
00406 {
00407 instance_name_for_metrics_ = name;
00408 }
00409
00414 std::string printMode_();
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424 std::mutex mutex_;
00425
00426 private:
00427
00428
00429 int request_port_;
00430 std::string request_addr_;
00431
00432
00433 struct sockaddr_in si_data_;
00434 int request_socket_;
00435 std::map<Fragment::sequence_id_t, Fragment::timestamp_t> requests_;
00436 std::atomic<bool> request_stop_requested_;
00437 std::chrono::steady_clock::time_point request_stop_timeout_;
00438 std::atomic<bool> request_received_;
00439 size_t end_of_run_timeout_ms_;
00440 std::mutex request_mutex_;
00441 std::thread requestThread_;
00442
00443 RequestMode mode_;
00444 Fragment::timestamp_t windowOffset_;
00445 Fragment::timestamp_t windowWidth_;
00446 Fragment::timestamp_t staleTimeout_;
00447 Fragment::type_t expectedType_;
00448 size_t maxFragmentCount_;
00449 bool uniqueWindows_;
00450 std::chrono::steady_clock::time_point last_window_send_time_;
00451 size_t missing_request_window_timeout_us_;
00452 size_t window_close_timeout_us_;
00453
00454 bool useDataThread_;
00455 size_t sleep_on_no_data_us_;
00456 std::atomic<bool> data_thread_running_;
00457 std::thread dataThread_;
00458
00459 std::condition_variable requestCondition_;
00460 std::condition_variable dataCondition_;
00461 std::atomic<int> dataBufferDepthFragments_;
00462 std::atomic<size_t> dataBufferDepthBytes_;
00463 int maxDataBufferDepthFragments_;
00464 size_t maxDataBufferDepthBytes_;
00465
00466 bool useMonitoringThread_;
00467 std::thread monitoringThread_;
00468 int64_t monitoringInterval_;
00469 std::chrono::steady_clock::time_point lastMonitoringCall_;
00470 bool isHardwareOK_;
00471
00472 FragmentPtrs dataBuffer_;
00473 FragmentPtrs newDataBuffer_;
00474 std::mutex dataBufferMutex_;
00475
00476 std::vector<artdaq::Fragment::fragment_id_t> fragment_ids_;
00477
00478
00479
00480
00481 int run_number_, subrun_number_;
00482
00483
00484
00485
00486 uint64_t timeout_;
00487
00488
00489
00490
00491
00492
00493
00494 uint64_t timestamp_;
00495
00496 std::atomic<bool> should_stop_, exception_, force_stop_;
00497 std::string latest_exception_report_;
00498 std::atomic<size_t> ev_counter_;
00499
00500 int board_id_;
00501 std::string instance_name_for_metrics_;
00502
00503
00504
00505
00506 int sleep_on_stop_us_;
00507
00508
00509
00510
00511
00512 virtual bool getNext_(FragmentPtrs& output) = 0;
00513
00514
00515
00516
00517
00518 virtual bool checkHWStatus_();
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530 virtual void start() = 0;
00531
00532
00533
00534 virtual void stopNoMutex() = 0;
00535
00536
00537
00538
00539
00540 virtual void stop() = 0;
00541
00542
00543
00544 virtual void pauseNoMutex();
00545
00546
00547
00548
00549 virtual void pause();
00550
00551
00552
00553
00554
00555 virtual void resume();
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565 virtual std::string report();
00566
00567 virtual std::string reportSpecific(std::string const&);
00568 };
00569 }
00570
00571 #endif