$treeview $search $mathjax $extrastylesheet
artdaq_demo
v3_04_00
$projectbrief
|
$projectbrief
|
$searchbox |
00001 #include "artdaq/TransferPlugins/TransferInterface.hh" 00002 #include "artdaq/TransferPlugins/MakeTransferPlugin.hh" 00003 #include "artdaq-core/Data/Fragment.hh" 00004 #include "artdaq-core/Utilities/ExceptionHandler.hh" 00005 #include "cetlib/BasicPluginFactory.h" 00006 00007 #include "messagefacility/MessageLogger/MessageLogger.h" 00008 #include "fhiclcpp/ParameterSet.h" 00009 00010 #include <boost/tokenizer.hpp> 00011 00012 #include <sys/shm.h> 00013 #include <memory> 00014 #include <iostream> 00015 #include <string> 00016 #include <limits> 00017 #include <sstream> 00018 00022 namespace artdaq 00023 { 00028 class NthEventTransfer : public TransferInterface 00029 { 00030 public: 00038 NthEventTransfer(fhicl::ParameterSet const& ps, artdaq::TransferInterface::Role role); 00039 00046 TransferInterface::CopyStatus 00047 transfer_fragment_min_blocking_mode(artdaq::Fragment const& fragment, size_t send_timeout_usec) override; 00048 00054 TransferInterface::CopyStatus 00055 transfer_fragment_reliable_mode(artdaq::Fragment&& fragment) override; 00056 00063 int receiveFragment(artdaq::Fragment& fragment, 00064 size_t receiveTimeout) override 00065 { 00066 // nth-event discarding is done at the send side. Pass receive calls through to underlying transfer 00067 return physical_transfer_->receiveFragment(fragment, receiveTimeout); 00068 } 00069 00076 int receiveFragmentHeader(detail::RawFragmentHeader& header, size_t receiveTimeout) override 00077 { 00078 return physical_transfer_->receiveFragmentHeader(header, receiveTimeout); 00079 } 00080 00087 int receiveFragmentData(RawDataType* destination, size_t wordCount) override 00088 { 00089 return physical_transfer_->receiveFragmentData(destination, wordCount); 00090 } 00091 00096 int source_rank() const override { return physical_transfer_->source_rank(); } 00097 00102 int destination_rank() const override { return physical_transfer_->destination_rank(); } 00103 00104 00109 bool isRunning() override { return physical_transfer_->isRunning(); } 00110 00115 void flush_buffers() override { physical_transfer_->flush_buffers(); } 00116 00117 private: 00118 00119 bool pass(const artdaq::Fragment&) const; 00120 00121 std::unique_ptr<TransferInterface> physical_transfer_; 00122 size_t nth_; 00123 size_t offset_; 00124 }; 00125 00126 NthEventTransfer::NthEventTransfer(fhicl::ParameterSet const& pset, artdaq::TransferInterface::Role role) : 00127 TransferInterface(pset, role) 00128 , nth_(pset.get<size_t>("nth")), 00129 offset_(pset.get<size_t>("offset", 0)) 00130 { 00131 if (pset.has_key("source_rank") || pset.has_key("destination_rank")) { 00132 throw cet::exception("NthEvent") << "The parameters \"source_rank\" and \"destination_rank\" must be explicitly defined in the body of the physical_transfer_plugin table, and not outside of it"; 00133 } 00134 00135 00136 if (offset_ >= nth_) { 00137 throw cet::exception("NthEvent") << "Offset value of " << offset_ << 00138 " must not be larger than the modulus value of " << nth_; 00139 } 00140 00141 if (nth_ == 0) 00142 { 00143 mf::LogWarning("NthEventTransfer") << "0 was passed as the nth parameter to NthEventTransfer. Will change to 1 (0 is undefined behavior)"; 00144 nth_ = 1; 00145 } 00146 // Instantiate the TransferInterface plugin used to effect transfers 00147 physical_transfer_ = MakeTransferPlugin(pset, "physical_transfer_plugin", role); 00148 } 00149 00150 00151 TransferInterface::CopyStatus 00152 NthEventTransfer::transfer_fragment_min_blocking_mode(artdaq::Fragment const& fragment, 00153 size_t send_timeout_usec) 00154 { 00155 00156 if (!pass(fragment)) 00157 { 00158 // Do not transfer but return success. Fragment is discarded 00159 return TransferInterface::CopyStatus::kSuccess; 00160 } 00161 00162 // This is the nth Fragment, transfer 00163 return physical_transfer_->transfer_fragment_min_blocking_mode(fragment, send_timeout_usec); 00164 } 00165 00166 TransferInterface::CopyStatus 00167 NthEventTransfer::transfer_fragment_reliable_mode(artdaq::Fragment&& fragment) 00168 { 00169 if (!pass(fragment)) 00170 { 00171 // Do not transfer but return success. Fragment is discarded 00172 return TransferInterface::CopyStatus::kSuccess; 00173 } 00174 00175 // This is the nth Fragment, transfer 00176 return physical_transfer_->transfer_fragment_reliable_mode(std::move(fragment)); 00177 } 00178 00179 bool 00180 NthEventTransfer::pass(const artdaq::Fragment& fragment) const 00181 { 00182 bool passed = false; 00183 00184 if (fragment.type() == artdaq::Fragment::DataFragmentType) { 00185 passed = (fragment.sequenceID() + nth_ - offset_) % nth_ == 0 ? true : false; 00186 } 00187 else { 00188 passed = true; 00189 } 00190 00191 return passed; 00192 } 00193 } 00194 00195 DEFINE_ARTDAQ_TRANSFER(artdaq::NthEventTransfer) 00196 00197 // Local Variables: 00198 // mode: c++ 00199 // End: