// license:GPL-2.0+ // copyright-holders:Couriersud /// /// \file queue.h /// #ifndef NL_CORE_QUEUE_H_ #define NL_CORE_QUEUE_H_ #include "queue.h" #include "../nl_errstr.h" #include "../nltypes.h" #include "../plib/pstate.h" #include "../plib/pstring.h" #include "../plib/ptimed_queue.h" #include #include #include #include namespace netlist { namespace detail { // Use timed_queue_heap to use stdc++ heap functions instead of linear processing. // This slows down processing by about 25% on a Kaby Lake. // template // using timed_queue = plib::timed_queue_heap; template using timed_queue = plib::timed_queue_linear; // ----------------------------------------------------------------------------- // queue_t // ----------------------------------------------------------------------------- // We don't need a thread-safe queue currently. Parallel processing of // solvers will update inputs after parallel processing. template class queue_base : public timed_queue, false>, public plib::state_manager_t::callback_t { public: using entry_t = plib::pqentry_t; using base_queue = timed_queue; using id_delegate = plib::pmfp; using obj_delegate = plib::pmfp; explicit queue_base(std::size_t size, id_delegate get_id, obj_delegate get_obj) : timed_queue, false>(size) , m_qsize(0) , m_times(size) , m_net_ids(size) , m_get_id(get_id) , m_obj_by_id(get_obj) { } ~queue_base() noexcept override = default; queue_base(const queue_base &) = delete; queue_base(queue_base &&) = delete; queue_base &operator=(const queue_base &) = delete; queue_base &operator=(queue_base &&) = delete; protected: void register_state(plib::state_manager_t &manager, const pstring &module) override { manager.save_item(this, m_qsize, module + "." + "qsize"); manager.save_item(this, &m_times[0], module + "." + "times", m_times.size()); manager.save_item(this, &m_net_ids[0], module + "." + "names", m_net_ids.size()); } void on_pre_save(plib::state_manager_t &manager) override { plib::unused_var(manager); m_qsize = this->size(); for (std::size_t i = 0; i < m_qsize; i++ ) { m_times[i] = this->listptr()[i].exec_time().as_raw(); m_net_ids[i] = m_get_id(this->listptr()[i].object()); } } void on_post_load(plib::state_manager_t &manager) override { plib::unused_var(manager); this->clear(); for (std::size_t i = 0; i < m_qsize; i++ ) { O *n = m_obj_by_id(m_net_ids[i]); this->template push(entry_t(netlist_time_ext::from_raw(m_times[i]),n)); } } private: std::size_t m_qsize; std::vector m_times; std::vector m_net_ids; id_delegate m_get_id; obj_delegate m_obj_by_id; }; using queue_t = queue_base; } // namespace detail } // namespace netlist #endif // NL_CORE_QUEUE_H_