.. _program_listing_file_register.hpp: Program Listing for File register.hpp ===================================== |exhale_lsh| :ref:`Return to documentation for file ` (``register.hpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #include "ers/ers.h" #include "config/config_register.hpp" #include "device.hpp" #include "regmap_manager.hpp" #include "register_device_controller.hpp" #include "hardware_monitor.hpp" #include #include #include "netio3-backend/EventLoop/AsioEventLoop.hpp" #include "netio3-backend/EventLoop/EpollEventLoop.hpp" #include #include "network/netio3_evloop.hpp" template class Register { public: explicit Register(const ConfigRegister & conf); private: RegmapManager m_regmap; Netio3EventLoop m_evt_loop; std::map> m_devices; std::map>> m_dev_registers; std::unique_ptr> hw_mon; void init_device(int dev_no); int get_or_init_primary(int dev_no); int get_or_init_secondary(int dev_no); int get_primary(int dev_no); }; template Register::Register(const ConfigRegister & c) : m_evt_loop{[&c]() { switch (c.network_mode) { case NetworkMode::tcp: return Netio3EventLoop{Netio3EventLoop::type_tag()}; case NetworkMode::rdma: return Netio3EventLoop{Netio3EventLoop::type_tag()}; default: throw std::runtime_error("Unknown network mode"); } }()} { for (const auto & dc : c.dconfs){ ERS_INFO(std::format("Opening device {}", dc.dev_no)); init_device(dc.dev_no); } unsigned int idx = 0; //to pass the single-device configuration to DeviceRegister for (const auto & dc : c.dconfs) { ERS_INFO(std::format("Device {}: send commands to fid {:#x}, get reply from {:#x}", dc.dev_no, dc.fid_cmd, dc.fid_reply)); int primary_no = get_or_init_primary(dc.dev_no); m_dev_registers.try_emplace(dc.dev_no, std::make_shared>(m_evt_loop, m_regmap, m_devices.at(dc.dev_no), m_devices.at(primary_no), c, idx)); ++idx; } if (c.enable_mon){ using device_pair = std::pair, std::shared_ptr>; std::vector all_devices; //make sure that that all requested devices are paired. for (const auto & dc : c.dconfs) { get_or_init_secondary(dc.dev_no); } //loop over all opened devices and match each primary with a secondary for (const auto &[dev_no, dev_ptr] : m_devices) { if (dev_ptr->is_primary()) { int secondary = get_or_init_secondary(dev_no); if (secondary != -1) { all_devices.push_back({m_devices.at(dev_no), m_devices.at(secondary)}); } else { all_devices.push_back({m_devices.at(dev_no), nullptr}); } } } ERS_INFO(std::format("Monitoring info for all devices on fid {:#x}", c.fid_mon)); hw_mon = std::make_unique>(all_devices, c); } m_evt_loop.start(); } template void Register::init_device(int dev_no) { m_devices.emplace(dev_no, std::make_unique(dev_no)); unsigned int lock_mask = 0; m_devices.at(dev_no)->open_device(lock_mask); } template int Register::get_or_init_primary(int dev_no) { int primary = get_primary(dev_no); if (dev_no != primary and m_devices.count(primary) == 0){ ERS_INFO(std::format("Opening required primary device {}", primary)); init_device(primary); } return primary; } template int Register::get_or_init_secondary(int dev_no) { int secondary = -1; if (m_devices.at(dev_no)->is_primary() and m_devices.at(dev_no)->get_card_endpoints() > 1){ secondary = dev_no + 1; if (m_devices.count(secondary) == 0){ ERS_INFO(std::format("Opening required secondary device (for monitoring) {}", secondary)); init_device(secondary); } } else if (not m_devices.at(dev_no)->is_primary()){ secondary = dev_no; } return secondary; } template int Register::get_primary(int dev_no) { int primary{-1}; if ( m_devices.at(dev_no)->is_primary() ){ primary = dev_no; } else { primary = dev_no - 1; } return primary; }