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