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