netlist: code maintenance. (nw)

- move memory pool to netlist_state_t removing one static allocation.
- add memory allocation stats to verbose output
- nl_assert no longer throws, first step to remove NL_EXCEPT macro.
This commit is contained in:
couriersud 2019-11-13 07:41:20 +01:00
parent 6a57025550
commit f4cf0cc86a
20 changed files with 394 additions and 299 deletions

View File

@ -137,18 +137,18 @@ private:
}; };
class netlist_mame_device::netlist_mame_t : public netlist::netlist_t class netlist_mame_device::netlist_mame_t : public netlist::netlist_state_t
{ {
public: public:
netlist_mame_t(netlist_mame_device &parent, const pstring &aname) netlist_mame_t(netlist_mame_device &parent, const pstring &aname)
: netlist::netlist_t(aname, plib::make_unique<netlist_mame_device::netlist_mame_callbacks_t>(parent)) : netlist::netlist_state_t(aname, plib::make_unique<netlist_mame_device::netlist_mame_callbacks_t>(parent))
, m_parent(parent) , m_parent(parent)
{ {
} }
netlist_mame_t(netlist_mame_device &parent, const pstring &aname, plib::unique_ptr<netlist::callbacks_t> cbs) netlist_mame_t(netlist_mame_device &parent, const pstring &aname, plib::unique_ptr<netlist::callbacks_t> cbs)
: netlist::netlist_t(aname, std::move(cbs)) : netlist::netlist_state_t(aname, std::move(cbs))
, m_parent(parent) , m_parent(parent)
{ {
} }
@ -176,7 +176,7 @@ public:
, m_cpu_device(nullptr) , m_cpu_device(nullptr)
, m_last(*this, "m_last", 0) , m_last(*this, "m_last", 0)
{ {
auto *nl = dynamic_cast<netlist_mame_device::netlist_mame_t *>(&exec()); auto *nl = dynamic_cast<netlist_mame_device::netlist_mame_t *>(&state());
if (nl != nullptr) if (nl != nullptr)
m_cpu_device = downcast<netlist_mame_cpu_device *>(&nl->parent()); m_cpu_device = downcast<netlist_mame_cpu_device *>(&nl->parent());
} }
@ -226,7 +226,7 @@ public:
, m_cpu_device(nullptr) , m_cpu_device(nullptr)
, m_last(*this, "m_last", 0) , m_last(*this, "m_last", 0)
{ {
auto *nl = dynamic_cast<netlist_mame_device::netlist_mame_t *>(&exec()); auto *nl = dynamic_cast<netlist_mame_device::netlist_mame_t *>(&state());
if (nl != nullptr) if (nl != nullptr)
m_cpu_device = downcast<netlist_mame_cpu_device *>(&nl->parent()); m_cpu_device = downcast<netlist_mame_cpu_device *>(&nl->parent());
} }
@ -503,9 +503,9 @@ public:
for (int i = 0; i < MAX_INPUT_CHANNELS; i++) for (int i = 0; i < MAX_INPUT_CHANNELS; i++)
{ {
m_channels[i].m_param_name = netlist::pool().make_unique<netlist::param_str_t>(*this, plib::pfmt("CHAN{1}")(i), ""); m_channels[i].m_param_name = anetlist.make_object<netlist::param_str_t>(*this, plib::pfmt("CHAN{1}")(i), "");
m_channels[i].m_param_mult = netlist::pool().make_unique<netlist::param_fp_t>(*this, plib::pfmt("MULT{1}")(i), 1.0); m_channels[i].m_param_mult = anetlist.make_object<netlist::param_fp_t>(*this, plib::pfmt("MULT{1}")(i), 1.0);
m_channels[i].m_param_offset = netlist::pool().make_unique<netlist::param_fp_t>(*this, plib::pfmt("OFFSET{1}")(i), 0.0); m_channels[i].m_param_offset = anetlist.make_object<netlist::param_fp_t>(*this, plib::pfmt("OFFSET{1}")(i), 0.0);
} }
} }
@ -589,7 +589,7 @@ netlist::setup_t &netlist_mame_device::setup()
{ {
if (!m_netlist) if (!m_netlist)
throw device_missing_dependencies(); throw device_missing_dependencies();
return m_netlist->nlstate().setup(); return m_netlist->setup();
} }
void netlist_mame_device::register_memregion_source(netlist::nlparse_t &setup, device_t &dev, const char *name) void netlist_mame_device::register_memregion_source(netlist::nlparse_t &setup, device_t &dev, const char *name)
@ -739,7 +739,7 @@ void netlist_mame_analog_output_device::custom_netlist_additions(netlist::netlis
if (owner()->has_running_machine()) if (owner()->has_running_machine())
m_delegate.resolve(); m_delegate.resolve();
auto dev = netlist::pool().make_unique<NETLIB_NAME(analog_callback)>(nlstate, dfqn); auto dev = nlstate.make_object<NETLIB_NAME(analog_callback)>(nlstate, dfqn);
//static_cast<NETLIB_NAME(analog_callback) *>(dev.get())->register_callback(std::move(m_delegate)); //static_cast<NETLIB_NAME(analog_callback) *>(dev.get())->register_callback(std::move(m_delegate));
dev->register_callback(std::move(m_delegate)); dev->register_callback(std::move(m_delegate));
nlstate.register_device(dfqn, std::move(dev)); nlstate.register_device(dfqn, std::move(dev));
@ -774,7 +774,7 @@ void netlist_mame_logic_output_device::custom_netlist_additions(netlist::netlist
if (owner()->has_running_machine()) if (owner()->has_running_machine())
m_delegate.resolve(); m_delegate.resolve();
auto dev = netlist::pool().make_unique<NETLIB_NAME(logic_callback)>(nlstate, dfqn); auto dev = nlstate.make_object<NETLIB_NAME(logic_callback)>(nlstate, dfqn);
dev->register_callback(std::move(m_delegate)); dev->register_callback(std::move(m_delegate));
nlstate.register_device(dfqn, std::move(dev)); nlstate.register_device(dfqn, std::move(dev));
nlstate.setup().register_link(dname + ".IN", pin); nlstate.setup().register_link(dname + ".IN", pin);
@ -1027,9 +1027,9 @@ void netlist_mame_device::device_config_complete()
} }
void netlist_mame_device::common_dev_start(netlist::netlist_t *lnetlist) const void netlist_mame_device::common_dev_start(netlist::netlist_state_t *lnetlist) const
{ {
auto &lsetup = lnetlist->nlstate().setup(); auto &lsetup = lnetlist->setup();
// Override log statistics // Override log statistics
pstring p = plib::util::environment("NL_STATS", ""); pstring p = plib::util::environment("NL_STATS", "");
@ -1040,7 +1040,7 @@ void netlist_mame_device::common_dev_start(netlist::netlist_t *lnetlist) const
if (err) if (err)
lsetup.log().warning("NL_STATS: invalid value {1}", p); lsetup.log().warning("NL_STATS: invalid value {1}", p);
else else
lnetlist->enable_stats(v); lnetlist->exec().enable_stats(v);
} }
// register additional devices // register additional devices
@ -1054,7 +1054,7 @@ void netlist_mame_device::common_dev_start(netlist::netlist_t *lnetlist) const
if( sdev != nullptr ) if( sdev != nullptr )
{ {
LOGDEVCALLS("Preparse subdevice %s/%s\n", d.name(), d.shortname()); LOGDEVCALLS("Preparse subdevice %s/%s\n", d.name(), d.shortname());
sdev->pre_parse_action(lnetlist->nlstate()); sdev->pre_parse_action(*lnetlist);
} }
} }
@ -1072,21 +1072,21 @@ void netlist_mame_device::common_dev_start(netlist::netlist_t *lnetlist) const
if( sdev != nullptr ) if( sdev != nullptr )
{ {
LOGDEVCALLS("Found subdevice %s/%s\n", d.name(), d.shortname()); LOGDEVCALLS("Found subdevice %s/%s\n", d.name(), d.shortname());
sdev->custom_netlist_additions(lnetlist->nlstate()); sdev->custom_netlist_additions(*lnetlist);
} }
} }
lsetup.prepare_to_run(); lsetup.prepare_to_run();
#endif #endif
} }
plib::unique_ptr<netlist::netlist_t> netlist_mame_device::base_validity_check(validity_checker &valid) const plib::unique_ptr<netlist::netlist_state_t> netlist_mame_device::base_validity_check(validity_checker &valid) const
{ {
try try
{ {
//netlist_mame_t lnetlist(*this, "netlist", plib::make_unique<netlist_validate_callbacks_t>()); //netlist_mame_t lnetlist(*this, "netlist", plib::make_unique<netlist_validate_callbacks_t>());
auto lnetlist = plib::make_unique<netlist::netlist_t>("netlist", plib::make_unique<netlist_validate_callbacks_t>()); auto lnetlist = plib::make_unique<netlist::netlist_state_t>("netlist", plib::make_unique<netlist_validate_callbacks_t>());
// enable validation mode // enable validation mode
lnetlist->nlstate().setup().set_extended_validation(false); lnetlist->setup().set_extended_validation(false);
common_dev_start(lnetlist.get()); common_dev_start(lnetlist.get());
for (device_t &d : subdevices()) for (device_t &d : subdevices())
@ -1095,7 +1095,7 @@ plib::unique_ptr<netlist::netlist_t> netlist_mame_device::base_validity_check(va
if( sdev != nullptr ) if( sdev != nullptr )
{ {
LOGDEVCALLS("Validity check on subdevice %s/%s\n", d.name(), d.shortname()); LOGDEVCALLS("Validity check on subdevice %s/%s\n", d.name(), d.shortname());
sdev->validity_helper(valid, lnetlist->nlstate()); sdev->validity_helper(valid, *lnetlist);
} }
} }
@ -1114,7 +1114,7 @@ plib::unique_ptr<netlist::netlist_t> netlist_mame_device::base_validity_check(va
{ {
osd_printf_error("%s\n", err.what()); osd_printf_error("%s\n", err.what());
} }
return plib::unique_ptr<netlist::netlist_t>(nullptr); return plib::unique_ptr<netlist::netlist_state_t>(nullptr);
} }
void netlist_mame_device::device_validity_check(validity_checker &valid) const void netlist_mame_device::device_validity_check(validity_checker &valid) const
@ -1129,18 +1129,18 @@ void netlist_mame_device::device_start()
{ {
LOGDEVCALLS("device_start entry\n"); LOGDEVCALLS("device_start entry\n");
m_netlist = netlist::pool().make_unique<netlist_mame_t>(*this, "netlist"); m_netlist = std::make_unique<netlist_mame_t>(*this, "netlist");
if (!machine().options().verbose()) if (!machine().options().verbose())
{ {
m_netlist->nlstate().log().verbose.set_enabled(false); m_netlist->log().verbose.set_enabled(false);
m_netlist->nlstate().log().debug.set_enabled(false); m_netlist->log().debug.set_enabled(false);
} }
common_dev_start(m_netlist.get()); common_dev_start(m_netlist.get());
m_netlist->nlstate().save(*this, m_rem, pstring(this->name()), "m_rem"); m_netlist->save(*this, m_rem, pstring(this->name()), "m_rem");
m_netlist->nlstate().save(*this, m_div, pstring(this->name()), "m_div"); m_netlist->save(*this, m_div, pstring(this->name()), "m_div");
m_netlist->nlstate().save(*this, m_old, pstring(this->name()), "m_old"); m_netlist->save(*this, m_old, pstring(this->name()), "m_old");
save_state(); save_state();
@ -1162,13 +1162,13 @@ void netlist_mame_device::device_reset()
LOGDEVCALLS("device_reset\n"); LOGDEVCALLS("device_reset\n");
m_old = netlist::netlist_time::zero(); m_old = netlist::netlist_time::zero();
m_rem = netlist::netlist_time::zero(); m_rem = netlist::netlist_time::zero();
netlist().reset(); netlist().exec().reset();
} }
void netlist_mame_device::device_stop() void netlist_mame_device::device_stop()
{ {
LOGDEVCALLS("device_stop\n"); LOGDEVCALLS("device_stop\n");
netlist().stop(); netlist().exec().stop();
} }
ATTR_COLD void netlist_mame_device::device_post_load() ATTR_COLD void netlist_mame_device::device_post_load()
@ -1176,7 +1176,7 @@ ATTR_COLD void netlist_mame_device::device_post_load()
LOGDEVCALLS("device_post_load\n"); LOGDEVCALLS("device_post_load\n");
netlist().run_state_manager().post_load(); netlist().run_state_manager().post_load();
netlist().nlstate().rebuild_lists(); netlist().rebuild_lists();
} }
ATTR_COLD void netlist_mame_device::device_pre_save() ATTR_COLD void netlist_mame_device::device_pre_save()
@ -1199,46 +1199,46 @@ void netlist_mame_device::update_icount(netlist::netlist_time time) noexcept
void netlist_mame_device::check_mame_abort_slice() noexcept void netlist_mame_device::check_mame_abort_slice() noexcept
{ {
if (m_icount <= 0) if (m_icount <= 0)
netlist().abort_current_queue_slice(); netlist().exec().abort_current_queue_slice();
} }
ATTR_COLD void netlist_mame_device::save_state() ATTR_COLD void netlist_mame_device::save_state()
{ {
for (auto const & s : netlist().run_state_manager().save_list()) for (auto const & s : netlist().run_state_manager().save_list())
{ {
netlist().log().debug("saving state for {1}\n", s->m_name.c_str()); netlist().log().debug("saving state for {1}\n", s->name().c_str());
if (s->m_dt.is_float) if (s->dt().is_float())
{ {
if (s->m_dt.size == sizeof(double)) if (s->dt().size() == sizeof(double))
save_pointer((double *) s->m_ptr, s->m_name.c_str(), s->m_count); save_pointer((double *) s->ptr(), s->name().c_str(), s->count());
else if (s->m_dt.size == sizeof(float)) else if (s->dt().size() == sizeof(float))
save_pointer((float *) s->m_ptr, s->m_name.c_str(), s->m_count); save_pointer((float *) s->ptr(), s->name().c_str(), s->count());
else else
netlist().log().fatal("Unknown floating type for {1}\n", s->m_name.c_str()); netlist().log().fatal("Unknown floating type for {1}\n", s->name().c_str());
} }
else if (s->m_dt.is_integral) else if (s->dt().is_integral())
{ {
if (s->m_dt.size == sizeof(int64_t)) if (s->dt().size() == sizeof(int64_t))
save_pointer((int64_t *) s->m_ptr, s->m_name.c_str(), s->m_count); save_pointer((int64_t *) s->ptr(), s->name().c_str(), s->count());
else if (s->m_dt.size == sizeof(int32_t)) else if (s->dt().size() == sizeof(int32_t))
save_pointer((int32_t *) s->m_ptr, s->m_name.c_str(), s->m_count); save_pointer((int32_t *) s->ptr(), s->name().c_str(), s->count());
else if (s->m_dt.size == sizeof(int16_t)) else if (s->dt().size() == sizeof(int16_t))
save_pointer((int16_t *) s->m_ptr, s->m_name.c_str(), s->m_count); save_pointer((int16_t *) s->ptr(), s->name().c_str(), s->count());
else if (s->m_dt.size == sizeof(int8_t)) else if (s->dt().size() == sizeof(int8_t))
save_pointer((int8_t *) s->m_ptr, s->m_name.c_str(), s->m_count); save_pointer((int8_t *) s->ptr(), s->name().c_str(), s->count());
#if (PHAS_INT128) #if (PHAS_INT128)
else if (s->m_dt.size == sizeof(INT128)) else if (s->dt().size() == sizeof(INT128))
save_pointer((int64_t *) s->m_ptr, s->m_name.c_str(), s->m_count * 2); save_pointer((int64_t *) s->ptr(), s->name().c_str(), s->count() * 2);
#endif #endif
else else
netlist().log().fatal("Unknown integral type size {1} for {2}\n", s->m_dt.size, s->m_name.c_str()); netlist().log().fatal("Unknown integral type size {1} for {2}\n", s->dt().size(), s->name().c_str());
} }
else if (s->m_dt.is_custom) else if (s->dt().is_custom())
{ {
/* do nothing */ /* do nothing */
} }
else else
netlist().log().fatal("found unsupported save element {1}\n", s->m_name); netlist().log().fatal("found unsupported save element {1}\n", s->name());
} }
} }
@ -1268,7 +1268,7 @@ void netlist_mame_cpu_device::device_start()
state_add(STATE_GENPCBASE, "CURPC", m_genPC).noshow(); state_add(STATE_GENPCBASE, "CURPC", m_genPC).noshow();
int index = 0; int index = 0;
for (auto &n : netlist().nlstate().nets()) for (auto &n : netlist().nets())
{ {
if (n->is_logic()) if (n->is_logic())
{ {
@ -1310,14 +1310,14 @@ ATTR_HOT void netlist_mame_cpu_device::execute_run()
m_genPC++; m_genPC++;
m_genPC &= 255; m_genPC &= 255;
debugger_instruction_hook(m_genPC); debugger_instruction_hook(m_genPC);
netlist().process_queue(m_div); netlist().exec().process_queue(m_div);
update_icount(netlist().time()); update_icount(netlist().exec().time());
} }
} }
else else
{ {
netlist().process_queue(m_div * m_icount); netlist().exec().process_queue(m_div * m_icount);
update_icount(netlist().time()); update_icount(netlist().exec().time());
} }
} }
@ -1339,11 +1339,11 @@ offs_t netlist_disassembler::disassemble(std::ostream &stream, offs_t pc, const
{ {
unsigned startpc = pc; unsigned startpc = pc;
int relpc = pc - m_dev->genPC(); int relpc = pc - m_dev->genPC();
if (relpc >= 0 && relpc < m_dev->netlist().queue().size()) if (relpc >= 0 && relpc < m_dev->netlist().exec().queue().size())
{ {
int dpc = m_dev->netlist().queue().size() - relpc - 1; int dpc = m_dev->netlist().exec().queue().size() - relpc - 1;
util::stream_format(stream, "%c %s @%10.7f", (relpc == 0) ? '*' : ' ', m_dev->netlist().queue()[dpc].object()->name().c_str(), util::stream_format(stream, "%c %s @%10.7f", (relpc == 0) ? '*' : ' ', m_dev->netlist().exec().queue()[dpc].object()->name().c_str(),
m_dev->netlist().queue()[dpc].exec_time().as_double()); m_dev->netlist().exec().queue()[dpc].exec_time().as_double());
} }
pc+=1; pc+=1;
@ -1369,7 +1369,7 @@ void netlist_mame_sound_device::device_validity_check(validity_checker &valid) c
if (lnetlist) if (lnetlist)
{ {
/*Ok - do some more checks */ /*Ok - do some more checks */
std::vector<nld_sound_out *> outdevs = lnetlist->nlstate().get_device_list<nld_sound_out>(); std::vector<nld_sound_out *> outdevs = lnetlist->get_device_list<nld_sound_out>();
if (outdevs.size() == 0) if (outdevs.size() == 0)
osd_printf_error("No output devices\n"); osd_printf_error("No output devices\n");
else else
@ -1381,7 +1381,7 @@ void netlist_mame_sound_device::device_validity_check(validity_checker &valid) c
osd_printf_error("illegal channel number %d\n", chan); osd_printf_error("illegal channel number %d\n", chan);
} }
} }
std::vector<nld_sound_in *> indevs = lnetlist->nlstate().get_device_list<nld_sound_in>(); std::vector<nld_sound_in *> indevs = lnetlist->get_device_list<nld_sound_in>();
if (indevs.size() > 1) if (indevs.size() > 1)
osd_printf_error("A maximum of one input device is allowed but found %d!\n", (int)indevs.size()); osd_printf_error("A maximum of one input device is allowed but found %d!\n", (int)indevs.size());
} }
@ -1397,7 +1397,7 @@ void netlist_mame_sound_device::device_start()
// Configure outputs // Configure outputs
std::vector<nld_sound_out *> outdevs = netlist().nlstate().get_device_list<nld_sound_out>(); std::vector<nld_sound_out *> outdevs = netlist().get_device_list<nld_sound_out>();
if (outdevs.size() == 0) if (outdevs.size() == 0)
fatalerror("No output devices"); fatalerror("No output devices");
@ -1424,7 +1424,7 @@ void netlist_mame_sound_device::device_start()
m_in = nullptr; m_in = nullptr;
std::vector<nld_sound_in *> indevs = netlist().nlstate().get_device_list<nld_sound_in>(); std::vector<nld_sound_in *> indevs = netlist().get_device_list<nld_sound_in>();
if (indevs.size() > 1) if (indevs.size() > 1)
fatalerror("A maximum of one input device is allowed!"); fatalerror("A maximum of one input device is allowed!");
if (indevs.size() == 1) if (indevs.size() == 1)
@ -1464,9 +1464,9 @@ void netlist_mame_sound_device::sound_stream_update(sound_stream &stream, stream
} }
} }
netlist::netlist_time cur(netlist().time()); netlist::netlist_time cur(netlist().exec().time());
netlist().process_queue(m_div * samples); netlist().exec().process_queue(m_div * samples);
cur += (m_div * samples); cur += (m_div * samples);

