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
00103 std::map<int, FragmentStoreElement> fragment_store_;
00104
00105 std::mutex input_cv_mutex_;
00106 std::condition_variable input_cv_;
00107 std::mutex output_cv_mutex_;
00108 std::condition_variable output_cv_;
00109
00110 detail::FragCounter recv_frag_count_;
00111 detail::FragCounter recv_frag_size_;
00112 detail::FragCounter recv_seq_count_;
00113 bool suppress_noisy_senders_;
00114 size_t suppression_threshold_;
00115
00116 size_t receive_timeout_;
00117 };
00118
00126 class artdaq::FragmentStoreElement
00127 {
00128 public:
00132 FragmentStoreElement()
00133 : frags_()
00134 , empty_(true)
00135 , eod_marker_(-1)
00136 {
00137 std::cout << "FragmentStoreElement CONSTRUCTOR" << std::endl;
00138 }
00139
00144 bool empty() const
00145 {
00146 return empty_;
00147 }
00148
00153 void emplace_front(FragmentPtr&& frag)
00154 {
00155 std::unique_lock<std::mutex> lk(mutex_);
00156 frags_.emplace_front(std::move(frag));
00157 empty_ = false;
00158 }
00159
00164 void emplace_back(FragmentPtr&& frag)
00165 {
00166 std::unique_lock<std::mutex> lk(mutex_);
00167 frags_.emplace_back(std::move(frag));
00168 empty_ = false;
00169 }
00170
00175 FragmentPtr front()
00176 {
00177 std::unique_lock<std::mutex> lk(mutex_);
00178 auto current_fragment = std::move(frags_.front());
00179 frags_.pop_front();
00180 empty_ = frags_.size() == 0;
00181 return std::move(current_fragment);
00182 }
00183
00188 void SetEndOfData(size_t eod) { eod_marker_ = eod; }
00193 size_t GetEndOfData() const { return eod_marker_; }
00194
00195 private:
00196 mutable std::mutex mutex_;
00197 FragmentPtrs frags_;
00198 std::atomic<bool> empty_;
00199 size_t eod_marker_;
00200 };
00201
00202 inline
00203 size_t
00204 artdaq::FragmentReceiverManager::
00205 count() const
00206 {
00207 return recv_frag_count_.count();
00208 }
00209
00210 inline
00211 size_t
00212 artdaq::FragmentReceiverManager::
00213 slotCount(size_t rank) const
00214 {
00215 return recv_frag_count_.slotCount(rank);
00216 }
00217
00218 inline
00219 size_t
00220 artdaq::FragmentReceiverManager::
00221 byteCount() const
00222 {
00223 return recv_frag_size_.count();
00224 }
00225 #endif //ARTDAQ_DAQRATE_DATATRANSFERMANAGER_HH