00001 #ifndef artdaq_ArtModules_TransferInterface_hh
00002 #define artdaq_ArtModules_TransferInterface_hh
00003
00004 #include "artdaq/DAQdata/Globals.hh"
00005 #include "artdaq-core/Data/Fragment.hh"
00006 #include "fhiclcpp/ParameterSet.h"
00007 #include "cetlib/compiler_macros.h"
00008
00009 #include <limits>
00010 #include <iostream>
00011 #include <sstream>
00012
00013 namespace artdaq
00014 {
00018 class TransferInterface
00019 {
00020 public:
00021 struct Config
00022 {
00023 fhicl::Atom<int> source_rank{ fhicl::Name{"source_rank"}, fhicl::Comment{"The rank that data is coming from"}, my_rank };
00024 fhicl::Atom<int> destination_rank{ fhicl::Name{ "destination_rank"}, fhicl::Comment{"The rank that data is going to"}, my_rank };
00025 fhicl::Atom<std::string> unique_label{ fhicl::Name{"unique_label"}, fhicl::Comment{"A label that uniquely identifies the TransferInterface instance"},"transfer_between_[source_rank]_and_[destination_rank]" };
00026 fhicl::Atom<size_t> buffer_count{ fhicl::Name{"buffer_count"}, fhicl::Comment{"How many Fragments can the TransferInterface handle simultaneously"},10 };
00027 fhicl::Atom<size_t> max_fragment_size{ fhicl::Name{"max_fragment_size_words" }, fhicl::Comment{ "The maximum Fragment size expected.May be used for static memory allocation, and will cause errors if larger Fragments are sent." }, 1024 };
00028 fhicl::Atom<short> partition_number{ fhicl::Name{"partition_number"},fhicl::Comment{"Partition that this TransferInterface is a part of"}, 0 };
00029
00030 };
00031 #if MESSAGEFACILITY_HEX_VERSION >= 0x20103
00032 using Parameters = fhicl::WrappedTable<Config>;
00033 #endif
00034
00035 enum : int
00036 {
00037 DATA_END = -2222,
00038 RECV_TIMEOUT = -1111,
00039 RECV_SUCCESS = 0
00040 };
00041
00045 enum class Role
00046 {
00047 kSend,
00048 kReceive
00049 };
00050
00055 enum class CopyStatus
00056 {
00057 kSuccess,
00058 kTimeout,
00059 kErrorNotRequiringException
00060 };
00061
00062 static std::string CopyStatusToString(CopyStatus in)
00063 {
00064 switch (in)
00065 {
00066 case CopyStatus::kSuccess: return "Success";
00067 case CopyStatus::kTimeout: return "Timeout";
00068 case CopyStatus::kErrorNotRequiringException: return "Error";
00069 default: return "UNKNOWN";
00070 }
00071 return "SWITCHERROR";
00072 }
00073
00090 TransferInterface(const fhicl::ParameterSet& ps, Role role);
00091
00095 TransferInterface(const TransferInterface&) = delete;
00096
00101 TransferInterface& operator=(const TransferInterface&) = delete;
00102
00106 virtual ~TransferInterface() = default;
00107
00114 virtual int receiveFragment(artdaq::Fragment& fragment, size_t receiveTimeout);
00115
00122 virtual int receiveFragmentHeader(detail::RawFragmentHeader& header, size_t receiveTimeout) = 0;
00123
00133 virtual int receiveFragmentData(RawDataType* destination, size_t wordCount) = 0;
00134
00141 virtual CopyStatus copyFragment(artdaq::Fragment& fragment, size_t send_timeout_usec) = 0;
00142
00143
00149 virtual CopyStatus moveFragment(artdaq::Fragment&& fragment) = 0;
00150
00155 std::string uniqueLabel() const { return unique_label_; }
00156
00161 virtual int source_rank() const { return source_rank_; }
00166 virtual int destination_rank() const { return destination_rank_; }
00167
00172 virtual bool isRunning() { return false; }
00173
00174
00175
00180 std::string GetTraceName() const { return unique_label_ + (role_ == Role::kSend ? "_SEND" : "_RECV"); }
00181 private:
00182 const Role role_;
00183
00184 const int source_rank_;
00185 const int destination_rank_;
00186 const std::string unique_label_;
00187
00188 protected:
00189 size_t buffer_count_;
00190 const size_t max_fragment_size_words_;
00191 const short partition_number_;
00192
00193 protected:
00198 Role role() const { return role_; }
00199 };
00200 }
00201
00202 #ifndef EXTERN_C_FUNC_DECLARE_START
00203 #define EXTERN_C_FUNC_DECLARE_START extern "C" {
00204 #endif
00205
00206 #define DEFINE_ARTDAQ_TRANSFER(klass) \
00207 EXTERN_C_FUNC_DECLARE_START \
00208 std::unique_ptr<artdaq::TransferInterface> make(fhicl::ParameterSet const & ps, \
00209 artdaq::TransferInterface::Role role) { \
00210 return std::unique_ptr<artdaq::TransferInterface>(new klass(ps, role)); \
00211 }}
00212
00213
00214 #endif
00215
00216
00217
00218