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
00110 bool isRunning() override { return physical_transfer_->isRunning(); }
00111
00112 private:
00113
00114 bool pass(const artdaq::Fragment&) const;
00115
00116 std::unique_ptr<TransferInterface> physical_transfer_;
00117 size_t nth_;
00118 size_t offset_;
00119 };
00120
00121 NthEventTransfer::NthEventTransfer(fhicl::ParameterSet const& pset, artdaq::TransferInterface::Role role) :
00122 TransferInterface(pset, role)
00123 , nth_(pset.get<size_t>("nth")),
00124 offset_(pset.get<size_t>("offset", 0))
00125 {
00126 if (pset.has_key("source_rank") || pset.has_key("destination_rank")) {
00127 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";
00128 }
00129
00130
00131 if (offset_ >= nth_) {
00132 throw cet::exception("NthEvent") << "Offset value of " << offset_ <<
00133 " must not be larger than the modulus value of " << nth_;
00134 }
00135
00136 if (nth_ == 0)
00137 {
00138 mf::LogWarning("NthEventTransfer") << "0 was passed as the nth parameter to NthEventTransfer. Will change to 1 (0 is undefined behavior)";
00139 nth_ = 1;
00140 }
00141
00142 physical_transfer_ = MakeTransferPlugin(pset, "physical_transfer_plugin", role);
00143 }
00144
00145
00146 TransferInterface::CopyStatus
00147 NthEventTransfer::copyFragment(artdaq::Fragment& fragment,
00148 size_t send_timeout_usec)
00149 {
00150
00151 if (!pass(fragment))
00152 {
00153
00154 return TransferInterface::CopyStatus::kSuccess;
00155 }
00156
00157
00158 return physical_transfer_->copyFragment(fragment, send_timeout_usec);
00159 }
00160
00161 TransferInterface::CopyStatus
00162 NthEventTransfer::moveFragment(artdaq::Fragment&& fragment)
00163 {
00164 if (!pass(fragment))
00165 {
00166
00167 return TransferInterface::CopyStatus::kSuccess;
00168 }
00169
00170
00171 return physical_transfer_->moveFragment(std::move(fragment));
00172 }
00173
00174 bool
00175 NthEventTransfer::pass(const artdaq::Fragment& fragment) const
00176 {
00177 bool passed = false;
00178
00179 if (fragment.type() == artdaq::Fragment::DataFragmentType) {
00180 passed = (fragment.sequenceID() + nth_ - offset_) % nth_ == 0 ? true : false;
00181 }
00182 else {
00183 passed = true;
00184 }
00185
00186 return passed;
00187 }
00188 }
00189
00190 DEFINE_ARTDAQ_TRANSFER(artdaq::NthEventTransfer)
00191
00192
00193
00194