00001 #ifndef ARTDAQ_DAQRATE_DATATRANSFERMANAGER_HH
00002 #define ARTDAQ_DAQRATE_DATATRANSFERMANAGER_HH
00003
00004 #include <map>
00005 #include <set>
00006 #include <memory>
00007 #include <thread>
00008 #include <condition_variable>
00009
00010 #include <fhiclcpp/fwd.h>
00011
00012 #include "artdaq-core/Data/Fragment.hh"
00013 #include "artdaq/TransferPlugins/TransferInterface.hh"
00014 #include "artdaq/DAQrate/detail/FragCounter.hh"
00015 #include "artdaq-utilities/Plugins/MetricManager.hh"
00016
00017 namespace artdaq
00018 {
00019 class DataReceiverManager;
00020 class FragmentStoreElement;
00021 }
00022
00028 class artdaq::DataReceiverManager
00029 {
00030 public:
00031
00046 explicit DataReceiverManager(const fhicl::ParameterSet& ps);
00047
00051 virtual ~DataReceiverManager();
00052
00059 FragmentPtr recvFragment(int& rank, size_t timeout_usec = 0);
00060
00065 size_t count() const;
00066
00072 size_t slotCount(size_t rank) const;
00073
00078 size_t byteCount() const;
00079
00083 void start_threads();
00084
00089 std::set<int> enabled_sources() const { return enabled_sources_; }
00090
00095 void suppress_source(int source);
00096
00100 void unsuppressAll();
00101
00109 void reject_fragment(int source_rank, FragmentPtr frag);
00110
00111 private:
00112 void runReceiver_(int);
00113
00114 bool fragments_ready_() const;
00115
00116 int get_next_source_() const;
00117
00118 std::atomic<bool> stop_requested_;
00119
00120 std::map<int, std::thread> source_threads_;
00121 std::map<int, std::unique_ptr<TransferInterface>> source_plugins_;
00122 std::set<int> enabled_sources_;
00123 std::set<int> suppressed_sources_;
00124
00125 std::map<int, FragmentStoreElement> fragment_store_;
00126
00127 std::mutex input_cv_mutex_;
00128 std::condition_variable input_cv_;
00129 std::mutex output_cv_mutex_;
00130 std::condition_variable output_cv_;
00131
00132 detail::FragCounter recv_frag_count_;
00133 detail::FragCounter recv_frag_size_;
00134 detail::FragCounter recv_seq_count_;
00135 bool suppress_noisy_senders_;
00136 size_t suppression_threshold_;
00137
00138 size_t receive_timeout_;
00139 };
00140
00148 class artdaq::FragmentStoreElement
00149 {
00150 public:
00154 FragmentStoreElement() : frags_()
00155 , empty_(true)
00156 {
00157 std::cout << "FragmentStoreElement CONSTRUCTOR" << std::endl;
00158 }
00159
00164 bool empty() const
00165 {
00166 return empty_;
00167 }
00168
00173 void emplace_front(FragmentPtr&& frag)
00174 {
00175 std::unique_lock<std::mutex> lk(mutex_);
00176 frags_.emplace_front(std::move(frag));
00177 empty_ = false;
00178 }
00179
00184 void emplace_back(FragmentPtr&& frag)
00185 {
00186 std::unique_lock<std::mutex> lk(mutex_);
00187 frags_.emplace_back(std::move(frag));
00188 empty_ = false;
00189 }
00190
00195 FragmentPtr front()
00196 {
00197 std::unique_lock<std::mutex> lk(mutex_);
00198 auto current_fragment = std::move(frags_.front());
00199 frags_.pop_front();
00200 empty_ = frags_.size() == 0;
00201 return std::move(current_fragment);
00202 }
00203
00204 private:
00205 mutable std::mutex mutex_;
00206 FragmentPtrs frags_;
00207 std::atomic<bool> empty_;
00208 };
00209
00210 inline
00211 size_t
00212 artdaq::DataReceiverManager::
00213 count() const
00214 {
00215 return recv_frag_count_.count();
00216 }
00217
00218 inline
00219 size_t
00220 artdaq::DataReceiverManager::
00221 slotCount(size_t rank) const
00222 {
00223 return recv_frag_count_.slotCount(rank);
00224 }
00225
00226 inline
00227 size_t
00228 artdaq::DataReceiverManager::
00229 byteCount() const
00230 {
00231 return recv_frag_size_.count();
00232 }
00233 #endif //ARTDAQ_DAQRATE_DATATRANSFERMANAGER_HH