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