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
00073 int source_rank() const { return physical_transfer_->source_rank(); }
00074 int destination_rank() const { return physical_transfer_->destination_rank(); }
00075
00076
00077 private:
00078
00079 bool pass(const artdaq::Fragment& ) const;
00080
00081 std::unique_ptr<TransferInterface> physical_transfer_;
00082 size_t nth_;
00083 size_t offset_;
00084 };
00085
00086 NthEventTransfer::NthEventTransfer(fhicl::ParameterSet const& pset, artdaq::TransferInterface::Role role) :
00087 TransferInterface(pset, role)
00088 , nth_(pset.get<size_t>("nth")),
00089 offset_(pset.get<size_t>("offset",0))
00090 {
00091 if (pset.has_key("source_rank") || pset.has_key("destination_rank")) {
00092 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";
00093 }
00094
00095
00096 if (offset_ >= nth_) {
00097 throw cet::exception("NthEvent") << "Offset value of " << offset_ <<
00098 " must not be larger than the modulus value of " << nth_;
00099 }
00100
00101 if(nth_ == 0)
00102 {
00103 mf::LogWarning("NthEventTransfer") << "0 was passed as the nth parameter to NthEventTransfer. Will change to 1 (0 is undefined behavior)";
00104 nth_ = 1;
00105 }
00106
00107 physical_transfer_ = MakeTransferPlugin(pset, "physical_transfer_plugin", role);
00108 }
00109
00110
00111 TransferInterface::CopyStatus
00112 NthEventTransfer::copyFragment(artdaq::Fragment& fragment,
00113 size_t send_timeout_usec)
00114 {
00115
00116 if (!pass(fragment))
00117 {
00118
00119 return TransferInterface::CopyStatus::kSuccess;
00120 }
00121
00122
00123 return physical_transfer_->copyFragment(fragment, send_timeout_usec);
00124 }
00125
00126 TransferInterface::CopyStatus
00127 NthEventTransfer::moveFragment(artdaq::Fragment&& fragment,
00128 size_t send_timeout_usec)
00129 {
00130 if (!pass(fragment))
00131 {
00132
00133 return TransferInterface::CopyStatus::kSuccess;
00134 }
00135
00136
00137 return physical_transfer_->moveFragment(std::move(fragment), send_timeout_usec);
00138 }
00139
00140 bool
00141 NthEventTransfer::pass(const artdaq::Fragment& fragment) const
00142 {
00143 bool passed = false;
00144
00145 if (fragment.type() == artdaq::Fragment::DataFragmentType) {
00146 passed = (fragment.sequenceID() + nth_ - offset_) % nth_ == 0 ? true: false;
00147 } else {
00148 passed = true;
00149 }
00150
00151 return passed;
00152 }
00153 }
00154
00155 DEFINE_ARTDAQ_TRANSFER(artdaq::NthEventTransfer)
00156
00157
00158
00159