View File

@ -100,18 +100,18 @@ protected:
netlist::netlist_time m_div; netlist::netlist_time m_div;
plib::unique_ptr<netlist::netlist_t> base_validity_check(validity_checker &valid) const; plib::unique_ptr<netlist::netlist_state_t> base_validity_check(validity_checker &valid) const;
private: private:
void save_state(); void save_state();
void common_dev_start(netlist::netlist_t *lnetlist) const; void common_dev_start(netlist::netlist_state_t *lnetlist) const;
/* timing support here - so sound can hijack it ... */ /* timing support here - so sound can hijack it ... */
netlist::netlist_time m_rem; netlist::netlist_time m_rem;
netlist::netlist_time m_old; netlist::netlist_time m_old;
netlist::unique_pool_ptr<netlist_mame_t> m_netlist; std::unique_ptr<netlist_mame_t> m_netlist;
func_type m_setup_func; func_type m_setup_func;
}; };

View File

@ -222,7 +222,7 @@ namespace analog
m_capmod = m_model.m_CAPMOD; m_capmod = m_model.m_CAPMOD;
// printf("capmod %d %g %g\n", m_capmod, (nl_fptype)m_model.m_VTO, m_polarity); // printf("capmod %d %g %g\n", m_capmod, (nl_fptype)m_model.m_VTO, m_polarity);
nl_assert_always(m_capmod == 0 || m_capmod == 2, "Error: CAPMODEL invalid value for " + m_model.name()); nl_assert_always(m_capmod == 0 || m_capmod == 2, "Error: CAPMODEL invalid value");
// //
// From http://ltwiki.org/LTspiceHelp/LTspiceHelp/M_MOSFET.htm : // From http://ltwiki.org/LTspiceHelp/LTspiceHelp/M_MOSFET.htm :
@ -238,7 +238,7 @@ namespace analog
// calculate effective channel length // calculate effective channel length
m_Leff = m_model.m_L - 2 * m_model.m_LD; m_Leff = m_model.m_L - 2 * m_model.m_LD;
nl_assert_always(m_Leff > nlconst::zero(), "Effective Lateral diffusion would be negative for model " + m_model.name()); nl_assert_always(m_Leff > nlconst::zero(), "Effective Lateral diffusion would be negative for model");
nl_fptype Cox = (m_model.m_TOX > nlconst::zero()) ? (constants::eps_SiO2() * constants::eps_0() / m_model.m_TOX) : nlconst::zero(); nl_fptype Cox = (m_model.m_TOX > nlconst::zero()) ? (constants::eps_SiO2() * constants::eps_0() / m_model.m_TOX) : nlconst::zero();
@ -259,7 +259,7 @@ namespace analog
m_phi = m_model.m_PHI; m_phi = m_model.m_PHI;
else if (m_model.m_NSUB > nlconst::zero()) else if (m_model.m_NSUB > nlconst::zero())
{ {
nl_assert_always(m_model.m_NSUB * nlconst::magic(1e6) >= constants::NiSi(), "Error calculating phi for model " + m_model.name()); nl_assert_always(m_model.m_NSUB * nlconst::magic(1e6) >= constants::NiSi(), "Error calculating phi for model");
m_phi = nlconst::two() * Vt * plib::log (m_model.m_NSUB * nlconst::magic(1e6) / constants::NiSi()); m_phi = nlconst::two() * Vt * plib::log (m_model.m_NSUB * nlconst::magic(1e6) / constants::NiSi());
} }
else else

