More netlist refactoring:

- Remove virtual from some destructors and make them protected. 
- Various cleanups.
- Small performance improvement. 
- Fixed some inconsistencies. 
- More c++ refactoring. (nw)
This commit is contained in:
couriersud 2017-01-24 09:14:49 +01:00
parent 25152bd69a
commit ba03118b09
31 changed files with 267 additions and 276 deletions

View File

@ -619,11 +619,11 @@ void netlist_mame_cpu_device_t::device_start()
netlist::detail::net_t *n = netlist().m_nets[i].get();
if (n->is_logic())
{
state_add(i*2, n->name().c_str(), downcast<netlist::logic_net_t *>(n)->Q_state_ptr());
state_add(i*2, n->name().c_str(), *downcast<netlist::logic_net_t *>(n)->Q_state_ptr());
}
else
{
state_add(i*2+1, n->name().c_str(), downcast<netlist::analog_net_t *>(n)->Q_Analog_state_ptr()).formatstr("%20s");
state_add(i*2+1, n->name().c_str(), *downcast<netlist::analog_net_t *>(n)->Q_Analog_state_ptr()).formatstr("%20s");
}
}

View File

@ -5,9 +5,10 @@
*
*/
#include <solver/nld_solver.h>
#include <algorithm>
#include "solver/nld_solver.h"
#include "nld_twoterm.h"
namespace netlist

View File

@ -5,7 +5,7 @@
*
*/
#include <devices/nlid_cmos.h>
#include "devices/nlid_cmos.h"
#include "nld_4020.h"
namespace netlist

View File

@ -5,7 +5,7 @@
*
*/
#include <devices/nlid_cmos.h>
#include "devices/nlid_cmos.h"
#include "analog/nld_twoterm.h"
#include "nld_4066.h"

View File

@ -5,7 +5,7 @@
*
*/
#include <devices/nlid_cmos.h>
#include "devices/nlid_cmos.h"
#include "analog/nld_twoterm.h"
#include "nld_4316.h"

View File

