00001 #ifndef ARTDAQ_DAQRATE_DATATRANSFERMANAGER_HH
00002 #define ARTDAQ_DAQRATE_DATATRANSFERMANAGER_HH
00003
00004 #include <map>
00005 #include <set>
00006 #include <memory>
00007 #include <condition_variable>
00008
00009 #include "fhiclcpp/fwd.h"
00010
00011 #include "artdaq-core/Data/Fragment.hh"
00012 #include "artdaq/TransferPlugins/TransferInterface.hh"
00013 #include "artdaq/DAQrate/detail/FragCounter.hh"
00014 #include "artdaq-utilities/Plugins/MetricManager.hh"
00015
00016 namespace artdaq
00017 {
00018 class FragmentReceiverManager;
00019 class FragmentStoreElement;
00020 }
00021
00027 class artdaq::FragmentReceiverManager
00028 {
00029 public:
00030
00045 explicit FragmentReceiverManager(const fhicl::ParameterSet& ps);
00046
00050 virtual ~FragmentReceiverManager();
00051
00058 FragmentPtr recvFragment(int& rank, size_t timeout_usec = 0);
00059
00064 size_t count() const;
00065
00071 size_t slotCount(size_t rank) const;
00072
00077 size_t byteCount() const;
00078
00082 void start_threads();
00083
00088 std::set<int> enabled_sources() const { return enabled_sources_; }
00089
00090 private:
00091 void runReceiver_(int);
00092
00093 bool fragments_ready_() const;
00094
00095 int get_next_source_() const;
00096
00097 std::atomic<bool> stop_requested_;
00098
00099 std::map<int, boost::thread> source_threads_;
00100 std::map<int, std::unique_ptr<TransferInterface>> source_plugins_;
00101 std::set<int> enabled_sources_;
00102 std::set<int> running_sources_;
00103
00104 std::map<int, FragmentStoreElement> fragment_store_;
00105
00106 std::mutex input_cv_mutex_;
00107 std::condition_variable input_cv_;
00108 std::mutex output_cv_mutex_;
00109 std::condition_variable output_cv_;
00110
00111 detail::FragCounter recv_frag_count_;
00112 detail::FragCounter recv_frag_size_;
00113 detail::FragCounter recv_seq_count_;
00114 bool suppress_noisy_senders_;
00115 size_t suppression_threshold_;
00116
00117 size_t receive_timeout_;
00118 mutable int last_source_;
00119 };
00120
00128 class artdaq::FragmentStoreElement
00129 {
00130 public:
00134 FragmentStoreElement()
00135 : frags_()
00136 , empty_(true)
00137 , eod_marker_(-1)
00138 {
00139 std::cout << "FragmentStoreElement CONSTRUCTOR" << std::endl;
00140 }
00141
00146 bool empty() const
00147 {
00148 return empty_;
00149 }
00150
00155 void emplace_front(FragmentPtr&& frag)
00156 {
00157 std::unique_lock<std::mutex> lk(mutex_);
00158 frags_.emplace_front(std::move(frag));
00159 empty_ = false;
00160 }
00161
00166 void emplace_back(FragmentPtr&& frag)
00167 {
00168 std::unique_lock<std::mutex> lk(mutex_);
00169 frags_.emplace_back(std::move(frag));
00170 empty_ = false;
00171 }
00172
00177 FragmentPtr front()
00178 {
00179 std::unique_lock<std::mutex> lk(mutex_);
00180 auto current_fragment = std::move(frags_.front());
00181 frags_.pop_front();
00182 empty_ = frags_.size() == 0;
00183 return current_fragment;
00184 }
00185
00190 void SetEndOfData(size_t eod) { eod_marker_ = eod; }
00195 size_t GetEndOfData() const { return eod_marker_; }
00196
00201 size_t size() const { return frags_.size(); }
00202
00203 private:
00204 mutable std::mutex mutex_;
00205 FragmentPtrs frags_;
00206 std::atomic<bool> empty_;
00207 size_t eod_marker_;
00208 };
00209
00210 inline
00211 size_t
00212 artdaq::FragmentReceiverManager::
00213 count() const
00214 {
00215 return recv_frag_count_.count();
00216 }
00217
00218 inline
00219 size_t
00220 artdaq::FragmentReceiverManager::
00221 slotCount(size_t rank) const
00222 {
00223 return recv_frag_count_.slotCount(rank);
00224 }
00225
00226 inline
00227 size_t
00228 artdaq::FragmentReceiverManager::
00229 byteCount() const
00230 {
00231 return recv_frag_size_.count();
00232 }
00233 #endif //ARTDAQ_DAQRATE_DATATRANSFERMANAGER_HH