View File

@ -92,9 +92,9 @@ namespace netlist
for (auto & pwr_sym : power_syms) for (auto & pwr_sym : power_syms)
{ {
pstring devname = out_proxied->device().name(); pstring devname = out_proxied->device().name();
auto tp_t = state().setup().find_terminal(devname + "." + pwr_sym.first, auto tp_t = anetlist.setup().find_terminal(devname + "." + pwr_sym.first,
/*detail::terminal_type::INPUT,*/ false); /*detail::terminal_type::INPUT,*/ false);
auto tn_t = state().setup().find_terminal(devname + "." + pwr_sym.second, auto tn_t = anetlist.setup().find_terminal(devname + "." + pwr_sym.second,
/*detail::terminal_type::INPUT,*/ false); /*detail::terminal_type::INPUT,*/ false);
if (f && (tp_t != nullptr && tn_t != nullptr)) if (f && (tp_t != nullptr && tn_t != nullptr))
log().warning(MI_MULTIPLE_POWER_TERMINALS_ON_DEVICE(out_proxied->device().name(), log().warning(MI_MULTIPLE_POWER_TERMINALS_ON_DEVICE(out_proxied->device().name(),
@ -113,9 +113,9 @@ namespace netlist
if (!f) if (!f)
{ {
if (logic_family()->fixed_V() == nlconst::zero()) if (logic_family()->fixed_V() == nlconst::zero())
log().error(MI_NO_POWER_TERMINALS_ON_DEVICE_1(state().setup().de_alias(out_proxied->device().name()))); log().error(MI_NO_POWER_TERMINALS_ON_DEVICE_1(anetlist.setup().de_alias(out_proxied->device().name())));
else else
log().info(MI_NO_POWER_TERMINALS_ON_DEVICE_1(state().setup().de_alias(out_proxied->device().name()))); log().info(MI_NO_POWER_TERMINALS_ON_DEVICE_1(anetlist.setup().de_alias(out_proxied->device().name())));
m_GNDHack = plib::make_unique<analog_output_t>(*this, "_QGND"); m_GNDHack = plib::make_unique<analog_output_t>(*this, "_QGND");
m_VCCHack = plib::make_unique<analog_output_t>(*this, "_QVCC"); m_VCCHack = plib::make_unique<analog_output_t>(*this, "_QVCC");
@ -126,7 +126,7 @@ namespace netlist
else else
{ {
log().verbose("D/A Proxy: Found power terminals on device {1}", out_proxied->device().name()); log().verbose("D/A Proxy: Found power terminals on device {1}", out_proxied->device().name());
if (state().setup().is_extended_validation()) if (anetlist.setup().is_extended_validation())
{ {
// During validation, don't connect to terminals found // During validation, don't connect to terminals found
// This will cause terminals not connected to a rail net to // This will cause terminals not connected to a rail net to

View File

@ -327,7 +327,7 @@ namespace devices
for (int i=0; i < m_N(); i++) for (int i=0; i < m_N(); i++)
{ {
pstring n = plib::pfmt("A{1}")(i); pstring n = plib::pfmt("A{1}")(i);
m_I.push_back(pool().make_unique<analog_input_t>(*this, n)); m_I.push_back(state().make_object<analog_input_t>(*this, n));
inps.push_back(n); inps.push_back(n);
m_vals.push_back(nlconst::zero()); m_vals.push_back(nlconst::zero());
} }
@ -426,8 +426,8 @@ namespace devices
{ {
if (owner.state().setup().is_extended_validation() || force_analog_input) if (owner.state().setup().is_extended_validation() || force_analog_input)
{ {
m_GND = pool().make_unique<analog_input_t>(owner, sGND, NETLIB_DELEGATE(power_pins, noop)); m_GND = owner.state().make_object<analog_input_t>(owner, sGND, NETLIB_DELEGATE(power_pins, noop));
m_VCC = pool().make_unique<analog_input_t>(owner, sVCC, NETLIB_DELEGATE(power_pins, noop)); m_VCC = owner.state().make_object<analog_input_t>(owner, sVCC, NETLIB_DELEGATE(power_pins, noop));
} }
else else
{ {

View File

@ -1,7 +1,7 @@
// license:GPL-2.0+ // license:GPL-2.0+
// copyright-holders:Couriersud // copyright-holders:Couriersud
#include "nlid_truthtable.h" #include "nlid_truthtable.h"
#include "netlist/nl_setup.h" #include "netlist/nl_setup.h"
#include "plib/palloc.h" #include "plib/palloc.h"
#include "plib/plists.h" #include "plib/plists.h"
@ -245,13 +245,13 @@ namespace devices
: truthtable_base_element_t(name, classname, def_param, sourcefile) : truthtable_base_element_t(name, classname, def_param, sourcefile)
{ } { }
unique_pool_ptr<device_t> Create(netlist_state_t &anetlist, const pstring &name) override unique_pool_ptr<device_t> Create(nlmempool &pool, netlist_state_t &anetlist, const pstring &name) override
{ {
using tt_type = nld_truthtable_t<m_NI, m_NO>; using tt_type = nld_truthtable_t<m_NI, m_NO>;
if (!m_ttbl) if (!m_ttbl)
{ {
m_ttbl = pool().make_unique<typename nld_truthtable_t<m_NI, m_NO>::truthtable_t>(); m_ttbl = pool.make_unique<typename nld_truthtable_t<m_NI, m_NO>::truthtable_t>();
truthtable_parser desc_s(m_NO, m_NI, truthtable_parser desc_s(m_NO, m_NI,
packed_int(m_ttbl->m_out_state.data(), sizeof(m_ttbl->m_out_state[0]) * 8), packed_int(m_ttbl->m_out_state.data(), sizeof(m_ttbl->m_out_state[0]) * 8),
m_ttbl->m_timing_index.data(), m_ttbl->m_timing_nt.data()); m_ttbl->m_timing_index.data(), m_ttbl->m_timing_nt.data());
@ -266,7 +266,7 @@ namespace devices
if (m_family_desc == nullptr) if (m_family_desc == nullptr)
plib::pthrow<nl_exception>("family description not found for {1}", m_family_name); plib::pthrow<nl_exception>("family description not found for {1}", m_family_name);
return pool().make_unique<tt_type>(anetlist, name, m_family_desc, *m_ttbl, m_desc); return pool.make_unique<tt_type>(anetlist, name, m_family_desc, *m_ttbl, m_desc);
} }
private: private:
unique_pool_ptr<typename nld_truthtable_t<m_NI, m_NO>::truthtable_t> m_ttbl; unique_pool_ptr<typename nld_truthtable_t<m_NI, m_NO>::truthtable_t> m_ttbl;
@ -512,7 +512,7 @@ namespace factory
ENTRY(12, sourcefile); ENTRY(12, sourcefile);
default: default:
pstring msg = plib::pfmt("unable to create truthtable<{1},{2}>")(desc.ni)(desc.no); pstring msg = plib::pfmt("unable to create truthtable<{1},{2}>")(desc.ni)(desc.no);
nl_assert_always(false, msg); nl_assert_always(false, msg.c_str());
} }
ret->m_desc = desc.desc; ret->m_desc = desc.desc;
ret->m_family_name = desc.family; ret->m_family_name = desc.family;

View File

@ -49,11 +49,11 @@ namespace netlist
unique_pool_ptr<devices::nld_base_d_to_a_proxy> logic_family_ttl_t::create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *proxied) const unique_pool_ptr<devices::nld_base_d_to_a_proxy> logic_family_ttl_t::create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *proxied) const
{ {
return pool().make_unique<devices::nld_d_to_a_proxy>(anetlist, name, proxied); return anetlist.make_object<devices::nld_d_to_a_proxy>(anetlist, name, proxied);
} }
unique_pool_ptr<devices::nld_base_a_to_d_proxy> logic_family_ttl_t::create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const unique_pool_ptr<devices::nld_base_a_to_d_proxy> logic_family_ttl_t::create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const
{ {
return pool().make_unique<devices::nld_a_to_d_proxy>(anetlist, name, proxied); return anetlist.make_object<devices::nld_a_to_d_proxy>(anetlist, name, proxied);
} }
class logic_family_cd4xxx_t : public logic_family_desc_t class logic_family_cd4xxx_t : public logic_family_desc_t
@ -76,12 +76,12 @@ namespace netlist
unique_pool_ptr<devices::nld_base_d_to_a_proxy> logic_family_cd4xxx_t::create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *proxied) const unique_pool_ptr<devices::nld_base_d_to_a_proxy> logic_family_cd4xxx_t::create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *proxied) const
{ {
return pool().make_unique<devices::nld_d_to_a_proxy>(anetlist, name, proxied); return anetlist.make_object<devices::nld_d_to_a_proxy>(anetlist, name, proxied);
} }
unique_pool_ptr<devices::nld_base_a_to_d_proxy> logic_family_cd4xxx_t::create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const unique_pool_ptr<devices::nld_base_a_to_d_proxy> logic_family_cd4xxx_t::create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const
{ {
return pool().make_unique<devices::nld_a_to_d_proxy>(anetlist, name, proxied); return anetlist.make_object<devices::nld_a_to_d_proxy>(anetlist, name, proxied);
} }
const logic_family_desc_t *family_TTL() const logic_family_desc_t *family_TTL()
@ -100,7 +100,7 @@ namespace netlist
// queue_t // queue_t
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
detail::queue_t::queue_t(netlist_state_t &nl) detail::queue_t::queue_t(netlist_t &nl)
: timed_queue<plib::pqentry_t<net_t *, netlist_time>, false>(512) : timed_queue<plib::pqentry_t<net_t *, netlist_time>, false>(512)
, netlist_ref(nl) , netlist_ref(nl)
, m_qsize(0) , m_qsize(0)
@ -144,8 +144,8 @@ namespace netlist
// netlist_ref_t // netlist_ref_t
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
detail::netlist_ref::netlist_ref(netlist_state_t &nl) detail::netlist_ref::netlist_ref(netlist_t &nl)
: m_netlist(nl.exec()) { } : m_netlist(nl) { }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
// device_object_t // device_object_t
@ -179,18 +179,16 @@ namespace netlist
// netlist_t // netlist_t
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
netlist_t::netlist_t(const pstring &aname, plib::unique_ptr<callbacks_t> callbacks) netlist_t::netlist_t(netlist_state_t &state)
: m_state(plib::make_unique<netlist_state_t>(aname, *this, std::move(callbacks))) : m_state(state)
, m_solver(nullptr) , m_solver(nullptr)
, m_time(netlist_time::zero()) , m_time(netlist_time::zero())
, m_mainclock(nullptr) , m_mainclock(nullptr)
, m_queue(*m_state) , m_queue(*this)
, m_use_stats(false) , m_use_stats(false)
{ {
devices::initialize_factory(nlstate().setup().factory()); state.run_state_manager().save_item(this, static_cast<plib::state_manager_t::callback_t &>(m_queue), "m_queue");
NETLIST_NAME(base)(nlstate().setup()); state.run_state_manager().save_item(this, m_time, "m_time");
run_state_manager().save_item(this, static_cast<plib::state_manager_t::callback_t &>(m_queue), "m_queue");
run_state_manager().save_item(this, m_time, "m_time");
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
@ -198,17 +196,21 @@ namespace netlist
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
netlist_state_t::netlist_state_t(const pstring &aname, netlist_state_t::netlist_state_t(const pstring &aname,
netlist_t & anetlist,
plib::unique_ptr<callbacks_t> &&callbacks) plib::unique_ptr<callbacks_t> &&callbacks)
: m_name(aname) : m_name(aname)
, m_netlist(anetlist)
, m_state() , m_state()
, m_callbacks(std::move(callbacks)) // Order is important here , m_callbacks(std::move(callbacks)) // Order is important here
, m_log(*m_callbacks) , m_log(*m_callbacks)
, m_setup(plib::make_unique<setup_t>(*this))
{ {
pstring libpath = plib::util::environment("NL_BOOSTLIB", plib::util::buildpath({".", "nlboost.so"})); pstring libpath = plib::util::environment("NL_BOOSTLIB", plib::util::buildpath({".", "nlboost.so"}));
m_lib = plib::make_unique<plib::dynlib>(libpath); m_lib = plib::make_unique<plib::dynlib>(libpath);
m_setup = plib::make_unique<setup_t>(*this);
// create the run interface
m_netlist = m_pool.make_unique<netlist_t>(*this);
devices::initialize_factory(m_setup->factory());
NETLIST_NAME(base)(*m_setup);
} }
@ -300,10 +302,10 @@ namespace netlist
void netlist_t::reset() void netlist_t::reset()
{ {
log().debug("Searching for mainclock\n"); log().debug("Searching for mainclock\n");
m_mainclock = m_state->get_single_device<devices::NETLIB_NAME(mainclock)>("mainclock"); m_mainclock = m_state.get_single_device<devices::NETLIB_NAME(mainclock)>("mainclock");
log().debug("Searching for solver\n"); log().debug("Searching for solver\n");
m_solver = m_state->get_single_device<devices::NETLIB_NAME(solver)>("solver"); m_solver = m_state.get_single_device<devices::NETLIB_NAME(solver)>("solver");
m_time = netlist_time::zero(); m_time = netlist_time::zero();
m_queue.clear(); m_queue.clear();
@ -312,7 +314,7 @@ namespace netlist
//if (m_solver != nullptr) //if (m_solver != nullptr)
// m_solver->reset(); // m_solver->reset();
m_state->reset(); m_state.reset();
} }
void netlist_state_t::reset() void netlist_state_t::reset()
@ -411,19 +413,19 @@ namespace netlist
if (m_use_stats) if (m_use_stats)
{ {
std::vector<size_t> index; std::vector<size_t> index;
for (size_t i=0; i < m_state->m_devices.size(); i++) for (size_t i=0; i < m_state.m_devices.size(); i++)
index.push_back(i); index.push_back(i);
std::sort(index.begin(), index.end(), std::sort(index.begin(), index.end(),
[&](size_t i1, size_t i2) { return m_state->m_devices[i1].second->m_stats->m_stat_total_time.total() < m_state->m_devices[i2].second->m_stats->m_stat_total_time.total(); }); [&](size_t i1, size_t i2) { return m_state.m_devices[i1].second->m_stats->m_stat_total_time.total() < m_state.m_devices[i2].second->m_stats->m_stat_total_time.total(); });
plib::pperftime_t<true>::type total_time(0); plib::pperftime_t<true>::type total_time(0);
plib::pperftime_t<true>::ctype total_count(0); plib::pperftime_t<true>::ctype total_count(0);
for (auto & j : index) for (auto & j : index)
{ {
auto entry = m_state->m_devices[j].second.get(); auto entry = m_state.m_devices[j].second.get();
auto stats = m_state->m_devices[j].second.get()->m_stats.get(); auto stats = m_state.m_devices[j].second.get()->m_stats.get();
log().verbose("Device {1:20} : {2:12} {3:12} {4:15} {5:12}", entry->name(), log().verbose("Device {1:20} : {2:12} {3:12} {4:15} {5:12}", entry->name(),
stats->m_stat_call_count(), stats->m_stat_total_time.count(), stats->m_stat_call_count(), stats->m_stat_total_time.count(),
stats->m_stat_total_time.total(), stats->m_stat_inc_active()); stats->m_stat_total_time.total(), stats->m_stat_inc_active());
@ -472,7 +474,7 @@ namespace netlist
} }
auto trigger = total_count * 200 / 1000000; // 200 ppm auto trigger = total_count * 200 / 1000000; // 200 ppm
for (auto &entry : m_state->m_devices) for (auto &entry : m_state.m_devices)
{ {
auto ep = entry.second.get(); auto ep = entry.second.get();
auto stats = ep->m_stats.get(); auto stats = ep->m_stats.get();
@ -483,7 +485,10 @@ namespace netlist
static_cast<nl_fptype>(stats->m_stat_inc_active()) / static_cast<nl_fptype>(stats->m_stat_total_time.count()), static_cast<nl_fptype>(stats->m_stat_inc_active()) / static_cast<nl_fptype>(stats->m_stat_total_time.count()),
stats->m_stat_inc_active(), stats->m_stat_total_time.count()); stats->m_stat_inc_active(), stats->m_stat_total_time.count());
} }
log().verbose("");
} }
log().verbose("Current pool memory allocated: {1:12} kB", nlstate().pool().cur_alloc() >> 10);
log().verbose("Maximum pool memory allocated: {1:12} kB", nlstate().pool().max_alloc() >> 10);
} }
core_device_t *netlist_state_t::get_single_device(const pstring &classname, bool (*cc)(core_device_t *)) const core_device_t *netlist_state_t::get_single_device(const pstring &classname, bool (*cc)(core_device_t *)) const
@ -513,29 +518,29 @@ namespace netlist
core_device_t::core_device_t(netlist_state_t &owner, const pstring &name) core_device_t::core_device_t(netlist_state_t &owner, const pstring &name)
: object_t(name) : object_t(name)
, logic_family_t() , logic_family_t()
, netlist_ref(owner) , netlist_ref(owner.exec())
, m_hint_deactivate(false) , m_hint_deactivate(false)
, m_active_outputs(*this, "m_active_outputs", 1) , m_active_outputs(*this, "m_active_outputs", 1)
{ {
if (logic_family() == nullptr) if (logic_family() == nullptr)
set_logic_family(family_TTL()); set_logic_family(family_TTL());
if (exec().stats_enabled()) if (exec().stats_enabled())
m_stats = pool().make_unique<stats_t>(); m_stats = owner.make_object<stats_t>();
} }
core_device_t::core_device_t(core_device_t &owner, const pstring &name) core_device_t::core_device_t(core_device_t &owner, const pstring &name)
: object_t(owner.name() + "." + name) : object_t(owner.name() + "." + name)
, logic_family_t() , logic_family_t()
, netlist_ref(owner.state()) , netlist_ref(owner.state().exec())
, m_hint_deactivate(false) , m_hint_deactivate(false)
, m_active_outputs(*this, "m_active_outputs", 1) , m_active_outputs(*this, "m_active_outputs", 1)
{ {
set_logic_family(owner.logic_family()); set_logic_family(owner.logic_family());
if (logic_family() == nullptr) if (logic_family() == nullptr)
set_logic_family(family_TTL()); set_logic_family(family_TTL());
state().register_device(this->name(), owned_pool_ptr<core_device_t>(this, false)); owner.state().register_device(this->name(), owned_pool_ptr<core_device_t>(this, false));
if (exec().stats_enabled()) if (exec().stats_enabled())
m_stats = pool().make_unique<stats_t>(); m_stats = owner.state().make_object<stats_t>();
} }
void core_device_t::set_default_delegate(detail::core_terminal_t &term) void core_device_t::set_default_delegate(detail::core_terminal_t &term)
@ -627,7 +632,7 @@ namespace netlist
detail::net_t::net_t(netlist_state_t &nl, const pstring &aname, core_terminal_t *railterminal) detail::net_t::net_t(netlist_state_t &nl, const pstring &aname, core_terminal_t *railterminal)
: object_t(aname) : object_t(aname)
, netlist_ref(nl) , netlist_ref(nl.exec())
, m_new_Q(*this, "m_new_Q", 0) , m_new_Q(*this, "m_new_Q", 0)
, m_cur_Q (*this, "m_cur_Q", 0) , m_cur_Q (*this, "m_cur_Q", 0)
, m_in_queue(*this, "m_in_queue", queue_status::DELIVERED) , m_in_queue(*this, "m_in_queue", queue_status::DELIVERED)
@ -982,4 +987,8 @@ namespace netlist
return dynamic_cast<const analog_net_t *>(this) != nullptr; return dynamic_cast<const analog_net_t *>(this) != nullptr;
} }
// ----------------------------------------------------------------------------------------
// netlist_state_t
// ----------------------------------------------------------------------------------------
} // namespace netlist } // namespace netlist

View File

@ -23,6 +23,7 @@
#include "plib/pstonum.h" #include "plib/pstonum.h"
#include "plib/pstream.h" #include "plib/pstream.h"
#include "plib/ptime.h" #include "plib/ptime.h"
#include "plib/pexception.h"
#include "nl_errstr.h" #include "nl_errstr.h"
#include "nltypes.h" #include "nltypes.h"
@ -174,13 +175,13 @@ class NETLIB_NAME(name) : public device_t
//============================================================ //============================================================
#if defined(MAME_DEBUG) || (NL_DEBUG == true) #if defined(MAME_DEBUG) || (NL_DEBUG == true)
#define nl_assert(x) do { if (1) if (!(x)) plib::pthrow<nl_exception>(plib::pfmt("assert: {1}:{2}: {3}")(__FILE__)(__LINE__)(#x) ); } while (0) #define nl_assert(x) passert_always(x);
#define NL_NOEXCEPT #define NL_NOEXCEPT
#else #else
#define nl_assert(x) do { if (0) if (!(x)) { /*throw nl_exception(plib::pfmt("assert: {1}:{2}: {3}")(__FILE__)(__LINE__)(#x) ); */} } while (0) #define nl_assert(x) do { } while (0)
#define NL_NOEXCEPT noexcept #define NL_NOEXCEPT noexcept
#endif #endif
#define nl_assert_always(x, msg) do { if (!(x)) plib::pthrow<nl_exception>("Fatal error: {1}\nCaused by assert: {2}:{3}: {4}", msg, __FILE__, __LINE__, #x); } while (0) #define nl_assert_always(x, msg) passert_always_msg(x, msg)
//============================================================ //============================================================
// Namespace starts // Namespace starts
@ -424,9 +425,19 @@ namespace netlist
store().insert({obj, aname}); store().insert({obj, aname});
} }
static const T get(const C *obj) noexcept static const T &get(const C *obj) noexcept
{ {
return store().find(obj)->second; try
{
auto ret(store().find(obj));
nl_assert(ret != store().end());
return ret->second;
}
catch (...)
{
nl_assert_always(true, "exception in property_store_t.get()");
return *static_cast<T *>(nullptr);
}
} }
static void remove(const C *obj) noexcept static void remove(const C *obj) noexcept
@ -472,7 +483,7 @@ namespace netlist
/// ///
/// \returns name of the object. /// \returns name of the object.
pstring name() const noexcept const pstring &name() const noexcept
{ {
return props::get(this); return props::get(this);
} }
@ -492,7 +503,7 @@ namespace netlist
struct netlist_ref struct netlist_ref
{ {
explicit netlist_ref(netlist_state_t &nl); explicit netlist_ref(netlist_t &nl);
COPYASSIGNMOVE(netlist_ref, delete) COPYASSIGNMOVE(netlist_ref, delete)
@ -1076,10 +1087,7 @@ namespace netlist
~device_t() noexcept override = default; ~device_t() noexcept override = default;
template<class C, typename... Args> template<class C, typename... Args>
void create_and_register_subdevice(const pstring &name, unique_pool_ptr<C> &dev, Args&&... args) void create_and_register_subdevice(const pstring &name, unique_pool_ptr<C> &dev, Args&&... args);
{
dev = pool().make_unique<C>(*this, name, std::forward<Args>(args)...);
}
void register_subalias(const pstring &name, detail::core_terminal_t &term); void register_subalias(const pstring &name, detail::core_terminal_t &term);
void register_subalias(const pstring &name, const pstring &aliased); void register_subalias(const pstring &name, const pstring &aliased);
@ -1335,7 +1343,7 @@ namespace netlist
public: public:
using base_queue = timed_queue<plib::pqentry_t<net_t *, netlist_time>, false>; using base_queue = timed_queue<plib::pqentry_t<net_t *, netlist_time>, false>;
using entry_t = plib::pqentry_t<net_t *, netlist_time>; using entry_t = plib::pqentry_t<net_t *, netlist_time>;
explicit queue_t(netlist_state_t &nl); explicit queue_t(netlist_t &nl);
~queue_t() noexcept override = default; ~queue_t() noexcept override = default;
queue_t(const queue_t &) = delete; queue_t(const queue_t &) = delete;
@ -1370,12 +1378,16 @@ namespace netlist
// need to preserve order of device creation ... // need to preserve order of device creation ...
using devices_collection_type = std::vector<std::pair<pstring, owned_pool_ptr<core_device_t>>>; using devices_collection_type = std::vector<std::pair<pstring, owned_pool_ptr<core_device_t>>>;
netlist_state_t(const pstring &aname, netlist_state_t(const pstring &aname,
netlist_t & anetlist,
plib::unique_ptr<callbacks_t> &&callbacks); plib::unique_ptr<callbacks_t> &&callbacks);
COPYASSIGNMOVE(netlist_state_t, delete) COPYASSIGNMOVE(netlist_state_t, delete)
~netlist_state_t() noexcept = default; /// \brief Destructor
///
/// The destructor is virtual to allow implementation specific devices
/// to connect to the outside world. For examples see MAME netlist.cpp.
///
virtual ~netlist_state_t() noexcept = default;
friend class netlist_t; // allow access to private members friend class netlist_t; // allow access to private members
@ -1428,8 +1440,8 @@ namespace netlist
plib::dynlib &lib() const noexcept { return *m_lib; } plib::dynlib &lib() const noexcept { return *m_lib; }
netlist_t &exec() { return m_netlist; } netlist_t &exec() { return *m_netlist; }
const netlist_t &exec() const { return m_netlist; } const netlist_t &exec() const { return *m_netlist; }
// state handling // state handling
plib::state_manager_t &run_state_manager() { return m_state; } plib::state_manager_t &run_state_manager() { return m_state; }
@ -1536,12 +1548,21 @@ namespace netlist
// sole use is to manage lifetime of family objects // sole use is to manage lifetime of family objects
std::unordered_map<pstring, plib::unique_ptr<logic_family_desc_t>> m_family_cache; std::unordered_map<pstring, plib::unique_ptr<logic_family_desc_t>> m_family_cache;
template<typename T, typename... Args>
unique_pool_ptr<T> make_object(Args&&... args)
{
return m_pool.make_unique<T>(std::forward<Args>(args)...);
}
// memory pool - still needed in some places
nlmempool &pool() noexcept { return m_pool; }
const nlmempool &pool() const noexcept { return m_pool; }
private: private:
void reset(); void reset();
nlmempool m_pool; // must be deleted last!
pstring m_name; pstring m_name;
netlist_t &m_netlist; unique_pool_ptr<netlist_t> m_netlist;
plib::unique_ptr<plib::dynlib> m_lib; // external lib needs to be loaded as long as netlist exists plib::unique_ptr<plib::dynlib> m_lib; // external lib needs to be loaded as long as netlist exists
plib::state_manager_t m_state; plib::state_manager_t m_state;
plib::unique_ptr<callbacks_t> m_callbacks; plib::unique_ptr<callbacks_t> m_callbacks;
@ -1599,7 +1620,7 @@ namespace netlist
{ {
public: public:
explicit netlist_t(const pstring &aname, plib::unique_ptr<callbacks_t> callbacks); explicit netlist_t(netlist_state_t &state);
COPYASSIGNMOVE(netlist_t, delete) COPYASSIGNMOVE(netlist_t, delete)
@ -1643,10 +1664,6 @@ namespace netlist
void stop(); void stop();
void reset(); void reset();
// state handling
plib::state_manager_t &run_state_manager() noexcept { return m_state->run_state_manager(); }
// only used by nltool to create static c-code // only used by nltool to create static c-code
devices::NETLIB_NAME(solver) *solver() const noexcept { return m_solver; } devices::NETLIB_NAME(solver) *solver() const noexcept { return m_solver; }
@ -1658,11 +1675,11 @@ namespace netlist
return static_cast<X *>(m_solver)->gmin(); return static_cast<X *>(m_solver)->gmin();
} }
netlist_state_t &nlstate() noexcept { return *m_state; } netlist_state_t &nlstate() noexcept { return m_state; }
const netlist_state_t &nlstate() const noexcept { return *m_state; } const netlist_state_t &nlstate() const noexcept { return m_state; }
log_type & log() noexcept { return m_state->log(); } log_type & log() noexcept { return m_state.log(); }
const log_type &log() const noexcept { return m_state->log(); } const log_type &log() const noexcept { return m_state.log(); }
void print_stats() const; void print_stats() const;
@ -1674,7 +1691,7 @@ namespace netlist
template <bool KEEP_STATS> template <bool KEEP_STATS>
void process_queue_stats(netlist_time delta) noexcept; void process_queue_stats(netlist_time delta) noexcept;
plib::unique_ptr<netlist_state_t> m_state; netlist_state_t & m_state;
devices::NETLIB_NAME(solver) * m_solver; devices::NETLIB_NAME(solver) * m_solver;
// mostly rw // mostly rw
@ -1725,6 +1742,12 @@ namespace netlist
return m_netlist.nlstate(); return m_netlist.nlstate();
} }
template<class C, typename... Args>
void device_t::create_and_register_subdevice(const pstring &name, unique_pool_ptr<C> &dev, Args&&... args)
{
dev = state().make_object<C>(*this, name, std::forward<Args>(args)...);
}
template <typename T> template <typename T>
param_num_t<T>::param_num_t(device_t &device, const pstring &name, const T val) param_num_t<T>::param_num_t(device_t &device, const pstring &name, const T val)
: param_t(device, name) : param_t(device, name)

View File

@ -76,9 +76,9 @@ namespace netlist { namespace factory
// factory_lib_entry_t: factory class to wrap macro based chips/elements // factory_lib_entry_t: factory class to wrap macro based chips/elements
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
unique_pool_ptr<device_t> library_element_t::Create(netlist_state_t &anetlist, const pstring &name) unique_pool_ptr<device_t> library_element_t::Create(nlmempool &pool, netlist_state_t &anetlist, const pstring &name)
{ {
return pool().make_unique<NETLIB_NAME(wrapper)>(anetlist, name); return pool.make_unique<NETLIB_NAME(wrapper)>(anetlist, name);
} }
void library_element_t::macro_actions(nlparse_t &nparser, const pstring &name) void library_element_t::macro_actions(nlparse_t &nparser, const pstring &name)

View File

@ -54,7 +54,10 @@ namespace factory {
COPYASSIGNMOVE(element_t, default) COPYASSIGNMOVE(element_t, default)
virtual unique_pool_ptr<device_t> Create(netlist_state_t &anetlist, const pstring &name) = 0; virtual unique_pool_ptr<device_t> Create(nlmempool &pool,
netlist_state_t &anetlist,
const pstring &name) = 0;
virtual void macro_actions(nlparse_t &nparser, const pstring &name) virtual void macro_actions(nlparse_t &nparser, const pstring &name)
{ {
plib::unused_var(nparser); plib::unused_var(nparser);
@ -84,9 +87,11 @@ namespace factory {
const pstring &def_param, const pstring &sourcefile) const pstring &def_param, const pstring &sourcefile)
: element_t(name, classname, def_param, sourcefile) { } : element_t(name, classname, def_param, sourcefile) { }
unique_pool_ptr<device_t> Create(netlist_state_t &anetlist, const pstring &name) override unique_pool_ptr<device_t> Create(nlmempool &pool,
netlist_state_t &anetlist,
const pstring &name) override
{ {
return pool().make_unique<C>(anetlist, name); return pool.make_unique<C>(anetlist, name);
} }
}; };
@ -146,7 +151,9 @@ namespace factory {
{ {
} }
unique_pool_ptr<device_t> Create(netlist_state_t &anetlist, const pstring &name) override; unique_pool_ptr<device_t> Create(nlmempool &pool,
netlist_state_t &anetlist,
const pstring &name) override;
void macro_actions(nlparse_t &nparser, const pstring &name) override; void macro_actions(nlparse_t &nparser, const pstring &name) override;

View File

@ -765,7 +765,7 @@ void setup_t::connect_terminals(detail::core_terminal_t &t1, detail::core_termin
{ {
log().debug("adding analog net ...\n"); log().debug("adding analog net ...\n");
// FIXME: Nets should have a unique name // FIXME: Nets should have a unique name
auto anet = pool().make_owned<analog_net_t>(m_nlstate,"net." + t1.name()); auto anet = nlstate().pool().make_owned<analog_net_t>(m_nlstate,"net." + t1.name());
auto anetp = anet.get(); auto anetp = anet.get();
m_nlstate.register_net(std::move(anet)); m_nlstate.register_net(std::move(anet));
t1.set_net(anetp); t1.set_net(anetp);
@ -961,7 +961,7 @@ void setup_t::register_dynamic_log_devices()
for (const pstring &ll : loglist) for (const pstring &ll : loglist)
{ {
pstring name = "log_" + ll; pstring name = "log_" + ll;
auto nc = factory().factory_by_name("LOG")->Create(m_nlstate, name); auto nc = factory().factory_by_name("LOG")->Create(m_nlstate.pool(), m_nlstate, name);
register_link(name + ".I", ll); register_link(name + ".I", ll);
log().debug(" dynamic link {1}: <{2}>\n",ll, name); log().debug(" dynamic link {1}: <{2}>\n",ll, name);
m_nlstate.register_device(nc->name(), std::move(nc)); m_nlstate.register_device(nc->name(), std::move(nc));
@ -1118,11 +1118,11 @@ public:
unique_pool_ptr<devices::nld_base_d_to_a_proxy> logic_family_std_proxy_t::create_d_a_proxy(netlist_state_t &anetlist, unique_pool_ptr<devices::nld_base_d_to_a_proxy> logic_family_std_proxy_t::create_d_a_proxy(netlist_state_t &anetlist,
const pstring &name, logic_output_t *proxied) const const pstring &name, logic_output_t *proxied) const
{ {
return pool().make_unique<devices::nld_d_to_a_proxy>(anetlist, name, proxied); return anetlist.make_object<devices::nld_d_to_a_proxy>(anetlist, name, proxied);
} }
unique_pool_ptr<devices::nld_base_a_to_d_proxy> logic_family_std_proxy_t::create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const unique_pool_ptr<devices::nld_base_a_to_d_proxy> logic_family_std_proxy_t::create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const
{ {
return pool().make_unique<devices::nld_a_to_d_proxy>(anetlist, name, proxied); return anetlist.make_object<devices::nld_a_to_d_proxy>(anetlist, name, proxied);
} }
@ -1205,7 +1205,7 @@ void setup_t::prepare_to_run()
if ( factory().is_class<devices::NETLIB_NAME(solver)>(e.second) if ( factory().is_class<devices::NETLIB_NAME(solver)>(e.second)
|| factory().is_class<devices::NETLIB_NAME(netlistparams)>(e.second)) || factory().is_class<devices::NETLIB_NAME(netlistparams)>(e.second))
{ {
m_nlstate.register_device(e.first, e.second->Create(m_nlstate, e.first)); m_nlstate.register_device(e.first, e.second->Create(nlstate().pool(), m_nlstate, e.first));
} }
} }
@ -1227,7 +1227,7 @@ void setup_t::prepare_to_run()
if ( !factory().is_class<devices::NETLIB_NAME(solver)>(e.second) if ( !factory().is_class<devices::NETLIB_NAME(solver)>(e.second)
&& !factory().is_class<devices::NETLIB_NAME(netlistparams)>(e.second)) && !factory().is_class<devices::NETLIB_NAME(netlistparams)>(e.second))
{ {
auto dev = e.second->Create(m_nlstate, e.first); auto dev = e.second->Create(m_nlstate.pool(), m_nlstate, e.first);
m_nlstate.register_device(dev->name(), std::move(dev)); m_nlstate.register_device(dev->name(), std::move(dev));
} }
} }

View File

@ -87,12 +87,6 @@ namespace netlist
template <typename T> template <typename T>
using unique_pool_ptr = nlmempool::unique_pool_ptr<T>; using unique_pool_ptr = nlmempool::unique_pool_ptr<T>;
inline nlmempool &pool()
{
static nlmempool static_pool;
return static_pool;
}
namespace detail { namespace detail {
/// \brief Enum specifying the type of object /// \brief Enum specifying the type of object

View File

@ -63,7 +63,7 @@ namespace plib {
{ {
// call destructor // call destructor
p->~T(); p->~T();
getref(m_a).deallocate(p); getref(m_a).deallocate(p, sizeof(T));
} }
//private: //private:
arena_storage_type m_a; arena_storage_type m_a;
@ -228,8 +228,7 @@ namespace plib {
void deallocate(T* p, std::size_t n) noexcept void deallocate(T* p, std::size_t n) noexcept
{ {
unused_var(n); m_a.deallocate(p, n);
m_a.deallocate(p);
} }
template <class AR1, class T1, std::size_t A1, class AR2, class T2, std::size_t A2> template <class AR1, class T1, std::size_t A1, class AR2, class T2, std::size_t A2>
@ -263,7 +262,9 @@ namespace plib {
struct aligned_arena struct aligned_arena
{ {
static constexpr const bool is_stateless = true; static constexpr const bool is_stateless = true;
template <class T, std::size_t ALIGN = alignof(T)> using size_type = std::size_t;
template <class T, size_type ALIGN = alignof(T)>
using allocator_type = arena_allocator<aligned_arena, T, ALIGN>; using allocator_type = arena_allocator<aligned_arena, T, ALIGN>;
template <typename T> template <typename T>
@ -298,8 +299,9 @@ namespace plib {
#endif #endif
} }
static inline void deallocate( void *ptr ) noexcept static inline void deallocate( void *ptr, size_t size ) noexcept
{ {
unused_var(size);
#if (PUSE_ALIGNED_ALLOCATION) #if (PUSE_ALIGNED_ALLOCATION)
// NOLINTNEXTLINE(cppcoreguidelines-no-malloc) // NOLINTNEXTLINE(cppcoreguidelines-no-malloc)
free(ptr); free(ptr);
@ -319,7 +321,7 @@ namespace plib {
} }
catch (...) catch (...)
{ {
deallocate(mem); deallocate(mem, sizeof(T));
throw; throw;
} }
} }
@ -335,7 +337,7 @@ namespace plib {
} }
catch (...) catch (...)
{ {
deallocate(mem); deallocate(mem, sizeof(T));
throw; throw;
} }
} }
@ -387,7 +389,7 @@ namespace plib {
inline void pdelete(T *ptr) noexcept inline void pdelete(T *ptr) noexcept
{ {
ptr->~T(); ptr->~T();
aligned_arena::deallocate(ptr); aligned_arena::deallocate(ptr, sizeof(T));
} }

View File

@ -72,11 +72,11 @@
/// \brief Number of bytes for cache line alignment /// \brief Number of bytes for cache line alignment
/// ///
#define PALIGN_CACHELINE (64) #define PALIGN_CACHELINE (16)
/// \brief Number of bytes for vector alignment /// \brief Number of bytes for vector alignment
/// ///
#define PALIGN_VECTOROPT (64) #define PALIGN_VECTOROPT (16)
#define PALIGNAS_CACHELINE() PALIGNAS(PALIGN_CACHELINE) #define PALIGNAS_CACHELINE() PALIGNAS(PALIGN_CACHELINE)
#define PALIGNAS_VECTOROPT() PALIGNAS(PALIGN_VECTOROPT) #define PALIGNAS_VECTOROPT() PALIGNAS(PALIGN_VECTOROPT)

View File

@ -19,12 +19,35 @@ namespace plib {
// terminate // terminate
//============================================================ //============================================================
void terminate(const pstring &msg) noexcept void terminate(const char *msg) noexcept
{ {
std::cerr << msg.c_str() << "\n"; try
{
std::cerr << msg << "\n";
}
catch (...)
{
/* ignore */
}
std::terminate(); std::terminate();
} }
void passert_fail(const char *assertion, const char *file, int lineno, const char *msg) noexcept
{
try
{
std::cerr << file << ":" << lineno << ": ";
if (msg != nullptr)
std::cerr << msg << "\n";
else
std::cerr << "Assertion '" << assertion << "' failed.\n";
}
catch (...)
{
/* ignore */
}
std::terminate();
}
//============================================================ //============================================================
// Exceptions // Exceptions

View File

@ -13,13 +13,22 @@
#include <exception> #include <exception>
#define passert_always(expr) \
((expr) ? static_cast<void>(0) : plib::passert_fail (#expr, __FILE__, __LINE__, nullptr))
#define passert_always_msg(expr, msg) \
((expr) ? static_cast<void>(0) : plib::passert_fail (#expr, __FILE__, __LINE__, msg))
namespace plib { namespace plib {
/// \brief Terminate the program. /// \brief Terminate the program.
/// ///
/// \note could be enhanced by setting a termination handler /// \note could be enhanced by setting a termination handler
/// ///
[[noreturn]] void terminate(const pstring &msg) noexcept; [[noreturn]] void terminate(const char *msg) noexcept;
[[noreturn]] void passert_fail(const char *assertion,
const char *file, int lineno, const char *msg) noexcept;
/// \brief throw an exception. /// \brief throw an exception.
/// ///

View File

@ -8,6 +8,7 @@
/// \file pmempool.h /// \file pmempool.h
/// ///
#include "pconfig.h"
#include "palloc.h" #include "palloc.h"
#include "pstream.h" #include "pstream.h"
#include "pstring.h" #include "pstring.h"
@ -28,80 +29,21 @@ namespace plib {
class mempool class mempool
{ {
private:
struct block
{
block(mempool &mp, std::size_t min_bytes)
: m_num_alloc(0)
, m_cur(0)
, m_data(nullptr)
, m_mempool(mp)
{
min_bytes = std::max(mp.m_min_alloc, min_bytes);
m_free = min_bytes;
std::size_t alloc_bytes = (min_bytes + mp.m_min_align); // - 1); // & ~(mp.m_min_align - 1);
//m_data_allocated = ::operator new(alloc_bytes);
m_data_allocated = new char[alloc_bytes];
void *r = m_data_allocated;
std::align(mp.m_min_align, min_bytes, r, alloc_bytes);
m_data = reinterpret_cast<char *>(r);
}
~block()
{
//::operator delete(m_data_allocated);
delete [] m_data_allocated;
}
block(const block &) = delete;
block(block &&) = delete;
block &operator =(const block &) = delete;
block &operator =(block &&) = delete;
std::size_t m_num_alloc;
std::size_t m_free;
std::size_t m_cur;
char *m_data;
char *m_data_allocated;
mempool &m_mempool;
};
struct info
{
info(block *b, std::size_t p) : m_block(b), m_pos(p) { }
~info() = default;
COPYASSIGNMOVE(info, default)
block * m_block;
std::size_t m_pos;
};
block * new_block(std::size_t min_bytes)
{
auto *b = plib::pnew<block>(*this, min_bytes);
m_blocks.push_back(b);
return b;
}
static std::unordered_map<void *, info> &sinfo()
{
static std::unordered_map<void *, info> spinfo;
return spinfo;
}
size_t m_min_alloc;
size_t m_min_align;
std::vector<block *> m_blocks;
public: public:
using size_type = std::size_t;
static constexpr const bool is_stateless = false; static constexpr const bool is_stateless = false;
template <class T, std::size_t ALIGN = alignof(T)>
template <class T, size_type ALIGN = alignof(T)>
using allocator_type = arena_allocator<mempool, T, ALIGN>; using allocator_type = arena_allocator<mempool, T, ALIGN>;
mempool(size_t min_alloc = (1<<21), size_t min_align = 16) mempool(size_t min_alloc = (1<<21), size_t min_align = PALIGN_CACHELINE)
: m_min_alloc(min_alloc), m_min_align(min_align) : m_min_alloc(min_alloc)
, m_min_align(min_align)
, m_stat_cur_alloc(0)
, m_stat_max_alloc(0)
{ {
} }
@ -156,29 +98,32 @@ namespace plib {
sinfo().insert({ ret, info(b, b->m_cur)}); sinfo().insert({ ret, info(b, b->m_cur)});
rs -= (capacity - size); rs -= (capacity - size);
b->m_cur += rs; b->m_cur += rs;
m_stat_cur_alloc += size;
m_stat_max_alloc = std::max(m_stat_max_alloc, m_stat_cur_alloc);
return ret; return ret;
} }
static void deallocate(void *ptr) static void deallocate(void *ptr, size_t size)
{ {
auto it = sinfo().find(ptr); auto it = sinfo().find(ptr);
if (it == sinfo().end()) if (it == sinfo().end())
plib::terminate("mempool::free - pointer not found\n"); plib::terminate("mempool::free - pointer not found");
block *b = it->second.m_block; block *b = it->second.m_block;
if (b->m_num_alloc == 0) if (b->m_num_alloc == 0)
plib::terminate("mempool::free - double free was called\n"); plib::terminate("mempool::free - double free was called");
else else
{ {
mempool &mp = b->m_mempool;
b->m_num_alloc--; b->m_num_alloc--;
mp.m_stat_cur_alloc -= size;
//printf("Freeing in block %p %lu\n", b, b->m_num_alloc); //printf("Freeing in block %p %lu\n", b, b->m_num_alloc);
if (b->m_num_alloc == 0) if (b->m_num_alloc == 0)
{ {
mempool &mp = b->m_mempool;
auto itb = std::find(mp.m_blocks.begin(), mp.m_blocks.end(), b); auto itb = std::find(mp.m_blocks.begin(), mp.m_blocks.end(), b);
if (itb == mp.m_blocks.end()) if (itb == mp.m_blocks.end())
plib::terminate("mempool::free - block not found\n"); plib::terminate("mempool::free - block not found");
mp.m_blocks.erase(itb); mp.m_blocks.erase(itb);
plib::pdelete(b); plib::pdelete(b);
@ -204,7 +149,7 @@ namespace plib {
} }
catch (...) catch (...)
{ {
this->deallocate(mem); this->deallocate(mem, sizeof(T));
throw; throw;
} }
} }
@ -220,13 +165,85 @@ namespace plib {
} }
catch (...) catch (...)
{ {
this->deallocate(mem); this->deallocate(mem, sizeof(T));
throw; throw;
} }
} }
size_type cur_alloc() const noexcept { return m_stat_cur_alloc; }
size_type max_alloc() const noexcept { return m_stat_max_alloc; }
bool operator ==(const mempool &rhs) const noexcept { return this == &rhs; } bool operator ==(const mempool &rhs) const noexcept { return this == &rhs; }
private:
struct block
{
block(mempool &mp, size_type min_bytes)
: m_num_alloc(0)
, m_cur(0)
, m_data(nullptr)
, m_mempool(mp)
{
min_bytes = std::max(mp.m_min_alloc, min_bytes);
m_free = min_bytes;
size_type alloc_bytes = (min_bytes + mp.m_min_align); // - 1); // & ~(mp.m_min_align - 1);
//m_data_allocated = ::operator new(alloc_bytes);
m_data_allocated = new char[alloc_bytes];
void *r = m_data_allocated;
std::align(mp.m_min_align, min_bytes, r, alloc_bytes);
m_data = reinterpret_cast<char *>(r);
}
~block()
{
//::operator delete(m_data_allocated);
delete [] m_data_allocated;
}
block(const block &) = delete;
block(block &&) = delete;
block &operator =(const block &) = delete;
block &operator =(block &&) = delete;
size_type m_num_alloc;
size_type m_free;
size_type m_cur;
char *m_data;
char *m_data_allocated;
mempool &m_mempool;
};
struct info
{
info(block *b, size_type p) : m_block(b), m_pos(p) { }
~info() = default;
COPYASSIGNMOVE(info, default)
block * m_block;
size_type m_pos;
};
block * new_block(size_type min_bytes)
{
auto *b = plib::pnew<block>(*this, min_bytes);
m_blocks.push_back(b);
return b;
}
static std::unordered_map<void *, info> &sinfo()
{
static std::unordered_map<void *, info> spinfo;
return spinfo;
}
size_t m_min_alloc;
size_t m_min_align;
std::vector<block *> m_blocks;
size_t m_stat_cur_alloc;
size_t m_stat_max_alloc;
}; };
} // namespace plib } // namespace plib

View File

@ -28,16 +28,22 @@ public:
struct datatype_t struct datatype_t
{ {
datatype_t(std::size_t bsize, bool bintegral, bool bfloat) datatype_t(std::size_t bsize, bool bintegral, bool bfloat)
: size(bsize), is_integral(bintegral), is_float(bfloat), is_custom(false) : m_size(bsize), m_is_integral(bintegral), m_is_float(bfloat), m_is_custom(false)
{} {}
explicit datatype_t(bool bcustom) explicit datatype_t(bool bcustom)
: size(0), is_integral(false), is_float(false), is_custom(bcustom) : m_size(0), m_is_integral(false), m_is_float(false), m_is_custom(bcustom)
{} {}
const std::size_t size; std::size_t size() const noexcept { return m_size; }
const bool is_integral; bool is_integral() const noexcept { return m_is_integral; }
const bool is_float; bool is_float() const noexcept { return m_is_float; }
const bool is_custom; bool is_custom() const noexcept { return m_is_custom; }
private:
std::size_t m_size;
bool m_is_integral;
bool m_is_float;
bool m_is_custom;
}; };
template<typename T> template<typename T>
@ -64,7 +70,7 @@ public:
struct entry_t struct entry_t
{ {
using list_t = std::vector<plib::unique_ptr<entry_t>>; using list_t = std::vector<entry_t>;
entry_t(const pstring &stname, const datatype_t &dt, const void *owner, entry_t(const pstring &stname, const datatype_t &dt, const void *owner,
const std::size_t count, void *ptr) const std::size_t count, void *ptr)
@ -73,11 +79,19 @@ public:
entry_t(const pstring &stname, const void *owner, callback_t *callback) entry_t(const pstring &stname, const void *owner, callback_t *callback)
: m_name(stname), m_dt(datatype_t(true)), m_owner(owner), m_callback(callback), m_count(0), m_ptr(nullptr) { } : m_name(stname), m_dt(datatype_t(true)), m_owner(owner), m_callback(callback), m_count(0), m_ptr(nullptr) { }
pstring name() const noexcept { return m_name; }
datatype_t dt() const noexcept { return m_dt; }
const void * owner() const noexcept { return m_owner; }
callback_t * callback() const noexcept { return m_callback; }
std::size_t count() const noexcept { return m_count; }
void * ptr() const noexcept { return m_ptr; }
private:
pstring m_name; pstring m_name;
const datatype_t m_dt; datatype_t m_dt;
const void * m_owner; const void * m_owner;
callback_t * m_callback; callback_t * m_callback;
const std::size_t m_count; std::size_t m_count;
void * m_ptr; void * m_ptr;
}; };
@ -115,19 +129,19 @@ public:
void save_state_ptr(const void *owner, const pstring &stname, const datatype_t &dt, const std::size_t count, void *ptr) void save_state_ptr(const void *owner, const pstring &stname, const datatype_t &dt, const std::size_t count, void *ptr)
{ {
m_save.push_back(plib::make_unique<entry_t>(stname, dt, owner, count, ptr)); m_save.emplace_back(stname, dt, owner, count, ptr);
} }
void pre_save() void pre_save()
{ {
for (auto & s : m_custom) for (auto & s : m_custom)
s->m_callback->on_pre_save(*this); s.callback()->on_pre_save(*this);
} }
void post_load() void post_load()
{ {
for (auto & s : m_custom) for (auto & s : m_custom)
s->m_callback->on_post_load(*this); s.callback()->on_post_load(*this);
} }
void remove_save_items(const void *owner) void remove_save_items(const void *owner)
@ -136,14 +150,14 @@ public:
while (i != m_save.begin()) while (i != m_save.begin())
{ {
i--; i--;
if (i->get()->m_owner == owner) if (i->owner() == owner)
i = m_save.erase(i); i = m_save.erase(i);
} }
i = m_custom.end(); i = m_custom.end();
while (i > m_custom.begin()) while (i > m_custom.begin())
{ {
i--; i--;
if (i->get()->m_owner == owner) if (i->owner() == owner)
i = m_custom.erase(i); i = m_custom.erase(i);
} }
} }
@ -152,7 +166,7 @@ public:
{ {
std::vector<const entry_t *> ret; std::vector<const entry_t *> ret;
for (auto &i : m_save) for (auto &i : m_save)
ret.push_back(i.get()); ret.push_back(&i);
return ret; return ret;
} }
@ -166,7 +180,7 @@ private:
template<> inline void state_manager_t::save_item(const void *owner, callback_t &state, const pstring &stname) template<> inline void state_manager_t::save_item(const void *owner, callback_t &state, const pstring &stname)
{ {
m_custom.push_back(plib::make_unique<entry_t>(stname, owner, &state)); m_custom.emplace_back(stname, owner, &state);
state.register_state(*this, stname); state.register_state(*this, stname);
} }

View File

@ -201,17 +201,15 @@ private:
tool_app_t &m_app; tool_app_t &m_app;
}; };
class netlist_tool_t : public netlist::netlist_t class netlist_tool_t : public netlist::netlist_state_t
{ {
public: public:
netlist_tool_t(tool_app_t &app, const pstring &aname) netlist_tool_t(tool_app_t &app, const pstring &aname)
: netlist::netlist_t(aname, plib::make_unique<netlist_tool_callbacks_t>(app)) : netlist::netlist_state_t(aname, plib::make_unique<netlist_tool_callbacks_t>(app))
{ {
} }
netlist::setup_t &setup() { return nlstate().setup(); }
void read_netlist(const pstring &filename, const pstring &name, void read_netlist(const pstring &filename, const pstring &name,
const std::vector<pstring> &logs, const std::vector<pstring> &logs,
const std::vector<pstring> &defines, const std::vector<pstring> &defines,
@ -254,19 +252,19 @@ public:
run_state_manager().pre_save(); run_state_manager().pre_save();
std::size_t size = 0; std::size_t size = 0;
for (auto const & s : run_state_manager().save_list()) for (auto const & s : run_state_manager().save_list())
size += s->m_dt.size * s->m_count; size += s->dt().size() * s->count();
std::vector<char> buf(size); std::vector<char> buf(size);
char *p = buf.data(); char *p = buf.data();
for (auto const & s : run_state_manager().save_list()) for (auto const & s : run_state_manager().save_list())
{ {
std::size_t sz = s->m_dt.size * s->m_count; std::size_t sz = s->dt().size() * s->count();
if (s->m_dt.is_float || s->m_dt.is_integral) if (s->dt().is_float() || s->dt().is_integral())
std::copy(static_cast<char *>(s->m_ptr), std::copy(static_cast<char *>(s->ptr()),
static_cast<char *>(s->m_ptr) + sz, p); static_cast<char *>(s->ptr()) + sz, p);
else else
log().fatal("found unsupported save element {1}\n", s->m_name); log().fatal("found unsupported save element {1}\n", s->name());
p += sz; p += sz;
} }
return buf; return buf;
@ -276,7 +274,7 @@ public:
{ {
std::size_t size = 0; std::size_t size = 0;
for (auto const & s : run_state_manager().save_list()) for (auto const & s : run_state_manager().save_list())
size += s->m_dt.size * s->m_count; size += s->dt().size() * s->count();
if (buf.size() != size) if (buf.size() != size)
plib::pthrow<netlist::nl_exception>("Size different during load state."); plib::pthrow<netlist::nl_exception>("Size different during load state.");
@ -285,15 +283,15 @@ public:
for (auto const & s : run_state_manager().save_list()) for (auto const & s : run_state_manager().save_list())
{ {
std::size_t sz = s->m_dt.size * s->m_count; std::size_t sz = s->dt().size() * s->count();
if (s->m_dt.is_float || s->m_dt.is_integral) if (s->dt().is_float() || s->dt().is_integral())
std::copy(p, p + sz, static_cast<char *>(s->m_ptr)); std::copy(p, p + sz, static_cast<char *>(s->ptr()));
else else
log().fatal("found unsupported save element {1}\n", s->m_name); log().fatal("found unsupported save element {1}\n", s->name());
p += sz; p += sz;
} }
run_state_manager().post_load(); run_state_manager().post_load();
nlstate().rebuild_lists(); this->rebuild_lists();
} }
protected: protected:
@ -388,7 +386,7 @@ void tool_app_t::run()
auto t_guard(t.guard()); auto t_guard(t.guard());
//plib::perftime_t<plib::exact_ticks> t; //plib::perftime_t<plib::exact_ticks> t;
nt.enable_stats(opt_stats()); nt.exec().enable_stats(opt_stats());
if (!opt_verb()) if (!opt_verb())
nt.log().verbose.set_enabled(false); nt.log().verbose.set_enabled(false);
@ -399,7 +397,7 @@ void tool_app_t::run()
opt_logs(), opt_logs(),
m_defines, opt_rfolders(), opt_includes()); m_defines, opt_rfolders(), opt_includes());
nt.reset(); nt.exec().reset();
inps = read_input(nt.setup(), opt_inp()); inps = read_input(nt.setup(), opt_inp());
ttr = netlist::netlist_time::from_fp(opt_ttr()); ttr = netlist::netlist_time::from_fp(opt_ttr());
@ -410,7 +408,7 @@ void tool_app_t::run()
t.reset(); t.reset();
netlist::netlist_time nlt = nt.time(); netlist::netlist_time nlt = nt.exec().time();
{ {
auto t_guard(t.guard()); auto t_guard(t.guard());
@ -425,7 +423,7 @@ void tool_app_t::run()
std::vector<char> loadstate; std::vector<char> loadstate;
reader.read(loadstate); reader.read(loadstate);
nt.load_state(loadstate); nt.load_state(loadstate);
pout("Loaded state, run will continue at {1:.6f}\n", nt.time().as_double()); pout("Loaded state, run will continue at {1:.6f}\n", nt.exec().time().as_double());
} }
unsigned pos = 0; unsigned pos = 0;
@ -435,7 +433,7 @@ void tool_app_t::run()
&& inps[pos].m_time < ttr && inps[pos].m_time < ttr
&& inps[pos].m_time >= nlt) && inps[pos].m_time >= nlt)
{ {
nt.process_queue(inps[pos].m_time - nlt); nt.exec().process_queue(inps[pos].m_time - nlt);
inps[pos].setparam(); inps[pos].setparam();
nlt = inps[pos].m_time; nlt = inps[pos].m_time;
pos++; pos++;
@ -444,7 +442,7 @@ void tool_app_t::run()
pout("runnning ...\n"); pout("runnning ...\n");
if (ttr > nlt) if (ttr > nlt)
nt.process_queue(ttr - nlt); nt.exec().process_queue(ttr - nlt);
else else
{ {
pout("end time {1:.6f} less than saved time {2:.6f}\n", pout("end time {1:.6f} less than saved time {2:.6f}\n",
@ -463,7 +461,7 @@ void tool_app_t::run()
plib::pbinary_writer writer(strm); plib::pbinary_writer writer(strm);
writer.write(savestate); writer.write(savestate);
} }
nt.stop(); nt.exec().stop();
} }
auto emutime(t.as_seconds<nl_fptype>()); auto emutime(t.as_seconds<nl_fptype>());
@ -526,11 +524,11 @@ void tool_app_t::static_compile()
// need to reset ... // need to reset ...
nt.reset(); nt.exec().reset();
std::map<pstring, pstring> mp; std::map<pstring, pstring> mp;
nt.solver()->create_solver_code(mp); nt.exec().solver()->create_solver_code(mp);
for (auto &e : mp) for (auto &e : mp)
{ {
@ -538,7 +536,7 @@ void tool_app_t::static_compile()
sout << e.second; sout << e.second;
} }
nt.stop(); nt.exec().stop();
} }
@ -758,7 +756,7 @@ void tool_app_t::create_header()
} }
pout("#endif // __PLIB_PREPROCESSOR__\n"); pout("#endif // __PLIB_PREPROCESSOR__\n");
pout("#endif\n"); pout("#endif\n");
nt.stop(); nt.exec().stop();
} }
@ -875,7 +873,7 @@ void tool_app_t::create_docheader()
} }
} }
} }
nt.stop(); nt.exec().stop();
} }
@ -904,7 +902,7 @@ void tool_app_t::listdevices()
pstring out = plib::pfmt("{1:-20} {2}(<id>")(f->classname())(f->name()); pstring out = plib::pfmt("{1:-20} {2}(<id>")(f->classname())(f->name());
f->macro_actions(nt.setup(), f->name() + "_lc"); f->macro_actions(nt.setup(), f->name() + "_lc");
auto d = f->Create(nt.nlstate(), f->name() + "_lc"); auto d = f->Create(nt.pool(), nt, f->name() + "_lc");
// get the list of terminals ... // get the list of terminals ...
std::vector<pstring> terms(nt.setup().get_terminals_for_device_name(d->name())); std::vector<pstring> terms(nt.setup().get_terminals_for_device_name(d->name()));

View File

@ -109,7 +109,7 @@ namespace solver
{ {
pstring nname(this->name() + "." + pstring(plib::pfmt("m{1}")(m_inps.size()))); pstring nname(this->name() + "." + pstring(plib::pfmt("m{1}")(m_inps.size())));
nl_assert(p->net().is_analog()); nl_assert(p->net().is_analog());
auto net_proxy_output_u = pool().make_unique<proxied_analog_output_t>(*this, nname, static_cast<analog_net_t *>(&p->net())); auto net_proxy_output_u = state().make_object<proxied_analog_output_t>(*this, nname, static_cast<analog_net_t *>(&p->net()));
net_proxy_output = net_proxy_output_u.get(); net_proxy_output = net_proxy_output_u.get();
m_inps.emplace_back(std::move(net_proxy_output_u)); m_inps.emplace_back(std::move(net_proxy_output_u));
} }
@ -336,7 +336,6 @@ namespace solver
{ {
pstring num = plib::pfmt("{1}")(k); pstring num = plib::pfmt("{1}")(k);
// FIXME: This shouldn't be necessary, recalculate on each entry ...
state().save(*this, m_gonn[k],"GO" + num, this->name(), m_terms[k].count()); state().save(*this, m_gonn[k],"GO" + num, this->name(), m_terms[k].count());
state().save(*this, m_gtn[k],"GT" + num, this->name(), m_terms[k].count()); state().save(*this, m_gtn[k],"GT" + num, this->name(), m_terms[k].count());
state().save(*this, m_Idrn[k],"IDR" + num, this->name(), m_terms[k].count()); state().save(*this, m_Idrn[k],"IDR" + num, this->name(), m_terms[k].count());