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 copyFragment(artdaq::Fragment& fragment, size_t send_timeout_usec) override;
00048
00055 TransferInterface::CopyStatus
00056 moveFragment(artdaq::Fragment&& fragment) override;
00057
00064 int receiveFragment(artdaq::Fragment& fragment,
00065 size_t receiveTimeout) override
00066 {
00067
00068 return physical_transfer_->receiveFragment(fragment, receiveTimeout);
00069 }
00070
00077 int receiveFragmentHeader(detail::RawFragmentHeader& header, size_t receiveTimeout) override
00078 {
00079 return physical_transfer_->receiveFragmentHeader(header, receiveTimeout);
00080 }
00081
00088 int receiveFragmentData(RawDataType* destination, size_t wordCount) override
00089 {
00090 return physical_transfer_->receiveFragmentData(destination, wordCount);
00091 }
00092
00097 int source_rank() const override { return physical_transfer_->source_rank(); }
00098
00103 int destination_rank() const override { return physical_transfer_->destination_rank(); }
00104
00105
00106 private:
00107
00108 bool pass(const artdaq::Fragment&) const;
00109
00110 std::unique_ptr<TransferInterface> physical_transfer_;
00111 size_t nth_;
00112 size_t offset_;
00113 };
00114
00115 NthEventTransfer::NthEventTransfer(fhicl::ParameterSet const& pset, artdaq::TransferInterface::Role role) :
00116 TransferInterface(pset, role)
00117 , nth_(pset.get<size_t>("nth")),
00118 offset_(pset.get<size_t>("offset", 0))
00119 {
00120 if (pset.has_key("source_rank") || pset.has_key("destination_rank")) {
00121 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";
00122 }
00123
00124
00125 if (offset_ >= nth_) {
00126 throw cet::exception("NthEvent") << "Offset value of " << offset_ <<
00127 " must not be larger than the modulus value of " << nth_;
00128 }
00129
00130 if (nth_ == 0)
00131 {
00132 mf::LogWarning("NthEventTransfer") << "0 was passed as the nth parameter to NthEventTransfer. Will change to 1 (0 is undefined behavior)";
00133 nth_ = 1;
00134 }
00135
00136 physical_transfer_ = MakeTransferPlugin(pset, "physical_transfer_plugin", role);
00137 }
00138
00139
00140 TransferInterface::CopyStatus
00141 NthEventTransfer::copyFragment(artdaq::Fragment& fragment,
00142 size_t send_timeout_usec)
00143 {
00144
00145 if (!pass(fragment))
00146 {
00147
00148 return TransferInterface::CopyStatus::kSuccess;
00149 }
00150
00151
00152 return physical_transfer_->copyFragment(fragment, send_timeout_usec);
00153 }
00154
00155 TransferInterface::CopyStatus
00156 NthEventTransfer::moveFragment(artdaq::Fragment&& fragment)
00157 {
00158 if (!pass(fragment))
00159 {
00160
00161 return TransferInterface::CopyStatus::kSuccess;
00162 }
00163
00164
00165 return physical_transfer_->moveFragment(std::move(fragment));
00166 }
00167
00168 bool
00169 NthEventTransfer::pass(const artdaq::Fragment& fragment) const
00170 {
00171 bool passed = false;
00172
00173 if (fragment.type() == artdaq::Fragment::DataFragmentType) {
00174 passed = (fragment.sequenceID() + nth_ - offset_) % nth_ == 0 ? true : false;
00175 }
00176 else {
00177 passed = true;
00178 }
00179
00180 return passed;
00181 }
00182 }
00183
00184 DEFINE_ARTDAQ_TRANSFER(artdaq::NthEventTransfer)
00185
00186
00187
00188