1 // license:GPL-2.0+ 2 // copyright-holders:Couriersud 3 4 /// 5 /// \file queue.h 6 /// 7 8 #ifndef NL_CORE_QUEUE_H_ 9 #define NL_CORE_QUEUE_H_ 10 11 #include "queue.h" 12 13 #include "../nl_errstr.h" 14 #include "../nltypes.h" 15 16 #include "../plib/pstate.h" 17 #include "../plib/pstring.h" 18 #include "../plib/ptimed_queue.h" 19 20 #include <array> 21 #include <unordered_map> 22 #include <utility> 23 #include <vector> 24 #include <queue> 25 26 namespace netlist 27 { 28 namespace detail { 29 // Use timed_queue_heap to use stdc++ heap functions instead of linear processing. 30 // This slows down processing by about 35% on a Kaby Lake. 31 // template <class T, bool TS> 32 // using timed_queue = plib::timed_queue_heap<T, TS>; 33 34 template <class T, bool TS> 35 using timed_queue = plib::timed_queue_linear<T, TS>; 36 37 // ----------------------------------------------------------------------------- 38 // queue_t 39 // ----------------------------------------------------------------------------- 40 41 // We don't need a thread-safe queue currently. Parallel processing of 42 // solvers will update inputs after parallel processing. 43 44 template <typename O, bool TS> 45 class queue_base : 46 public timed_queue<plib::pqentry_t<netlist_time_ext, O *>, false>, 47 public plib::state_manager_t::callback_t 48 { 49 public: 50 using entry_t = plib::pqentry_t<netlist_time_ext, O *>; 51 using base_queue = timed_queue<entry_t, false>; 52 using id_delegate = plib::pmfp<std::size_t, const O *>; 53 using obj_delegate = plib::pmfp<O *, std::size_t>; 54 queue_base(std::size_t size,id_delegate get_id,obj_delegate get_obj)55 explicit queue_base(std::size_t size, id_delegate get_id, obj_delegate get_obj) 56 : timed_queue<plib::pqentry_t<netlist_time_ext, O *>, false>(size) 57 , m_qsize(0) 58 , m_times(size) 59 , m_net_ids(size) 60 , m_get_id(get_id) 61 , m_obj_by_id(get_obj) 62 { 63 } 64 65 ~queue_base() noexcept override = default; 66 67 queue_base(const queue_base &) = delete; 68 queue_base(queue_base &&) = delete; 69 queue_base &operator=(const queue_base &) = delete; 70 queue_base &operator=(queue_base &&) = delete; 71 72 protected: 73 register_state(plib::state_manager_t & manager,const pstring & module)74 void register_state(plib::state_manager_t &manager, const pstring &module) override 75 { 76 manager.save_item(this, m_qsize, module + "." + "qsize"); 77 manager.save_item(this, &m_times[0], module + "." + "times", m_times.size()); 78 manager.save_item(this, &m_net_ids[0], module + "." + "names", m_net_ids.size()); 79 } on_pre_save(plib::state_manager_t & manager)80 void on_pre_save(plib::state_manager_t &manager) override 81 { 82 plib::unused_var(manager); 83 m_qsize = this->size(); 84 for (std::size_t i = 0; i < m_qsize; i++ ) 85 { 86 m_times[i] = this->listptr()[i].exec_time().as_raw(); 87 m_net_ids[i] = m_get_id(this->listptr()[i].object()); 88 } 89 } on_post_load(plib::state_manager_t & manager)90 void on_post_load(plib::state_manager_t &manager) override 91 { 92 plib::unused_var(manager); 93 this->clear(); 94 for (std::size_t i = 0; i < m_qsize; i++ ) 95 { 96 O *n = m_obj_by_id(m_net_ids[i]); 97 this->template push<false>(entry_t(netlist_time_ext::from_raw(m_times[i]),n)); 98 } 99 } 100 101 private: 102 std::size_t m_qsize; 103 std::vector<netlist_time_ext::internal_type> m_times; 104 std::vector<std::size_t> m_net_ids; 105 id_delegate m_get_id; 106 obj_delegate m_obj_by_id; 107 }; 108 109 using queue_t = queue_base<net_t, false>; 110 111 } // namespace detail 112 } // namespace netlist 113 114 115 #endif // NL_CORE_QUEUE_H_ 116