@ -82,7 +82,7 @@ namespace netlist
netlist_time delay = NLTIME_FROM_NS(26);
if (m_CLRQ())
{
bool clear_unset = !m_last_CLRQ();
bool clear_unset = !m_last_CLRQ;
if (clear_unset)
{
delay = NLTIME_FROM_NS(35);

View File

@ -29,8 +29,8 @@ namespace netlist
logic_input_t m_I;
logic_output_t m_Q;
state_var_u8 m_reset;
state_var_u8 m_state;
state_var<netlist_sig_t> m_reset;
state_var<netlist_sig_t> m_state;
};
NETLIB_OBJECT(7493)
@ -99,7 +99,7 @@ namespace netlist
NETLIB_UPDATE(7493ff)
{
constexpr netlist_time out_delay = NLTIME_FROM_NS(18);
static constexpr netlist_time out_delay = NLTIME_FROM_NS(18);
if (m_reset)
{
m_state ^= 1;

View File

@ -158,21 +158,22 @@ namespace netlist
{
if (m_loadq)
{
switch (m_cnt())
if (m_cnt < MAXCNT - 1)
{
case MAXCNT - 1:
m_cnt = MAXCNT;
m_RC.push(m_ent, NLTIME_FROM_NS(20));
m_QA.push(1, NLTIME_FROM_NS(20));
break;
case MAXCNT:
m_RC.push(0, NLTIME_FROM_NS(20));
m_cnt = 0;
update_outputs_all(m_cnt, NLTIME_FROM_NS(20));
break;
default:
m_cnt++;
update_outputs(m_cnt);
m_cnt++;
update_outputs(m_cnt);
}
else if (m_cnt == MAXCNT - 1)
{
m_cnt = MAXCNT;
m_RC.push(m_ent, NLTIME_FROM_NS(20));
m_QA.push(1, NLTIME_FROM_NS(20));
}
else // MAXCNT
{
m_RC.push(0, NLTIME_FROM_NS(20));
m_cnt = 0;
update_outputs_all(m_cnt, NLTIME_FROM_NS(20));
}
}
else

View File

@ -161,22 +161,22 @@ namespace netlist
{
if (m_loadq)
{
switch (m_cnt())
if (m_cnt < MAXCNT - 1)
{
case MAXCNT - 1:
m_cnt = MAXCNT;
m_RC.push(m_ent, NLTIME_FROM_NS(27));
m_QA.push(1, NLTIME_FROM_NS(20));
break;
case MAXCNT:
m_RC.push(0, NLTIME_FROM_NS(27));
m_cnt = 0;
update_outputs_all(m_cnt, NLTIME_FROM_NS(20));
break;
default:
m_cnt++;
update_outputs_all(m_cnt, NLTIME_FROM_NS(20));
break;
m_cnt++;
update_outputs_all(m_cnt, NLTIME_FROM_NS(20));
}
else if (m_cnt == MAXCNT - 1)
{
m_cnt = MAXCNT;
m_RC.push(m_ent, NLTIME_FROM_NS(27));
m_QA.push(1, NLTIME_FROM_NS(20));
}
else // MAXCNT
{
m_RC.push(0, NLTIME_FROM_NS(27));
m_cnt = 0;
update_outputs_all(m_cnt, NLTIME_FROM_NS(20));
}
}
else

View File

@ -6,7 +6,7 @@
*/
#include "nld_mm5837.h"
#include <solver/nld_matrix_solver.h>
#include "solver/nld_matrix_solver.h"
#include "analog/nld_twoterm.h"
#define R_LOW (1000.0)

View File

@ -7,7 +7,7 @@
#include "nld_ne555.h"
#include "analog/nld_twoterm.h"
#include <solver/nld_solver.h>
#include "solver/nld_solver.h"
#define R_OFF (1E20)
#define R_ON (25) // Datasheet states a maximum discharge of 200mA, R = 5V / 0.2

View File

@ -5,8 +5,8 @@
*
*/
#include <solver/nld_solver.h>
#include <solver/nld_matrix_solver.h>
#include "solver/nld_solver.h"
#include "solver/nld_matrix_solver.h"
#include "nlid_system.h"
namespace netlist

View File

@ -8,6 +8,7 @@
#include "nld_truthtable.h"
#include "plib/plists.h"
#include "nl_setup.h"
#include "plib/palloc.h"
namespace netlist
{
@ -272,7 +273,7 @@ netlist_base_factory_truthtable_t::~netlist_base_factory_truthtable_t()
#define ENTRYY(n, m, s) case (n * 100 + m): \
{ using xtype = netlist_factory_truthtable_t<n, m>; \
ret = new xtype(desc.name, desc.classname, desc.def_param, s); } break
ret = plib::palloc<xtype>(desc.name, desc.classname, desc.def_param, s); } break
#define ENTRY(n, s) ENTRYY(n, 1, s); ENTRYY(n, 2, s); ENTRYY(n, 3, s); \
ENTRYY(n, 4, s); ENTRYY(n, 5, s); ENTRYY(n, 6, s)

View File

@ -113,9 +113,9 @@ namespace netlist
{
pstring devname = out_proxied->device().name();
auto tp = netlist().setup().find_terminal(devname + "." + power_syms[i][0],
detail::device_object_t::type_t::INPUT, false);
detail::core_terminal_t::type_t::INPUT, false);
auto tn = netlist().setup().find_terminal(devname + "." + power_syms[i][1],
detail::device_object_t::type_t::INPUT, false);
detail::core_terminal_t::type_t::INPUT, false);
if (tp != nullptr && tn != nullptr)
{
/* alternative logic */

View File

@ -25,7 +25,7 @@ namespace netlist
namespace detail
{
#if (USE_MEMPOOL)
static plib::mempool pool(65536, 8);
static plib::mempool pool(6553600, 64);
void * object_t::operator new (size_t size)
{
@ -184,7 +184,7 @@ void detail::queue_t::on_post_load()
detail::net_t *n = netlist().find_net(pstring(m_names[i].m_buf, pstring::UTF8));
//log().debug("Got {1} ==> {2}\n", qtemp[i].m_name, n));
//log().debug("schedule time {1} ({2})\n", n->time().as_double(), netlist_time::from_raw(m_times[i]).as_double()));
this->push(n, netlist_time::from_raw(m_times[i]));
this->push(queue_t::entry_t(netlist_time::from_raw(m_times[i]),n));
}
}
@ -216,20 +216,18 @@ detail::device_object_t::device_object_t(core_device_t &dev, const pstring &anam
{
}
detail::device_object_t::type_t detail::device_object_t::type() const
detail::core_terminal_t::type_t detail::core_terminal_t::type() const
{
if (dynamic_cast<const terminal_t *>(this) != nullptr)
return type_t::TERMINAL;
else if (dynamic_cast<const param_t *>(this) != nullptr)
return param_t::PARAM;
else if (dynamic_cast<const logic_input_t *>(this) != nullptr)
return param_t::INPUT;
return type_t::INPUT;
else if (dynamic_cast<const logic_output_t *>(this) != nullptr)
return param_t::OUTPUT;
return type_t::OUTPUT;
else if (dynamic_cast<const analog_input_t *>(this) != nullptr)
return param_t::INPUT;
return type_t::INPUT;
else if (dynamic_cast<const analog_output_t *>(this) != nullptr)
return param_t::OUTPUT;
return type_t::OUTPUT;
else
{
netlist().log().fatal(MF_1_UNKNOWN_TYPE_FOR_OBJECT, name());
@ -254,19 +252,16 @@ netlist_t::netlist_t(const pstring &aname)
{
state().save_item(this, static_cast<plib::state_manager_t::callback_t &>(m_queue), "m_queue");
state().save_item(this, m_time, "m_time");
m_setup = new setup_t(*this);
m_setup = plib::make_unique<setup_t>(*this);
/* FIXME: doesn't really belong here */
NETLIST_NAME(base)(*m_setup);
}
netlist_t::~netlist_t()
{
if (m_setup != nullptr)
delete m_setup;
m_nets.clear();
m_devices.clear();
pfree(m_lib);
pstring::resetmem();
}
@ -356,7 +351,7 @@ void netlist_t::start()
}
pstring libpath = plib::util::environment("NL_BOOSTLIB", plib::util::buildpath({".", "nlboost.so"}));
m_lib = plib::palloc<plib::dynlib>(libpath);
m_lib = plib::make_unique<plib::dynlib>(libpath);
/* resolve inputs */
setup().resolve_inputs();
@ -448,7 +443,7 @@ void netlist_t::process_queue(const netlist_time &delta)
{
netlist_time stop(m_time + delta);
m_queue.push(nullptr, stop);
m_queue.push(detail::queue_t::entry_t(stop, nullptr));
m_stat_mainloop.start();
@ -475,17 +470,20 @@ void netlist_t::process_queue(const netlist_time &delta)
while (m_queue.top().m_exec_time > mc_time)
{
m_time = mc_time;
mc_time += inc;
mc_net.toggle_new_Q();
mc_net.update_devs();
mc_time += inc;
}
const detail::queue_t::entry_t e(m_queue.pop());
m_time = e.m_exec_time;
if (e.m_object == nullptr)
if (e.m_object != nullptr)
{
e.m_object->update_devs();
m_perf_out_processed.inc();
}
else
break;
e.m_object->update_devs();
m_perf_out_processed.inc();
}
mc_net.set_time(mc_time);
}
@ -686,13 +684,6 @@ detail::family_setter_t::family_setter_t(core_device_t &dev, const logic_family_
// net_t
// ----------------------------------------------------------------------------------------
// FIXME: move somewhere central
struct do_nothing_deleter{
template<typename T> void operator()(T*){}
};
detail::net_t::net_t(netlist_t &nl, const pstring &aname, core_terminal_t *mr)
: object_t(aname)
, netlist_ref(nl)
@ -725,7 +716,7 @@ void detail::net_t::inc_active(core_terminal_t &term) NL_NOEXCEPT
if (m_time > netlist().time())
{
m_in_queue = 1; /* pending */
netlist().queue().push(this, m_time);
netlist().queue().push(queue_t::entry_t(m_time, this));
}
else
{
@ -1100,11 +1091,11 @@ param_double_t::param_double_t(device_t &device, const pstring name, const doubl
m_param = device.setup().get_initial_param_val(this->name(),val);
netlist().save(*this, m_param, "m_param");
}
#if 0
param_double_t::~param_double_t()
{
}
#endif
param_int_t::param_int_t(device_t &device, const pstring name, const int val)
: param_t(device, name)
{
@ -1112,9 +1103,11 @@ param_int_t::param_int_t(device_t &device, const pstring name, const int val)
netlist().save(*this, m_param, "m_param");
}
#if 0
param_int_t::~param_int_t()
{
}
#endif
param_logic_t::param_logic_t(device_t &device, const pstring name, const bool val)
: param_t(device, name)
@ -1123,9 +1116,11 @@ param_logic_t::param_logic_t(device_t &device, const pstring name, const bool va
netlist().save(*this, m_param, "m_param");
}
#if 0
param_logic_t::~param_logic_t()
{
}
#endif
param_ptr_t::param_ptr_t(device_t &device, const pstring name, uint8_t * val)
: param_t(device, name)
@ -1134,9 +1129,11 @@ param_ptr_t::param_ptr_t(device_t &device, const pstring name, uint8_t * val)
//netlist().save(*this, m_param, "m_param");
}
#if 0
param_ptr_t::~param_ptr_t()
{
}
#endif
void param_model_t::changed()
{

View File

@ -29,7 +29,7 @@
// ----------------------------------------------------------------------------------------
/*! netlist_sig_t is the type used for logic signals. */
using netlist_sig_t = std::uint_least32_t;
using netlist_sig_t = std::uint32_t;
//============================================================
// MACROS / New Syntax
@ -281,12 +281,12 @@ namespace netlist
public:
logic_family_t() : m_logic_family(nullptr) {}
~logic_family_t() { }
const logic_family_desc_t *logic_family() const { return m_logic_family; }
void set_logic_family(const logic_family_desc_t *fam) { m_logic_family = fam; }
protected:
~logic_family_t() { } // prohibit polymorphic destruction
const logic_family_desc_t *m_logic_family;
};
@ -321,19 +321,15 @@ namespace netlist
//! Move Constructor.
state_var(state_var &&rhs) NL_NOEXCEPT = default;
//! Assignment operator to assign value of a state var.
state_var &operator=(state_var rhs) { std::swap(rhs.m_value, this->m_value); return *this; }
state_var &operator=(const state_var &rhs) { m_value = rhs; return *this; }
//! Assignment operator to assign value of type T.
state_var &operator=(const T rhs) { m_value = rhs; return *this; }
state_var &operator=(const T &rhs) { m_value = rhs; return *this; }
//! Return value of state variable.
operator T & () { return m_value; }
//! Return value of state variable.
T & operator()() { return m_value; }
//! Return const value of state variable.
operator const T & () const { return m_value; }
//! Return const value of state variable.
const T & operator()() const { return m_value; }
constexpr operator const T & () const { return m_value; }
T * ptr() { return &m_value; }
const T * ptr() const { return &m_value; }
constexpr T * ptr() const { return &m_value; }
private:
T m_value;
};
@ -346,13 +342,20 @@ namespace netlist
struct state_var<T[N]>
{
public:
state_var(device_t &dev, const pstring name, const T & value);
//! Constructor.
template <typename O>
state_var(O &owner, //!< owner must have a netlist() method.
const pstring name, //!< identifier/name for this state variable
const T &value //!< Initial value after construction
);
//! Copy Constructor.
state_var(const state_var &rhs) NL_NOEXCEPT = default;
//! Move Constructor.
state_var(state_var &&rhs) NL_NOEXCEPT = default;
state_var &operator=(const state_var rhs) { m_value = rhs.m_value; return *this; }
state_var &operator=(const T rhs) { m_value = rhs; return *this; }
state_var &operator=(const state_var &rhs) { m_value = rhs.m_value; return *this; }
state_var &operator=(const T &rhs) { m_value = rhs; return *this; }
T & operator[](const std::size_t i) { return m_value[i]; }
const T & operator[](const std::size_t i) const { return m_value[i]; }
constexpr T & operator[](const std::size_t i) const { return m_value[i]; }
private:
T m_value[N];
};
@ -392,7 +395,6 @@ namespace netlist
* Every class derived from the object_t class must have a name.
*/
object_t(const pstring &aname /*!< string containing name of the object */);
virtual ~object_t();
/*! return name of the object
*
@ -404,6 +406,8 @@ namespace netlist
void operator delete (void *ptr, void *) { }
void * operator new (size_t size);
void operator delete (void * mem);
protected:
~object_t(); // only childs should be destructible
private:
pstring m_name;
@ -412,11 +416,13 @@ namespace netlist
struct detail::netlist_ref
{
netlist_ref(netlist_t &nl) : m_netlist(nl) { }
~netlist_ref() {}
netlist_t & netlist() { return m_netlist; }
const netlist_t & netlist() const { return m_netlist; }
protected:
~netlist_ref() {} // prohibit polymorphic destruction
private:
netlist_t & m_netlist;
@ -435,14 +441,6 @@ namespace netlist
{
P_PREVENT_COPYING(device_object_t)
public:
/*! Enum specifying the type of object */
enum type_t {
TERMINAL = 0, /*!< object is an analog terminal */
INPUT = 1, /*!< object is an input */
OUTPUT = 2, /*!< object is an output */
PARAM = 3, /*!< object is a parameter */
};
/*! Constructor.
*
* \param dev device owning the object.
@ -454,16 +452,6 @@ namespace netlist
*/
core_device_t &device() const { return m_device; }
/*! The object type.
* \returns type of the object
*/
type_t type() const;
/*! Checks if object is of specified type.
* \param atype type to check object against.
* \returns true if object is of specified type else false.
*/
bool is_type(const type_t atype) const { return (type() == atype); }
/*! The netlist owning the owner of this object.
* \returns reference to netlist object.
*/
@ -500,9 +488,26 @@ namespace netlist
STATE_BIDIR = 256
};
/*! Enum specifying the type of object */
enum type_t {
TERMINAL = 0, /*!< object is an analog terminal */
INPUT = 1, /*!< object is an input */
OUTPUT = 2, /*!< object is an output */
};
core_terminal_t(core_device_t &dev, const pstring &aname, const state_e state);
virtual ~core_terminal_t();
/*! The object type.
* \returns type of the object
*/
type_t type() const;
/*! Checks if object is of specified type.
* \param atype type to check object against.
* \returns true if object is of specified type else false.
*/
bool is_type(const type_t atype) const { return (type() == atype); }
void set_net(net_t *anet);
void clear_net();
bool has_net() const { return (m_net != nullptr); }
@ -706,12 +711,6 @@ namespace netlist
void reset();
void add_terminal(core_terminal_t &terminal);
void remove_terminal(core_terminal_t &terminal);
bool is_logic() const NL_NOEXCEPT;
bool is_analog() const NL_NOEXCEPT;
void toggle_new_Q() { m_new_Q ^= 1; }
void force_queue_execution() { m_new_Q = (m_cur_Q ^ 1); }
@ -732,6 +731,14 @@ namespace netlist
void inc_active(core_terminal_t &term) NL_NOEXCEPT;
void dec_active(core_terminal_t &term) NL_NOEXCEPT;
/* setup stuff */
void add_terminal(core_terminal_t &terminal);
void remove_terminal(core_terminal_t &terminal);
bool is_logic() const NL_NOEXCEPT;
bool is_analog() const NL_NOEXCEPT;
void rebuild_list(); /* rebuild m_list after a load */
void move_connections(net_t &dest_net);
@ -764,7 +771,7 @@ namespace netlist
virtual ~logic_net_t();
netlist_sig_t Q() const { return m_cur_Q; }
netlist_sig_t new_Q() const { return m_new_Q; }
netlist_sig_t new_Q() const { return m_new_Q; }
void initial(const netlist_sig_t val) { m_cur_Q = m_new_Q = val; }
void set_Q(const netlist_sig_t newQ, const netlist_time delay) NL_NOEXCEPT
@ -789,7 +796,7 @@ namespace netlist
/* internal state support
* FIXME: get rid of this and implement export/import in MAME
*/
netlist_sig_t &Q_state_ptr() { return m_cur_Q; }
netlist_sig_t *Q_state_ptr() { return m_cur_Q.ptr(); }
protected:
private:
@ -808,7 +815,7 @@ namespace netlist
virtual ~analog_net_t();
nl_double Q_Analog() const { return m_cur_Analog; }
nl_double &Q_Analog_state_ptr() { return m_cur_Analog; }
nl_double *Q_Analog_state_ptr() { return m_cur_Analog.ptr(); }
//FIXME: needed by current solver code
devices::matrix_solver_t *solver() const { return m_solver; }
@ -874,11 +881,12 @@ namespace netlist
};
param_t(device_t &device, const pstring &name);
virtual ~param_t();
param_type_t param_type() const;
protected:
virtual ~param_t(); /* not intended to be destroyed */
void update_param();
template<typename C>
@ -897,7 +905,6 @@ namespace netlist
{
public:
param_ptr_t(device_t &device, const pstring name, std::uint8_t* val);
virtual ~param_ptr_t();
std::uint8_t * operator()() const { return m_param; }
void setTo(std::uint8_t *param) { set(m_param, param); }
private:
@ -908,7 +915,6 @@ namespace netlist
{
public:
param_logic_t(device_t &device, const pstring name, const bool val);
virtual ~param_logic_t();
bool operator()() const { return m_param; }
void setTo(const bool &param) { set(m_param, param); }
private:
@ -919,7 +925,6 @@ namespace netlist
{
public:
param_int_t(device_t &device, const pstring name, const int val);
virtual ~param_int_t();
int operator()() const { return m_param; }
void setTo(const int &param) { set(m_param, param); }
private:
@ -930,7 +935,6 @@ namespace netlist
{
public:
param_double_t(device_t &device, const pstring name, const double val);
virtual ~param_double_t();
double operator()() const { return m_param; }
void setTo(const double &param) { set(m_param, param); }
private:
@ -942,6 +946,7 @@ namespace netlist
public:
param_str_t(device_t &device, const pstring name, const pstring val);
virtual ~param_str_t();
const pstring operator()() const { return Value(); }
void setTo(const pstring &param)
{
@ -1128,7 +1133,7 @@ namespace netlist
template<class C, typename... Args>
void register_sub(const pstring &name, std::unique_ptr<C> &dev, const Args&... args)
{
dev.reset(new C(*this, name, args...));
dev.reset(plib::palloc<C>(*this, name, args...));
}
void register_subalias(const pstring &name, detail::core_terminal_t &term);
@ -1309,9 +1314,9 @@ namespace netlist
devices::NETLIB_NAME(netlistparams) *m_params;
pstring m_name;
setup_t * m_setup;
std::unique_ptr<setup_t> m_setup;
plib::plog_base<NL_DEBUG> m_log;
plib::dynlib * m_lib; // external lib needs to be loaded as long as netlist exists
std::unique_ptr<plib::dynlib> m_lib; // external lib needs to be loaded as long as netlist exists
plib::state_manager_t m_state;
@ -1421,7 +1426,7 @@ namespace netlist
m_time = netlist().time() + delay;
m_in_queue = (m_active > 0); /* queued ? */
if (m_in_queue)
netlist().queue().push(this, m_time);
netlist().queue().push(queue_t::entry_t(m_time, this));
}
}
@ -1433,7 +1438,7 @@ namespace netlist
m_time = netlist().time() + delay;
m_in_queue = (m_active > 0); /* queued ? */
if (m_in_queue)
netlist().queue().push(this, m_time);
netlist().queue().push(queue_t::entry_t(m_time, this));
}
inline const analog_net_t & analog_t::net() const NL_NOEXCEPT
@ -1450,7 +1455,7 @@ namespace netlist
inline logic_net_t & logic_t::net() NL_NOEXCEPT
{
return *static_cast<logic_net_t *>(&core_terminal_t::net());
return static_cast<logic_net_t &>(core_terminal_t::net());
}
inline const logic_net_t & logic_t::net() const NL_NOEXCEPT
@ -1487,9 +1492,10 @@ namespace netlist
}
template <typename T, std::size_t N>
state_var<T[N]>::state_var(device_t &dev, const pstring name, const T & value)
template <typename O>
state_var<T[N]>::state_var(O &owner, const pstring name, const T & value)
{
dev.netlist().save(dev, m_value, name);
owner.netlist().save(owner, m_value, name);
for (std::size_t i=0; i<N; i++)
m_value[i] = value;
}
@ -1506,5 +1512,14 @@ namespace netlist
}
namespace plib
{
template<typename X>
struct ptype_traits<netlist::state_var<X>> : ptype_traits<X>
{
};
}
#endif /* NLBASE_H_ */

View File

@ -17,12 +17,11 @@
#include "plib/putil.h"
#include "nl_base.h"
#if 1
#define NETLIB_DEVICE_IMPL(chip) \
static std::unique_ptr<factory::element_t> NETLIB_NAME(chip ## _c)( \
const pstring &name, const pstring &classname, const pstring &def_param) \
{ \
return std::unique_ptr<factory::element_t>(new factory::device_element_t<NETLIB_NAME(chip)>(name, classname, def_param, pstring(__FILE__))); \
return std::unique_ptr<factory::element_t>(plib::palloc<factory::device_element_t<NETLIB_NAME(chip)>>(name, classname, def_param, pstring(__FILE__))); \
} \
factory::constructor_ptr_t decl_ ## chip = NETLIB_NAME(chip ## _c);
@ -30,16 +29,10 @@
static std::unique_ptr<factory::element_t> NETLIB_NAME(chip ## _c)( \
const pstring &name, const pstring &classname, const pstring &def_param) \
{ \
return std::unique_ptr<factory::element_t>(new factory::device_element_t<ns :: NETLIB_NAME(chip)>(name, classname, def_param, pstring(__FILE__))); \
return std::unique_ptr<factory::element_t>(plib::palloc<factory::device_element_t<ns :: NETLIB_NAME(chip)>>(name, classname, def_param, pstring(__FILE__))); \
} \
factory::constructor_ptr_t decl_ ## chip = NETLIB_NAME(chip ## _c);
#else
#define NETLIB_DEVICE_IMPL(chip) factory::constructor_ptr_t decl_ ## chip = factory::constructor_t< NETLIB_NAME(chip) >;
#define NETLIB_DEVICE_IMPL_NS(ns, chip) factory::constructor_ptr_t decl_ ## chip = factory::constructor_t< ns :: NETLIB_NAME(chip) >;
#endif
namespace netlist { namespace factory
{
// -----------------------------------------------------------------------------
@ -99,7 +92,7 @@ namespace netlist { namespace factory
void register_device(const pstring &name, const pstring &classname,
const pstring &def_param)
{
register_device(std::unique_ptr<element_t>(new device_element_t<device_class>(name, classname, def_param)));
register_device(std::unique_ptr<element_t>(plib::palloc<device_element_t<device_class>>(name, classname, def_param)));
}
void register_device(std::unique_ptr<element_t> factory);
@ -127,7 +120,7 @@ namespace netlist { namespace factory
std::unique_ptr<element_t> constructor_t(const pstring &name, const pstring &classname,
const pstring &def_param)
{
return std::unique_ptr<element_t>(new device_element_t<T>(name, classname, def_param));
return std::unique_ptr<element_t>(plib::palloc<device_element_t<T>>(name, classname, def_param));
}
// -----------------------------------------------------------------------------

View File

@ -11,6 +11,8 @@
#define NLLISTS_H_
#include <atomic>
#include <thread>
#include <mutex>
#include "nl_config.h"
#include "plib/plists.h"
@ -26,30 +28,24 @@ namespace netlist
//FIXME: move to an appropriate place
template<bool enabled_ = true>
class pspin_lock
class pspin_mutex
{
public:
pspin_lock() { }
void acquire() noexcept{ while (m_lock.test_and_set(std::memory_order_acquire)) { } }
void release() noexcept { m_lock.clear(std::memory_order_release); }
pspin_mutex() noexcept { }
void lock() noexcept{ while (m_lock.test_and_set(std::memory_order_acquire)) { } }
void unlock() noexcept { m_lock.clear(std::memory_order_release); }
private:
std::atomic_flag m_lock = ATOMIC_FLAG_INIT;
};
template<>
class pspin_lock<false>
class pspin_mutex<false>
{
public:
void acquire() const noexcept { }
void release() const noexcept { }
void lock() const noexcept { }
void unlock() const noexcept { }
};
#if HAS_OPENMP && USE_OPENMP
using tqlock = pspin_lock<true>;
#else
using tqlock = pspin_lock<false>;
#endif
template <class Element, class Time>
class timed_queue
{
@ -58,6 +54,18 @@ namespace netlist
struct entry_t
{
entry_t() { }
entry_t(const Time &t, const Element &o) : m_exec_time(t), m_object(o) { }
entry_t(const entry_t &e) : m_exec_time(e.m_exec_time), m_object(e.m_object) { }
entry_t(entry_t &&e) : m_exec_time(e.m_exec_time), m_object(e.m_object) { }
entry_t& operator=(entry_t && other)
{
m_exec_time = other.m_exec_time;
m_object = other.m_object;
return *this;
}
Time m_exec_time;
Element m_object;
};
@ -65,37 +73,35 @@ namespace netlist
timed_queue(unsigned list_size)
: m_list(list_size)
{
m_lock.acquire();
clear();
m_lock.release();
}
std::size_t capacity() const { return m_list.size(); }
bool empty() const { return (m_end == &m_list[1]); }
void push(Element o, const Time t) noexcept
void push(entry_t &&e) noexcept
{
/* Lock */
m_lock.acquire();
tqlock lck(m_lock);
entry_t * i = m_end;
for (; t > (i - 1)->m_exec_time; --i)
while (e.m_exec_time > (i - 1)->m_exec_time)
{
*(i) = *(i-1);
*(i) = std::move(*(i-1));
--i;
m_prof_sortmove.inc();
}
*i = { t, o };
*i = std::move(e);
++m_end;
m_prof_call.inc();
m_lock.release();
}
entry_t pop() noexcept { return *(--m_end); }
const entry_t &top() const noexcept { return *(m_end-1); }
entry_t pop() noexcept { return std::move(*(--m_end)); }
const entry_t &top() const noexcept { return std::move(*(m_end-1)); }
void remove(const Element &elem) noexcept
{
/* Lock */
m_lock.acquire();
tqlock lck(m_lock);
for (entry_t * i = m_end - 1; i > &m_list[0]; i--)
{
if (i->m_object == elem)
@ -103,24 +109,23 @@ namespace netlist
m_end--;
while (i < m_end)
{
*i = *(i+1);
*i = std::move(*(i+1));
++i;
}
m_lock.release();
return;
}
}
m_lock.release();
}
void retime(const Element &elem, const Time t) noexcept
{
remove(elem);
push(elem, t);
push(entry_t(t, elem));
}
void clear()
{
tqlock lck(m_lock);
m_end = &m_list[0];
/* put an empty element with maximum time into the queue.
* the insert algo above will run into this element and doesn't
@ -137,8 +142,14 @@ namespace netlist
const entry_t & operator[](const std::size_t index) const { return m_list[ 1 + index]; }
private:
#if HAS_OPENMP && USE_OPENMP
using tqmutex = pspin_mutex<true>;
#else
using tqmutex = pspin_mutex<false>;
#endif
using tqlock = std::lock_guard<tqmutex>;
tqlock m_lock;
tqmutex m_lock;
entry_t * m_end;
std::vector<entry_t> m_list;

View File

@ -135,7 +135,7 @@ void setup_t::register_dippins_arr(const pstring &terms)
}
}
pstring setup_t::objtype_as_str(detail::device_object_t &in) const
pstring setup_t::termtype_as_str(detail::core_terminal_t &in) const
{
switch (in.type())
{
@ -145,8 +145,6 @@ pstring setup_t::objtype_as_str(detail::device_object_t &in) const
return pstring("INPUT");
case terminal_t::OUTPUT:
return pstring("OUTPUT");
case terminal_t::PARAM:
return pstring("PARAM");
}
// FIXME: noreturn
log().fatal(MF_1_UNKNOWN_OBJECT_TYPE_1, static_cast<unsigned>(in.type()));
@ -199,9 +197,9 @@ void setup_t::register_param(pstring name, param_t &param)
void setup_t::register_term(detail::core_terminal_t &term)
{
if (!m_terminals.insert({term.name(), &term}).second)
log().fatal(MF_2_ADDING_1_2_TO_TERMINAL_LIST, objtype_as_str(term),
log().fatal(MF_2_ADDING_1_2_TO_TERMINAL_LIST, termtype_as_str(term),
term.name());
log().debug("{1} {2}\n", objtype_as_str(term), term.name());
log().debug("{1} {2}\n", termtype_as_str(term), term.name());
}
void setup_t::register_link_arr(const pstring &terms)
@ -340,12 +338,12 @@ detail::core_terminal_t *setup_t::find_terminal(const pstring &terminal_in, bool
}
detail::core_terminal_t *setup_t::find_terminal(const pstring &terminal_in,
detail::device_object_t::type_t atype, bool required)
detail::core_terminal_t::type_t atype, bool required)
{
const pstring &tname = resolve_alias(terminal_in);
auto ret = m_terminals.find(tname);
/* look for default */
if (ret == m_terminals.end() && atype == detail::device_object_t::OUTPUT)
if (ret == m_terminals.end() && atype == detail::core_terminal_t::OUTPUT)
{
/* look for ".Q" std output */
ret = m_terminals.find(tname + ".Q");
@ -440,7 +438,6 @@ devices::nld_base_proxy *setup_t::get_a_d_proxy(detail::core_terminal_t &inp)
auto ret = new_proxy.get();
#if 1
/* connect all existing terminals to new net */
if (inp.has_net())
@ -455,13 +452,6 @@ devices::nld_base_proxy *setup_t::get_a_d_proxy(detail::core_terminal_t &inp)
inp.net().m_core_terms.clear(); // clear the list
}
ret->out().net().add_terminal(inp);
#else
if (inp.has_net())
//fatalerror("logic inputs can only belong to one net!\n");
merge_nets(ret->out().net(), inp.net());
else
ret->out().net().add_terminal(inp);
#endif
netlist().register_dev(std::move(new_proxy));
return ret;
}

View File

@ -285,7 +285,7 @@ namespace netlist
std::unordered_map<pstring, detail::core_terminal_t *> m_terminals;
/* needed by proxy */
detail::core_terminal_t *find_terminal(const pstring &outname_in, detail::device_object_t::type_t atype, bool required = true);
detail::core_terminal_t *find_terminal(const pstring &outname_in, detail::core_terminal_t::type_t atype, bool required = true);
private:
@ -300,7 +300,7 @@ namespace netlist
bool connect_input_input(detail::core_terminal_t &t1, detail::core_terminal_t &t2);
// helpers
pstring objtype_as_str(detail::device_object_t &in) const;
pstring termtype_as_str(detail::core_terminal_t &in) const;
devices::nld_base_proxy *get_d_a_proxy(detail::core_terminal_t &out);
devices::nld_base_proxy *get_a_d_proxy(detail::core_terminal_t &inp);

View File

@ -45,82 +45,83 @@ namespace netlist
constexpr explicit ptime(const internal_type nom, const internal_type den) noexcept
: m_time(nom * (resolution / den)) { }
ptime &operator=(const ptime rhs) { m_time = rhs.m_time; return *this; }
ptime &operator=(const ptime rhs) noexcept { m_time = rhs.m_time; return *this; }
ptime &operator+=(const ptime &rhs) { m_time += rhs.m_time; return *this; }
ptime &operator-=(const ptime &rhs) { m_time -= rhs.m_time; return *this; }
ptime &operator+=(const ptime &rhs) noexcept { m_time += rhs.m_time; return *this; }
ptime &operator-=(const ptime &rhs) noexcept { m_time -= rhs.m_time; return *this; }
friend ptime operator-(ptime lhs, const ptime &rhs)
friend constexpr ptime operator-(const ptime &lhs, const ptime &rhs) noexcept
{
lhs -= rhs;
return lhs;
return ptime(lhs.m_time - rhs.m_time);
}
friend ptime operator+(ptime lhs, const ptime &rhs)
friend constexpr ptime operator+(const ptime &lhs, const ptime &rhs) noexcept
{
lhs += rhs;
return lhs;
return ptime(lhs.m_time + rhs.m_time);
}
friend ptime operator*(ptime lhs, const mult_type factor)
friend constexpr ptime operator*(const ptime &lhs, const mult_type factor) noexcept
{
lhs.m_time *= static_cast<internal_type>(factor);
return lhs;
return ptime(lhs.m_time * static_cast<internal_type>(factor));
}
friend mult_type operator/(const ptime &lhs, const ptime &rhs)
friend constexpr mult_type operator/(const ptime &lhs, const ptime &rhs) noexcept
{
return static_cast<mult_type>(lhs.m_time / rhs.m_time);
}
friend bool operator<(const ptime &lhs, const ptime &rhs)
friend constexpr bool operator<(const ptime &lhs, const ptime &rhs) noexcept
{
return (lhs.m_time < rhs.m_time);
}
friend bool operator>(const ptime &lhs, const ptime &rhs)
friend constexpr bool operator>(const ptime &lhs, const ptime &rhs) noexcept
{
return (rhs < lhs);
}
friend bool operator<=(const ptime &lhs, const ptime &rhs)
friend constexpr bool operator<=(const ptime &lhs, const ptime &rhs) noexcept
{
return !(lhs > rhs);
}
friend bool operator>=(const ptime &lhs, const ptime &rhs)
friend constexpr bool operator>=(const ptime &lhs, const ptime &rhs) noexcept
{
return !(lhs < rhs);
}
friend bool operator==(const ptime &lhs, const ptime &rhs)
friend constexpr bool operator==(const ptime &lhs, const ptime &rhs) noexcept
{
return lhs.m_time == rhs.m_time;
}
friend bool operator!=(const ptime &lhs, const ptime &rhs)
friend constexpr bool operator!=(const ptime &lhs, const ptime &rhs) noexcept
{
return !(lhs == rhs);
}
constexpr internal_type as_raw() const { return m_time; }
constexpr double as_double() const { return static_cast<double>(m_time)
/ static_cast<double>(resolution); }
constexpr internal_type as_raw() const noexcept { return m_time; }
constexpr double as_double() const noexcept
{
return static_cast<double>(m_time)
/ static_cast<double>(resolution);
}
// for save states ....
internal_type *get_internaltype_ptr() { return &m_time; }
internal_type *get_internaltype_ptr() noexcept { return &m_time; }
static constexpr ptime from_nsec(const internal_type ns) { return ptime(ns, UINT64_C(1000000000)); }
static constexpr ptime from_usec(const internal_type us) { return ptime(us, UINT64_C(1000000)); }
static constexpr ptime from_msec(const internal_type ms) { return ptime(ms, UINT64_C(1000)); }
static constexpr ptime from_hz(const internal_type hz) { return ptime(1 , hz); }
static constexpr ptime from_raw(const internal_type raw) { return ptime(raw, resolution); }
static constexpr ptime from_double(const double t) { return ptime(static_cast<internal_type>( t * static_cast<double>(resolution)), resolution); }
static constexpr ptime from_nsec(const internal_type ns) noexcept { return ptime(ns, UINT64_C(1000000000)); }
static constexpr ptime from_usec(const internal_type us) noexcept { return ptime(us, UINT64_C(1000000)); }
static constexpr ptime from_msec(const internal_type ms) noexcept { return ptime(ms, UINT64_C(1000)); }
static constexpr ptime from_hz(const internal_type hz) noexcept { return ptime(1 , hz); }
static constexpr ptime from_raw(const internal_type raw) noexcept { return ptime(raw); }
static constexpr ptime from_double(const double t) noexcept { return ptime(static_cast<internal_type>( t * static_cast<double>(resolution)), resolution); }
static constexpr ptime zero() { return ptime(0, resolution); }
static constexpr ptime quantum() { return ptime(1, resolution); }
static constexpr ptime never() { return ptime(plib::numeric_limits<internal_type>::max(), resolution); }
static constexpr ptime zero() noexcept { return ptime(0, resolution); }
static constexpr ptime quantum() noexcept { return ptime(1, resolution); }
static constexpr ptime never() noexcept { return ptime(plib::numeric_limits<internal_type>::max(), resolution); }
private:
constexpr explicit ptime(const internal_type time) : m_time(time) {}
internal_type m_time;
};

View File

@ -41,6 +41,9 @@ typedef __int128_t INT128;
#endif
#if defined(__GNUC__)
#ifdef RESTRICT
#undef RESTRICT
#endif
#define RESTRICT __restrict__
#define ATTR_UNUSED __attribute__((__unused__))
#else
@ -240,7 +243,7 @@ namespace plib {
inline R call(O *obj, Targs... args) const
{
using function_ptr = MEMBER_ABI R (*)(O *obj, Targs... args);
return (*reinterpret_cast<function_ptr>(m_func))(obj, std::forward<Targs>(args)...);
return (reinterpret_cast<function_ptr>(m_func))(obj, std::forward<Targs>(args)...);
}
private:
generic_function m_func;

View File

@ -56,6 +56,7 @@ public:
template<typename... Args>
void emplace(const std::size_t index, Args&&... args)
{
// allocate on buffer
new (&m_buf[index]) C(std::forward<Args>(args)...);
}

View File

@ -502,30 +502,11 @@ static const pstring pmf_verbose[] =
};
#endif
struct tt
{
void test(int a) {printf ("test :%d\n", a);}
int test1() { return 1;}
};
plib::pmfp<void, int> atest;
plib::pmfp<int> atest1;
int main(int argc, char *argv[])
{
tool_options_t opts;
int ret;
tt x;
atest.set(&tt::test, &x);
atest1.set(&tt::test1, &x);
atest(1);
int a = atest1();
printf("%d\n", a);
//return 1 ;
/* make SIGFPE actually deliver signals on supoorted platforms */
plib::fpsignalenabler::global_enable(true);
plib::fpsignalenabler sigen(plib::FP_ALL & ~plib::FP_INEXACT & ~plib::FP_UNDERFLOW);

View File

@ -1,13 +1,12 @@
// license:GPL-2.0+
// copyright-holders:Couriersud
#include <plib/poptions.h>
#include <cstdio>
#include <cstring>
#include "plib/pstring.h"
#include "plib/plists.h"
#include "plib/pstream.h"
#include "plib/poptions.h"
#include "nl_setup.h"
#include <memory>
class nlwav_options_t : public plib::options
{
@ -143,10 +142,10 @@ private:
static void convert()
{
plib::postream *fo = (opts.opt_out() == "-" ? &pout_strm : new plib::pofilestream(opts.opt_out()));
plib::pistream *fin = (opts.opt_inp() == "-" ? &pin_strm : new plib::pifilestream(opts.opt_inp()));
plib::postream *fo = (opts.opt_out() == "-" ? &pout_strm : plib::palloc<plib::pofilestream>(opts.opt_out()));
plib::pistream *fin = (opts.opt_inp() == "-" ? &pin_strm : plib::palloc<plib::pifilestream>(opts.opt_inp()));
plib::putf8_reader reader(*fin);
wav_t *wo = new wav_t(*fo, 48000);
wav_t *wo = plib::palloc<wav_t>(*fo, 48000U);
double dt = 1.0 / static_cast<double>(wo->sample_rate());
double ct = dt;
@ -213,11 +212,11 @@ static void convert()
//printf("%f %f\n", t, v);
#endif
}
delete wo;
plib::pfree(wo);
if (opts.opt_inp() != "-")
delete fin;
plib::pfree(fin);
if (opts.opt_out() != "-")
delete fo;
plib::pfree(fo);
if (!opts.opt_quiet())
{

View File

@ -91,11 +91,6 @@ matrix_solver_t::matrix_solver_t(netlist_t &anetlist, const pstring &name,
matrix_solver_t::~matrix_solver_t()
{
for (unsigned k = 0; k < m_terms.size(); k++)
{
plib::pfree(m_terms[k]);
}
}
void matrix_solver_t::setup_base(analog_net_t::list_t &nets)
@ -109,7 +104,7 @@ void matrix_solver_t::setup_base(analog_net_t::list_t &nets)
for (auto & net : nets)
{
m_nets.push_back(net);
m_terms.push_back(plib::palloc<terms_for_net_t>());
m_terms.push_back(plib::make_unique<terms_for_net_t>());
m_rails_temp.push_back(plib::palloc<terms_for_net_t>());
}
@ -164,7 +159,6 @@ void matrix_solver_t::setup_base(analog_net_t::list_t &nets)
}
break;
case terminal_t::OUTPUT:
case terminal_t::PARAM:
log().fatal(MF_1_UNHANDLED_ELEMENT_1_FOUND,
p->name());
break;
@ -242,7 +236,7 @@ void matrix_solver_t::setup_matrix()
/* create a list of non zero elements. */
for (unsigned k = 0; k < iN; k++)
{
terms_for_net_t * t = m_terms[k];
terms_for_net_t * t = m_terms[k].get();
/* pretty brutal */
int *other = t->connected_net_idx();
@ -264,7 +258,7 @@ void matrix_solver_t::setup_matrix()
*/
for (unsigned k = 0; k < iN; k++)
{
terms_for_net_t * t = m_terms[k];
terms_for_net_t * t = m_terms[k].get();
/* pretty brutal */
int *other = t->connected_net_idx();
@ -294,9 +288,9 @@ void matrix_solver_t::setup_matrix()
* This should reduce cache misses ...
*/
bool **touched = new bool*[iN];
bool **touched = plib::palloc_array<bool *>(iN);
for (unsigned k=0; k<iN; k++)
touched[k] = new bool[iN];
touched[k] = plib::palloc_array<bool>(iN);
for (unsigned k = 0; k < iN; k++)
{
@ -354,8 +348,8 @@ void matrix_solver_t::setup_matrix()
}
for (unsigned k=0; k<iN; k++)
delete [] touched[k];
delete [] touched;
plib::pfree_array(touched[k]);
plib::pfree_array(touched);
}
void matrix_solver_t::update_inputs()
@ -499,7 +493,7 @@ netlist_time matrix_solver_t::compute_next_timestep(const double cur_ts)
for (std::size_t k = 0, iN=m_terms.size(); k < iN; k++)
{
analog_net_t *n = m_nets[k];
terms_for_net_t *t = m_terms[k];
terms_for_net_t *t = m_terms[k].get();
const nl_double DD_n = (n->Q_Analog() - t->m_last_V);
const nl_double hn = cur_ts;
@ -548,12 +542,12 @@ void matrix_solver_t::log_stats()
log().verbose(" {1:6.3} average newton raphson loops",
static_cast<double>(this->m_stat_newton_raphson) / static_cast<double>(this->m_stat_vsolver_calls));
log().verbose(" {1:10} invocations ({2:6.0} Hz) {3:10} gs fails ({4:6.2} %) {5:6.3} average",
this->m_stat_calculations(),
static_cast<double>(this->m_stat_calculations()) / this->netlist().time().as_double(),
this->m_iterative_fail(),
100.0 * static_cast<double>(this->m_iterative_fail())
/ static_cast<double>(this->m_stat_calculations()),
static_cast<double>(this->m_iterative_total()) / static_cast<double>(this->m_stat_calculations()));
this->m_stat_calculations,
static_cast<double>(this->m_stat_calculations) / this->netlist().time().as_double(),
this->m_iterative_fail,
100.0 * static_cast<double>(this->m_iterative_fail)
/ static_cast<double>(this->m_stat_calculations),
static_cast<double>(this->m_iterative_total) / static_cast<double>(this->m_stat_calculations));
}
}

View File

@ -161,7 +161,7 @@ protected:
template <typename T>
void build_LE_RHS();
std::vector<terms_for_net_t *> m_terms;
std::vector<std::unique_ptr<terms_for_net_t>> m_terms;
std::vector<analog_net_t *> m_nets;
std::vector<std::unique_ptr<proxied_analog_output_t>> m_inps;

View File

@ -200,7 +200,7 @@ void matrix_solver_direct_t<m_N, storage_N>::vsetup(analog_net_t::list_t &nets)
/* add RHS element */
for (unsigned k = 0; k < N(); k++)
{
terms_for_net_t * t = m_terms[k];
terms_for_net_t * t = m_terms[k].get();
if (!plib::container::contains(t->m_nzrd, N()))
t->m_nzrd.push_back(N());

View File

@ -96,7 +96,7 @@ void matrix_solver_GCR_t<m_N, storage_N>::vsetup(analog_net_t::list_t &nets)
bool touched[storage_N][storage_N] = { { false } };
for (unsigned k = 0; k < iN; k++)
{
for (auto & j : this->m_terms[k]->m_nz)
for (auto &j : this->m_terms[k]->m_nz)
touched[k][j] = true;
}
@ -255,7 +255,7 @@ unsigned matrix_solver_GCR_t<m_N, storage_N>::vsolve_non_dynamic(const bool newt
for (unsigned k = 0; k < iN; k++)
{
terms_for_net_t *t = this->m_terms[k];
terms_for_net_t *t = this->m_terms[k].get();
nl_double gtot_t = 0.0;
nl_double RHS_t = 0.0;

View File

@ -81,7 +81,7 @@ void matrix_solver_GMRES_t<m_N, storage_N>::vsetup(analog_net_t::list_t &nets)
for (unsigned k=0; k<iN; k++)
{
terms_for_net_t * RESTRICT row = this->m_terms[k];
terms_for_net_t * RESTRICT row = this->m_terms[k].get();
mat.ia[k] = nz;
for (unsigned j=0; j<row->m_nz.size(); j++)

View File

@ -297,12 +297,12 @@ void NETLIB_NAME(solver)::post_start()
switch (net_count)
{
#if 1
#if 0
case 1:
ms = create_solver<1,1>(1, use_specific);
ms = create_solver<1,1>(1, false);
break;
case 2:
ms = create_solver<2,2>(2, use_specific);
ms = create_solver<2,2>(2, false);
break;
case 3:
ms = create_solver<3,3>(3, use_specific);
@ -322,6 +322,9 @@ void NETLIB_NAME(solver)::post_start()
case 8:
ms = create_solver<8,8>(8, use_specific);
break;
case 9:
ms = create_solver<9,9>(9, use_specific);
break;
case 10:
ms = create_solver<10,10>(10, use_specific);
break;