Netlist: Added pascal like strings (pstring) class. These use only size(void *) in objects. Uses reference counter to share identical string between various pstrings.

In addition, fixed some bugs and added auto-sizing to netlist_list_t. 

There shouldn't be memory holes left now, apart from memory allocated in a static class factory.
This commit is contained in:
Couriersud 2013-11-24 20:08:04 +00:00
parent 0d0f072d59
commit cb6f1d0194
18 changed files with 690 additions and 245 deletions

2
.gitattributes vendored
View File

@ -2144,6 +2144,8 @@ src/emu/netlist/nl_parser.h svneol=native#text/plain
src/emu/netlist/nl_setup.c svneol=native#text/plain
src/emu/netlist/nl_setup.h svneol=native#text/plain
src/emu/netlist/nl_time.h svneol=native#text/plain
src/emu/netlist/pstring.c svneol=native#text/plain
src/emu/netlist/pstring.h svneol=native#text/plain
src/emu/network.c svneol=native#text/plain
src/emu/network.h svneol=native#text/plain
src/emu/output.c svneol=native#text/plain

View File

@ -49,8 +49,6 @@
#include "netlist/nl_setup.h"
#include "netlist/devices/net_lib.h"
const netlist_time netlist_time::zero = netlist_time::from_raw(0);
// ----------------------------------------------------------------------------------------
// netlist_mame_device
// ----------------------------------------------------------------------------------------
@ -91,8 +89,8 @@ void netlist_mame_device::device_start()
m_setup->start_devices();
bool allok = true;
for (on_device_start **ods = m_device_start_list.first(); ods <= m_device_start_list.last(); ods++)
allok &= (*ods)->OnDeviceStart();
for (device_start_list_t::entry_t *ods = m_device_start_list.first(); ods != NULL; ods = m_device_start_list.next(ods))
allok &= ods->object()->OnDeviceStart();
if (!allok)
fatalerror("required elements not found\n");

View File

@ -118,7 +118,9 @@ public:
netlist_setup_t &setup() { return *m_setup; }
netlist_t &netlist() { return *m_netlist; }
netlist_list_t<on_device_start *> m_device_start_list;
typedef netlist_list_t<on_device_start *> device_start_list_t;
device_start_list_t m_device_start_list;
protected:
// device-level overrides

View File

@ -987,7 +987,7 @@ static const net_device_t_base_factory *netregistry[] =
NULL
};
netlist_device_t *net_create_device_by_classname(const astring &classname, netlist_setup_t &setup)
netlist_device_t *net_create_device_by_classname(const pstring &classname, netlist_setup_t &setup)
{
const net_device_t_base_factory **p = &netregistry[0];
while (*p != NULL)
@ -1003,7 +1003,7 @@ netlist_device_t *net_create_device_by_classname(const astring &classname, netli
return NULL; // appease code analysis
}
netlist_device_t *net_create_device_by_name(const astring &name, netlist_setup_t &setup)
netlist_device_t *net_create_device_by_name(const pstring &name, netlist_setup_t &setup)
{
const net_device_t_base_factory **p = &netregistry[0];
while (*p != NULL)

View File

@ -98,13 +98,24 @@ NETLIB_UPDATE_PARAM(solver)
m_inc = netlist_time::from_hz(m_freq.Value());
}
NETLIB_NAME(solver)::~NETLIB_NAME(solver)()
{
net_list_t::entry_t *p = m_nets.first();
while (p != NULL)
{
net_list_t::entry_t *pn = m_nets.next(pn);
delete pn->object();
p = pn;
}
}
NETLIB_FUNC_VOID(solver, post_start, ())
{
NL_VERBOSE_OUT(("post start solver ...\n"));
for (netlist_net_t **pn = m_nets.first(); pn != NULL; pn = m_nets.next(pn))
for (net_list_t::entry_t *pn = m_nets.first(); pn != NULL; pn = m_nets.next(pn))
{
NL_VERBOSE_OUT(("setting up net\n"));
for (netlist_terminal_t *p = (*pn)->m_head; p != NULL; p = p->m_update_list_next)
for (netlist_terminal_t *p = pn->object()->m_head; p != NULL; p = p->m_update_list_next)
{
switch (p->type())
{
@ -121,11 +132,11 @@ NETLIB_FUNC_VOID(solver, post_start, ())
break;
}
}
if ((*pn)->m_head == NULL)
if (pn->object()->m_head == NULL)
{
NL_VERBOSE_OUT(("Deleting net ...\n"));
netlist_net_t *to_delete = *pn;
m_nets.del(to_delete);
netlist_net_t *to_delete = pn->object();
m_nets.remove(to_delete);
delete to_delete;
pn--;
}
@ -146,15 +157,15 @@ NETLIB_UPDATE(solver)
NL_VERBOSE_OUT(("Step!\n"));
/* update all terminals for new time step */
m_last_step = now;
for (netlist_terminal_t **p = m_terms.first(); p != NULL; p = m_terms.next(p))
(*p)->netdev().step_time(delta.as_double());
for (terminal_list_t::entry_t *p = m_terms.first(); p != NULL; p = m_terms.next(p))
p->object()->netdev().step_time(delta.as_double());
}
for (netlist_net_t **pn = m_nets.first(); pn != NULL; pn = m_nets.next(pn))
for (net_list_t::entry_t *pn = m_nets.first(); pn != NULL; pn = m_nets.next(pn))
{
double gtot = 0;
double iIdr = 0;
for (netlist_terminal_t *p = (*pn)->m_head; p != NULL; p = p->m_update_list_next)
for (netlist_terminal_t *p = pn->object()->m_head; p != NULL; p = p->m_update_list_next)
{
if (p->isType(netlist_terminal_t::TERMINAL))
{
@ -165,9 +176,9 @@ NETLIB_UPDATE(solver)
}
double new_val = iIdr / gtot;
if (fabs(new_val - (*pn)->m_cur.Analog) > 1e-4)
if (fabs(new_val - pn->object()->m_cur.Analog) > 1e-4)
resched = true;
(*pn)->m_cur.Analog = (*pn)->m_new.Analog = new_val;
pn->object()->m_cur.Analog = pn->object()->m_new.Analog = new_val;
NL_VERBOSE_OUT(("Info: %d\n", (*pn)->m_num_cons));
NL_VERBOSE_OUT(("New: %lld %f %f\n", netlist().time().as_raw(), netlist().time().as_double(), new_val));
@ -179,8 +190,8 @@ NETLIB_UPDATE(solver)
else
{
/* update all inputs connected */
for (netlist_terminal_t **p = m_inps.first(); p != NULL; p = m_inps.next(p))
(*p)->netdev().update_dev();
for (terminal_list_t::entry_t *p = m_inps.first(); p != NULL; p = m_inps.next(p))
p->object()->netdev().update_dev();
/* step circuit */
if (!m_Q.net().is_queued())
{

View File

@ -96,6 +96,9 @@ NETLIB_DEVICE_WITH_PARAMS(clock,
// ----------------------------------------------------------------------------------------
NETLIB_DEVICE_WITH_PARAMS(solver,
typedef netlist_list_t<netlist_terminal_t *> terminal_list_t;
typedef netlist_list_t<netlist_net_t *> net_list_t;
netlist_ttl_input_t m_feedback;
netlist_ttl_output_t m_Q;
@ -104,11 +107,14 @@ NETLIB_DEVICE_WITH_PARAMS(solver,
netlist_time m_inc;
netlist_time m_last_step;
netlist_list_t<netlist_terminal_t *> m_terms;
netlist_list_t<netlist_terminal_t *> m_inps;
terminal_list_t m_terms;
terminal_list_t m_inps;
public:
netlist_list_t<netlist_net_t *> m_nets;
~NETLIB_NAME(solver)();
net_list_t m_nets;
ATTR_HOT inline void schedule();

View File

@ -18,8 +18,9 @@ NETLISTOBJ = $(EMUOBJ)/netlist
#-------------------------------------------------
NETLISTOBJS+= \
$(NETLISTOBJ)/nl_setup.o \
$(NETLISTOBJ)/nl_base.o \
$(NETLISTOBJ)/pstring.o \
$(NETLISTOBJ)/nl_setup.o \
$(NETLISTOBJ)/nl_parser.o \
$(NETLISTOBJ)/devices/nld_system.o \
$(NETLISTOBJ)/devices/net_lib.o \

View File

@ -5,6 +5,9 @@
#include "nl_base.h"
#include "devices/nld_system.h"
#include "pstring.h"
const netlist_time netlist_time::zero = netlist_time::from_raw(0);
// ----------------------------------------------------------------------------------------
// netlist_object_t
@ -14,25 +17,24 @@ ATTR_COLD netlist_object_t::netlist_object_t(const type_t atype, const family_t
: m_objtype(atype)
, m_family(afamily)
, m_netlist(NULL)
, m_name(NULL)
{}
ATTR_COLD netlist_object_t::~netlist_object_t()
{
delete m_name;
//delete m_name;
}
ATTR_COLD void netlist_object_t::init_object(netlist_base_t &nl, const astring &aname)
ATTR_COLD void netlist_object_t::init_object(netlist_base_t &nl, const pstring &aname)
{
m_netlist = &nl;
m_name = new astring(aname);
m_name = aname;
}
ATTR_COLD const astring &netlist_object_t::name() const
ATTR_COLD const pstring &netlist_object_t::name() const
{
if (m_name == NULL)
if (m_name == "")
fatalerror("object not initialized");
return *m_name;
return m_name;
}
// ----------------------------------------------------------------------------------------
@ -47,7 +49,7 @@ ATTR_COLD netlist_owned_object_t::netlist_owned_object_t(const type_t atype,
}
ATTR_COLD void netlist_owned_object_t::init_object(netlist_core_device_t &dev,
const astring &aname)
const pstring &aname)
{
netlist_object_t::init_object(dev.netlist(), aname);
m_netdev = &dev;
@ -58,15 +60,17 @@ ATTR_COLD void netlist_owned_object_t::init_object(netlist_core_device_t &dev,
// ----------------------------------------------------------------------------------------
netlist_base_t::netlist_base_t()
: m_mainclock(NULL),
m_time_ps(netlist_time::zero),
: m_time_ps(netlist_time::zero),
m_rem(0),
m_div(NETLIST_DIV)
m_div(NETLIST_DIV),
m_mainclock(NULL),
m_solver(NULL)
{
}
netlist_base_t::~netlist_base_t()
{
pstring::resetmem();
}
ATTR_COLD void netlist_base_t::set_mainclock_dev(NETLIB_NAME(mainclock) *dev)
@ -81,11 +85,12 @@ ATTR_COLD void netlist_base_t::set_solver_dev(NETLIB_NAME(solver) *dev)
ATTR_COLD void netlist_base_t::reset()
{
m_time_ps = netlist_time::zero;
m_rem = 0;
m_queue.clear();
if (m_mainclock != NULL)
m_mainclock->m_Q.net().set_time(netlist_time::zero);
m_time_ps = netlist_time::zero;
m_rem = 0;
m_queue.clear();
if (m_mainclock != NULL)
m_mainclock->m_Q.net().set_time(netlist_time::zero);
}
@ -121,7 +126,7 @@ ATTR_HOT ATTR_ALIGN void netlist_base_t::process_queue(INT32 &atime)
{
while ( (atime > 0) && (m_queue.is_not_empty()))
{
const queue_t::entry_t e = m_queue.pop();
const queue_t::entry_t &e = m_queue.pop();
update_time(e.time(), atime);
//if (FATAL_ERROR_AFTER_NS)
@ -156,7 +161,7 @@ ATTR_HOT ATTR_ALIGN void netlist_base_t::process_queue(INT32 &atime)
NETLIB_NAME(mainclock)::mc_update(mcQ, time() + inc);
}
const queue_t::entry_t e = m_queue.pop();
const queue_t::entry_t &e = m_queue.pop();
update_time(e.time(), atime);
@ -197,7 +202,7 @@ netlist_core_device_t::netlist_core_device_t()
{
}
ATTR_COLD void netlist_core_device_t::init(netlist_setup_t &setup, const astring &name)
ATTR_COLD void netlist_core_device_t::init(netlist_setup_t &setup, const pstring &name)
{
init_object(setup.netlist(), name);
@ -248,7 +253,7 @@ netlist_device_t::~netlist_device_t()
//NL_VERBOSE_OUT(("~net_device_t\n");
}
ATTR_COLD void netlist_device_t::init(netlist_setup_t &setup, const astring &name)
ATTR_COLD void netlist_device_t::init(netlist_setup_t &setup, const pstring &name)
{
netlist_core_device_t::init(setup, name);
m_setup = &setup;
@ -256,33 +261,33 @@ ATTR_COLD void netlist_device_t::init(netlist_setup_t &setup, const astring &nam
}
ATTR_COLD void netlist_device_t::register_sub(netlist_core_device_t &dev, const astring &name)
ATTR_COLD void netlist_device_t::register_sub(netlist_core_device_t &dev, const pstring &name)
{
dev.init(*m_setup, this->name() + "." + name);
}
ATTR_COLD void netlist_device_t::register_output(netlist_core_device_t &dev, const astring &name, netlist_output_t &port)
ATTR_COLD void netlist_device_t::register_output(netlist_core_device_t &dev, const pstring &name, netlist_output_t &port)
{
m_setup->register_object(*this, dev, name, port, netlist_terminal_t::STATE_OUT);
}
ATTR_COLD void netlist_device_t::register_terminal(const astring &name, netlist_terminal_t &port)
ATTR_COLD void netlist_device_t::register_terminal(const pstring &name, netlist_terminal_t &port)
{
m_setup->register_object(*this,*this,name, port, netlist_terminal_t::STATE_INP_ACTIVE);
}
ATTR_COLD void netlist_device_t::register_output(const astring &name, netlist_output_t &port)
ATTR_COLD void netlist_device_t::register_output(const pstring &name, netlist_output_t &port)
{
m_setup->register_object(*this,*this,name, port, netlist_terminal_t::STATE_OUT);
}
ATTR_COLD void netlist_device_t::register_input(netlist_core_device_t &dev, const astring &name, netlist_input_t &inp, netlist_input_t::state_e type)
ATTR_COLD void netlist_device_t::register_input(netlist_core_device_t &dev, const pstring &name, netlist_input_t &inp, netlist_input_t::state_e type)
{
m_terminals.add(name);
m_setup->register_object(*this, dev, name, inp, type);
}
ATTR_COLD void netlist_device_t::register_input(const astring &name, netlist_input_t &inp, netlist_input_t::state_e type)
ATTR_COLD void netlist_device_t::register_input(const pstring &name, netlist_input_t &inp, netlist_input_t::state_e type)
{
register_input(*this, name, inp, type);
}
@ -303,14 +308,14 @@ ATTR_COLD void netlist_device_t::register_link_internal(netlist_input_t &in, net
register_link_internal(*this, in, out, aState);
}
ATTR_COLD void netlist_device_t::register_param(netlist_core_device_t &dev, const astring &name, netlist_param_t &param, double initialVal)
ATTR_COLD void netlist_device_t::register_param(netlist_core_device_t &dev, const pstring &name, netlist_param_t &param, double initialVal)
{
param.set_netdev(dev);
param.initial(initialVal);
m_setup->register_object(*this, *this, name, param, netlist_terminal_t::STATE_NONEX);
}
ATTR_COLD void netlist_device_t::register_param(const astring &name, netlist_param_t &param, double initialVal)
ATTR_COLD void netlist_device_t::register_param(const pstring &name, netlist_param_t &param, double initialVal)
{
register_param(*this,name, param, initialVal);
}
@ -451,7 +456,7 @@ ATTR_COLD netlist_terminal_t::netlist_terminal_t()
}
ATTR_COLD void netlist_terminal_t::init_object(netlist_core_device_t &dev, const astring &aname, const state_e astate)
ATTR_COLD void netlist_terminal_t::init_object(netlist_core_device_t &dev, const pstring &aname, const state_e astate)
{
set_state(astate);
netlist_owned_object_t::init_object(dev, aname);
@ -480,7 +485,7 @@ netlist_output_t::netlist_output_t(const type_t atype, const family_t afamily)
this->set_net(m_my_net);
}
ATTR_COLD void netlist_output_t::init_object(netlist_core_device_t &dev, const astring &aname)
ATTR_COLD void netlist_output_t::init_object(netlist_core_device_t &dev, const pstring &aname)
{
netlist_terminal_t::init_object(dev, aname, STATE_OUT);
net().init_object(dev.netlist(), aname);

View File

@ -138,6 +138,7 @@
#include "nl_config.h"
#include "nl_lists.h"
#include "nl_time.h"
#include "pstring.h"
// ----------------------------------------------------------------------------------------
// Type definitions
@ -248,9 +249,9 @@ public:
virtual ~netlist_object_t();
ATTR_COLD void init_object(netlist_base_t &nl, const astring &aname);
ATTR_COLD void init_object(netlist_base_t &nl, const pstring &aname);
ATTR_COLD const astring &name() const;
ATTR_COLD const pstring &name() const;
ATTR_HOT inline const type_t type() const { return m_objtype; }
ATTR_HOT inline const family_t family() const { return m_family; }
@ -262,10 +263,10 @@ public:
ATTR_HOT inline const netlist_base_t & RESTRICT netlist() const { return *m_netlist; }
private:
pstring m_name;
const type_t m_objtype;
const family_t m_family;
netlist_base_t * RESTRICT m_netlist;
astring *m_name;
};
// ----------------------------------------------------------------------------------------
@ -277,7 +278,7 @@ class netlist_owned_object_t : public netlist_object_t
public:
ATTR_COLD netlist_owned_object_t(const type_t atype, const family_t afamily);
ATTR_COLD void init_object(netlist_core_device_t &dev, const astring &aname);
ATTR_COLD void init_object(netlist_core_device_t &dev, const pstring &aname);
ATTR_HOT inline netlist_core_device_t & RESTRICT netdev() const { return *m_netdev; }
private:
@ -306,7 +307,7 @@ public:
ATTR_COLD netlist_terminal_t(const type_t atype, const family_t afamily);
ATTR_COLD netlist_terminal_t();
ATTR_COLD void init_object(netlist_core_device_t &dev, const astring &aname, const state_e astate);
ATTR_COLD void init_object(netlist_core_device_t &dev, const pstring &aname, const state_e astate);
ATTR_COLD void set_net(netlist_net_t &anet);
ATTR_COLD inline bool has_net() { return (m_net != NULL); }
@ -515,7 +516,7 @@ public:
ATTR_COLD netlist_output_t(const type_t atype, const family_t afamily);
ATTR_COLD void init_object(netlist_core_device_t &dev, const astring &aname);
ATTR_COLD void init_object(netlist_core_device_t &dev, const pstring &aname);
double m_low_V;
double m_high_V;
@ -601,7 +602,7 @@ public:
ATTR_COLD virtual ~netlist_core_device_t();
ATTR_COLD virtual void init(netlist_setup_t &setup, const astring &name);
ATTR_COLD virtual void init(netlist_setup_t &setup, const pstring &name);
ATTR_HOT virtual void update_param() {}
@ -656,9 +657,11 @@ public:
ATTR_HOT virtual void step_time(const double st) { }
ATTR_HOT virtual void update_terminals() { }
/* stats */
#if (NL_KEEP_STATISTICS)
/* stats */
osd_ticks_t total_time;
INT32 stat_count;
#endif
#if USE_DELEGATES
net_update_delegate static_update;
@ -681,21 +684,21 @@ public:
ATTR_COLD virtual ~netlist_device_t();
ATTR_COLD virtual void init(netlist_setup_t &setup, const astring &name);
ATTR_COLD virtual void init(netlist_setup_t &setup, const pstring &name);
ATTR_COLD const netlist_setup_t *setup() const { return m_setup; }
ATTR_COLD bool variable_input_count() { return m_variable_input_count; }
ATTR_COLD void register_sub(netlist_core_device_t &dev, const astring &name);
ATTR_COLD void register_sub(netlist_core_device_t &dev, const pstring &name);
ATTR_COLD void register_terminal(const astring &name, netlist_terminal_t &port);
ATTR_COLD void register_terminal(const pstring &name, netlist_terminal_t &port);
ATTR_COLD void register_output(const astring &name, netlist_output_t &out);
ATTR_COLD void register_output(netlist_core_device_t &dev, const astring &name, netlist_output_t &out);
ATTR_COLD void register_output(const pstring &name, netlist_output_t &out);
ATTR_COLD void register_output(netlist_core_device_t &dev, const pstring &name, netlist_output_t &out);
ATTR_COLD void register_input(const astring &name, netlist_input_t &in, netlist_input_t::state_e state = netlist_input_t::STATE_INP_ACTIVE);
ATTR_COLD void register_input(netlist_core_device_t &dev, const astring &name, netlist_input_t &in, netlist_input_t::state_e state = netlist_input_t::STATE_INP_ACTIVE);
ATTR_COLD void register_input(const pstring &name, netlist_input_t &in, netlist_input_t::state_e state = netlist_input_t::STATE_INP_ACTIVE);
ATTR_COLD void register_input(netlist_core_device_t &dev, const pstring &name, netlist_input_t &in, netlist_input_t::state_e state = netlist_input_t::STATE_INP_ACTIVE);
ATTR_COLD void register_link_internal(netlist_input_t &in, netlist_output_t &out, netlist_input_t::state_e aState);
ATTR_COLD void register_link_internal(netlist_core_device_t &dev, netlist_input_t &in, netlist_output_t &out, netlist_input_t::state_e aState);
@ -703,15 +706,15 @@ public:
ATTR_HOT virtual void update_terminals() { }
/* driving logic outputs don't count in here */
netlist_list_t<astring> m_terminals;
netlist_list_t<pstring, 20> m_terminals;
protected:
virtual void update() { }
virtual void start() { }
ATTR_COLD void register_param(const astring &sname, netlist_param_t &param, const double initialVal = 0.0);
ATTR_COLD void register_param(netlist_core_device_t &dev, const astring &sname, netlist_param_t &param, const double initialVal = 0.0);
ATTR_COLD void register_param(const pstring &sname, netlist_param_t &param, const double initialVal = 0.0);
ATTR_COLD void register_param(netlist_core_device_t &dev, const pstring &sname, netlist_param_t &param, const double initialVal = 0.0);
netlist_setup_t *m_setup;
bool m_variable_input_count;
@ -780,19 +783,22 @@ public:
ATTR_COLD void reset();
protected:
#if (NL_KEEP_STATISTICS)
// performance
int m_perf_out_processed;
int m_perf_inp_processed;
int m_perf_inp_active;
#endif
private:
netlist_time m_time_ps;
queue_t m_queue;
NETLIB_NAME(mainclock) * m_mainclock;
NETLIB_NAME(solver) * m_solver;
netlist_time m_time_ps;
UINT32 m_rem;
UINT32 m_div;
NETLIB_NAME(mainclock) * m_mainclock;
NETLIB_NAME(solver) * m_solver;
ATTR_HOT void update_time(const netlist_time t, INT32 &atime);
};
@ -994,7 +1000,7 @@ ATTR_HOT inline const bool netlist_analog_input_t::is_highz() const
class net_device_t_base_factory
{
public:
net_device_t_base_factory(const astring &name, const astring &classname)
net_device_t_base_factory(const pstring &name, const pstring &classname)
: m_name(name), m_classname(classname)
{}
@ -1002,18 +1008,18 @@ public:
virtual netlist_device_t *Create() const = 0;
const astring &name() const { return m_name; }
const astring &classname() const { return m_classname; }
const pstring &name() const { return m_name; }
const pstring &classname() const { return m_classname; }
protected:
astring m_name; /* device name */
astring m_classname; /* device class name */
pstring m_name; /* device name */
pstring m_classname; /* device class name */
};
template <class C>
class net_device_t_factory : public net_device_t_base_factory
{
public:
net_device_t_factory(const astring &name, const astring &classname)
net_device_t_factory(const pstring &name, const pstring &classname)
: net_device_t_base_factory(name, classname) { }
netlist_device_t *Create() const
@ -1024,8 +1030,8 @@ public:
}
};
netlist_device_t *net_create_device_by_classname(const astring &classname, netlist_setup_t &setup);
netlist_device_t *net_create_device_by_name(const astring &name, netlist_setup_t &setup);
netlist_device_t *net_create_device_by_classname(const pstring &classname, netlist_setup_t &setup);
netlist_device_t *net_create_device_by_name(const pstring &name, netlist_setup_t &setup);
#endif /* NLBASE_H_ */

View File

@ -16,6 +16,8 @@
// SETUP
//============================================================
//#define astring breakme()
#define USE_DELEGATES (0)
/*
* The next options needs -Wno-pmf-conversions to compile and gcc

View File

@ -15,14 +15,23 @@
// ----------------------------------------------------------------------------------------
template <class _ListClass>
template <class _ListClass, int _NumElem = 128>
struct netlist_list_t
{
public:
ATTR_COLD netlist_list_t(int numElements = 100)
struct entry_t {
// keep compatibility with tagmap
_ListClass object() { return m_obj; }
_ListClass m_obj;
};
ATTR_COLD netlist_list_t(int numElements = _NumElem)
{
m_num_elements = numElements;
m_list = new _ListClass[m_num_elements];
m_list = new entry_t[m_num_elements];
m_ptr = m_list;
m_ptr--;
}
@ -32,24 +41,29 @@ public:
}
ATTR_HOT inline void add(const _ListClass elem)
{
assert(m_ptr-m_list <= m_num_elements - 1);
if (m_ptr-m_list >= m_num_elements - 1)
resize(m_num_elements * 2);
*(++m_ptr) = elem;
(++m_ptr)->m_obj = elem;
}
ATTR_HOT inline void resize(const int new_size)
{
int cnt = count();
_ListClass *m_new = new _ListClass[new_size];
memcpy(m_new, m_list, new_size * sizeof(_ListClass));
entry_t *m_new = new entry_t[new_size];
entry_t *pd = m_new;
for (entry_t *ps = m_list; ps <= m_ptr; ps++, pd++)
*pd = *ps;
delete[] m_list;
m_list = m_new;
m_ptr = m_list + cnt - 1;
m_num_elements = new_size;
}
ATTR_HOT inline void del(const _ListClass elem)
ATTR_HOT inline void remove(const _ListClass elem)
{
for (_ListClass * i=m_list; i<=m_ptr; i++)
for (entry_t *i = m_list; i <= m_ptr; i++)
{
if (*i == elem)
if (i->object() == elem)
{
while (i <= m_ptr)
{
@ -61,16 +75,16 @@ public:
}
}
}
ATTR_HOT inline _ListClass *first() { return (m_ptr >= m_list ? &m_list[0] : NULL ); }
ATTR_HOT inline _ListClass *next(_ListClass *lc) { return (lc < last() ? lc + 1 : NULL ); }
ATTR_HOT inline _ListClass *last() { return m_ptr; }
ATTR_HOT inline _ListClass *item(int i) { return &m_list[i]; }
ATTR_HOT inline entry_t *first() { return (m_ptr >= m_list ? &m_list[0] : NULL ); }
ATTR_HOT inline entry_t *next(entry_t *lc) { return (lc < last() ? lc + 1 : NULL ); }
ATTR_HOT inline entry_t *last() { return m_ptr; }
ATTR_HOT inline entry_t *item(int i) { return &m_list[i]; }
ATTR_HOT inline int count() const { return m_ptr - m_list + 1; }
ATTR_HOT inline bool empty() { return (m_ptr < m_list); }
ATTR_HOT inline void clear() { m_ptr = m_list - 1; }
ATTR_HOT inline void reset() { m_ptr = m_list - 1; }
private:
_ListClass * m_ptr;
_ListClass * m_list;
entry_t * m_ptr;
entry_t * m_list;
int m_num_elements;
//_ListClass m_list[_NumElements];
};
@ -111,7 +125,7 @@ public:
if (is_empty() || (e.time() <= (m_end - 1)->time()))
{
*m_end++ = e;
//inc_stat(m_prof_end);
inc_stat(m_prof_end);
}
else
{
@ -120,20 +134,20 @@ public:
{
i--;
*(i+1) = *i;
//inc_stat(m_prof_sortmove);
inc_stat(m_prof_sortmove);
}
*i = e;
//inc_stat(m_prof_sort);
inc_stat(m_prof_sort);
}
assert(m_end - m_list < _Size);
}
ATTR_HOT inline const entry_t pop()
ATTR_HOT inline const entry_t &pop()
{
return *--m_end;
}
ATTR_HOT inline const entry_t peek() const
ATTR_HOT inline const entry_t &peek() const
{
return *(m_end-1);
}
@ -142,12 +156,15 @@ public:
{
m_end = &m_list[0];
}
// profiling
#if (NL_KEEP_STATISTICS)
// profiling
INT32 m_prof_start;
INT32 m_prof_end;
INT32 m_prof_sortmove;
INT32 m_prof_sort;
#endif
private:
entry_t * RESTRICT m_end;

View File

@ -16,7 +16,7 @@ void netlist_parser::parse(char *buf)
m_p = buf;
while (*m_p)
{
astring n;
pstring n;
skipws();
if (!*m_p) break;
n = getname('(');
@ -34,8 +34,8 @@ void netlist_parser::parse(char *buf)
void netlist_parser::net_alias()
{
astring alias;
astring out;
pstring alias;
pstring out;
skipws();
alias = getname(',');
skipws();
@ -46,7 +46,7 @@ void netlist_parser::net_alias()
void netlist_parser::netdev_param()
{
astring param;
pstring param;
double val;
skipws();
param = getname(',');
@ -58,11 +58,11 @@ void netlist_parser::netdev_param()
check_char(')');
}
void netlist_parser::netdev_const(const astring &dev_name)
void netlist_parser::netdev_const(const pstring &dev_name)
{
astring name;
pstring name;
netlist_device_t *dev;
astring paramfq;
pstring paramfq;
double val;
skipws();
@ -72,16 +72,15 @@ void netlist_parser::netdev_const(const astring &dev_name)
skipws();
val = eval_param();
check_char(')');
paramfq = name;
paramfq.cat(".CONST");
paramfq = name + ".CONST";
NL_VERBOSE_OUT(("Parser: Const: %s %f\n", name.cstr(), val));
//m_setup.find_param(paramfq).initial(val);
m_setup.register_param(paramfq, val);
}
void netlist_parser::netdev_device(const astring &dev_type)
void netlist_parser::netdev_device(const pstring &dev_type)
{
astring devname;
pstring devname;
netlist_device_t *dev;
int cnt;
@ -96,11 +95,9 @@ void netlist_parser::netdev_device(const astring &dev_type)
{
m_p++;
skipws();
astring output_name = getname2(',', ')');
pstring output_name = getname2(',', ')');
NL_VERBOSE_OUT(("Parser: ID: %s %s\n", output_name.cstr(), dev->m_terminals.item(cnt)->cstr()));
astring temp;
temp.printf("%s.[%d]", devname.cstr(), cnt);
m_setup.register_link(temp, output_name);
m_setup.register_link(pstring::sprintf("%s.[%d]", devname.cstr(), cnt), output_name);
skipws();
cnt++;
}
@ -156,7 +153,7 @@ void netlist_parser::skipws()
}
}
astring netlist_parser::getname(char sep)
pstring netlist_parser::getname(char sep)
{
char buf[300];
char *p1 = buf;
@ -165,10 +162,10 @@ astring netlist_parser::getname(char sep)
*p1++ = *m_p++;
*p1 = 0;
m_p++;
return astring(buf);
return pstring(buf);
}
astring netlist_parser::getname2(char sep1, char sep2)
pstring netlist_parser::getname2(char sep1, char sep2)
{
char buf[300];
char *p1 = buf;
@ -176,7 +173,7 @@ astring netlist_parser::getname2(char sep1, char sep2)
while ((*m_p != sep1) && (*m_p != sep2))
*p1++ = *m_p++;
*p1 = 0;
return astring(buf);
return pstring(buf);
}
void netlist_parser::check_char(char ctocheck)

View File

@ -19,15 +19,15 @@ public:
void parse(char *buf);
void net_alias();
void netdev_param();
void netdev_const(const astring &dev_name);
void netdev_device(const astring &dev_type);
void netdev_const(const pstring &dev_name);
void netdev_device(const pstring &dev_type);
private:
void skipeol();
void skipws();
astring getname(char sep);
astring getname2(char sep1, char sep2);
pstring getname(char sep);
pstring getname2(char sep1, char sep2);
void check_char(char ctocheck);
double eval_param();

View File

@ -41,13 +41,17 @@ static void tagmap_free_entries(T &tm)
netlist_setup_t::~netlist_setup_t()
{
tagmap_free_entries<tagmap_devices_t>(m_devices);
tagmap_free_entries<tagmap_link_t>(m_links);
tagmap_free_entries<tagmap_astring_t>(m_alias);
//tagmap_free_entries<tagmap_link_t>(m_links);
//tagmap_free_entries<tagmap_nstring_t>(m_alias);
m_links.reset();
m_alias.reset();
m_params.reset();
m_terminals.reset();
m_params_temp.reset();
pstring::resetmem();
}
netlist_device_t *netlist_setup_t::register_dev(netlist_device_t *dev, const astring &name)
netlist_device_t *netlist_setup_t::register_dev(netlist_device_t *dev, const pstring &name)
{
if (!(m_devices.add(name, dev, false)==TMERR_NONE))
fatalerror("Error adding %s to device list\n", name.cstr());
@ -55,13 +59,14 @@ netlist_device_t *netlist_setup_t::register_dev(netlist_device_t *dev, const ast
}
template <class T>
static void remove_start_with(T &hm, astring &sw)
static void remove_start_with(T &hm, pstring &sw)
{
typename T::entry_t *entry = hm.first();
while (entry != NULL)
{
typename T::entry_t *next = hm.next(entry);
if (sw.cmpsubstr(entry->tag(), 0, sw.len()) == 0)
pstring x = entry->tag().cstr();
if (sw.equals(x.substr(0, sw.len())))
{
NL_VERBOSE_OUT(("removing %s\n", entry->tag().cstr()));
hm.remove(entry->object());
@ -70,15 +75,13 @@ static void remove_start_with(T &hm, astring &sw)
}
}
void netlist_setup_t::remove_dev(const astring &name)
void netlist_setup_t::remove_dev(const pstring &name)
{
netlist_device_t *dev = m_devices.find(name);
astring temp = name;
pstring temp = name + ".";
if (dev == NULL)
fatalerror("Device %s does not exist\n", name.cstr());
temp.cat(".");
//remove_start_with<tagmap_input_t>(m_inputs, temp);
remove_start_with<tagmap_terminal_t>(m_terminals, temp);
remove_start_with<tagmap_param_t>(m_params, temp);
@ -87,14 +90,14 @@ void netlist_setup_t::remove_dev(const astring &name)
while (p != NULL)
{
tagmap_link_t::entry_t *n = m_links.next(p);
if (temp.cmpsubstr(p->object()->e1,0,temp.len()) == 0 || temp.cmpsubstr(p->object()->e2,0,temp.len()) == 0)
if (temp.equals(p->object().e1.substr(0,temp.len())) || temp.equals(p->object().e2.substr(0,temp.len())))
m_links.remove(p->object());
p = n;
}
m_devices.remove(name);
}
void netlist_setup_t::register_callback(const astring &devname, netlist_output_delegate delegate)
void netlist_setup_t::register_callback(const pstring &devname, netlist_output_delegate delegate)
{
NETLIB_NAME(analog_callback) *dev = (NETLIB_NAME(analog_callback) *) m_devices.find(devname);
if (dev == NULL)
@ -102,13 +105,14 @@ void netlist_setup_t::register_callback(const astring &devname, netlist_output_d
dev->register_callback(delegate);
}
void netlist_setup_t::register_alias(const astring &alias, const astring &out)
void netlist_setup_t::register_alias(const pstring &alias, const pstring &out)
{
if (!(m_alias.add(alias, new astring(out), false)==TMERR_NONE))
//if (!(m_alias.add(alias, new nstring(out), false)==TMERR_NONE))
if (!(m_alias.add(alias, out, false)==TMERR_NONE))
fatalerror("Error adding alias %s to alias list\n", alias.cstr());
}
astring netlist_setup_t::objtype_as_astr(netlist_object_t &in)
pstring netlist_setup_t::objtype_as_astr(netlist_object_t &in)
{
switch (in.type())
{
@ -134,7 +138,7 @@ astring netlist_setup_t::objtype_as_astr(netlist_object_t &in)
fatalerror("Unknown object type %d\n", in.type());
}
void netlist_setup_t::register_object(netlist_device_t &dev, netlist_core_device_t &upd_dev, const astring &name, netlist_object_t &obj, netlist_input_t::state_e state)
void netlist_setup_t::register_object(netlist_device_t &dev, netlist_core_device_t &upd_dev, const pstring &name, netlist_object_t &obj, netlist_input_t::state_e state)
{
switch (obj.type())
{
@ -157,17 +161,16 @@ void netlist_setup_t::register_object(netlist_device_t &dev, netlist_core_device
break;
case netlist_terminal_t::PARAM:
{
netlist_param_t &param = dynamic_cast<netlist_param_t &>(obj);
astring temp = param.netdev().name();
temp.cat(".");
temp.cat(name);
const astring *val = m_params_temp.find(temp);
if (val != NULL)
pstring temp = param.netdev().name() + "." + name;
const pstring val = m_params_temp.find(temp);
if (val != "")
{
//printf("Found parameter ... %s : %s\n", temp.cstr(), val->cstr());
double vald = 0;
if (sscanf(val->cstr(), "%lf", &vald) != 1)
fatalerror("Invalid number conversion %s : %s\n", temp.cstr(), val->cstr());
if (sscanf(val.cstr(), "%lf", &vald) != 1)
fatalerror("Invalid number conversion %s : %s\n", temp.cstr(), val.cstr());
param.initial(vald);
}
if (!(m_params.add(temp, &param, false)==TMERR_NONE))
@ -179,52 +182,52 @@ void netlist_setup_t::register_object(netlist_device_t &dev, netlist_core_device
}
}
void netlist_setup_t::register_link(const astring &sin, const astring &sout)
void netlist_setup_t::register_link(const pstring &sin, const pstring &sout)
{
link_t *temp = new link_t(sin, sout);
link_t temp = link_t(sin, sout);
NL_VERBOSE_OUT(("link %s <== %s\n", sin.cstr(), sout.cstr()));
if (!(m_links.add(sin + "." + sout, temp, false)==TMERR_NONE))
fatalerror("Error adding link %s<==%s to link list\n", sin.cstr(), sout.cstr());
m_links.add(temp);
//if (!(m_links.add(sin + "." + sout, temp, false)==TMERR_NONE))
// fatalerror("Error adding link %s<==%s to link list\n", sin.cstr(), sout.cstr());
}
void netlist_setup_t::register_param(const astring &param, const double value)
void netlist_setup_t::register_param(const pstring &param, const double value)
{
// FIXME: there should be a better way
astring temp;
temp.printf("%.9e", value);
register_param(param, temp);
register_param(param, pstring::sprintf("%.9e", value));
}
void netlist_setup_t::register_param(const astring &param, const astring &value)
void netlist_setup_t::register_param(const pstring &param, const pstring &value)
{
if (!(m_params_temp.add(param, new astring(value), false)==TMERR_NONE))
//if (!(m_params_temp.add(param, new nstring(value), false)==TMERR_NONE))
if (!(m_params_temp.add(param, value, false)==TMERR_NONE))
fatalerror("Error adding parameter %s to parameter list\n", param.cstr());
}
const astring netlist_setup_t::resolve_alias(const astring &name) const
const pstring netlist_setup_t::resolve_alias(const pstring &name) const
{
const astring *temp = m_alias.find(name);
astring ret = name;
if (temp != NULL)
ret = *temp;
const pstring temp = m_alias.find(name);
pstring ret = name;
if (temp != "")
ret = temp;
int p = ret.find(".[");
if (p > 0)
{
astring dname = ret;
pstring dname = ret;
netlist_device_t *dev = m_devices.find(dname.substr(0,p));
if (dev == NULL)
fatalerror("Device for %s not found\n", name.cstr());
ret.substr(p+2,ret.len()-p-3);
int c = atoi(ret);
ret = dev->name() + "." + *(dev->m_terminals.item(c));
int c = atoi(ret.substr(p+2,ret.len()-p-3));
ret = dev->name() + "." + dev->m_terminals.item(c)->object();
}
//printf("%s==>%s\n", name.cstr(), ret.cstr());
return ret;
}
netlist_terminal_t &netlist_setup_t::find_terminal(const astring &terminal_in)
netlist_terminal_t &netlist_setup_t::find_terminal(const pstring &terminal_in)
{
const astring &tname = resolve_alias(terminal_in);
const pstring &tname = resolve_alias(terminal_in);
netlist_terminal_t *ret;
ret = dynamic_cast<netlist_terminal_t *>(m_terminals.find(tname));
@ -232,8 +235,7 @@ netlist_terminal_t &netlist_setup_t::find_terminal(const astring &terminal_in)
if (ret == NULL)
{
/* look for ".Q" std output */
astring s = tname;
s.cat(".Q");
pstring s = tname + ".Q";
ret = dynamic_cast<netlist_terminal_t *>(m_terminals.find(s));
}
if (ret == NULL)
@ -242,9 +244,9 @@ netlist_terminal_t &netlist_setup_t::find_terminal(const astring &terminal_in)
return *ret;
}
netlist_terminal_t &netlist_setup_t::find_terminal(const astring &terminal_in, netlist_object_t::type_t atype)
netlist_terminal_t &netlist_setup_t::find_terminal(const pstring &terminal_in, netlist_object_t::type_t atype)
{
const astring &tname = resolve_alias(terminal_in);
const pstring &tname = resolve_alias(terminal_in);
netlist_terminal_t *ret;
ret = dynamic_cast<netlist_terminal_t *>(m_terminals.find(tname));
@ -252,8 +254,7 @@ netlist_terminal_t &netlist_setup_t::find_terminal(const astring &terminal_in, n
if (ret == NULL && atype == netlist_object_t::OUTPUT)
{
/* look for ".Q" std output */
astring s = tname;
s.cat(".Q");
pstring s = tname + ".Q";
ret = dynamic_cast<netlist_terminal_t *>(m_terminals.find(s));
}
if (ret == NULL)
@ -264,9 +265,9 @@ netlist_terminal_t &netlist_setup_t::find_terminal(const astring &terminal_in, n
return *ret;
}
netlist_param_t &netlist_setup_t::find_param(const astring &param_in)
netlist_param_t &netlist_setup_t::find_param(const pstring &param_in)
{
const astring &outname = resolve_alias(param_in);
const pstring &outname = resolve_alias(param_in);
netlist_param_t *ret;
ret = m_params.find(outname);
@ -282,10 +283,10 @@ void netlist_setup_t::connect_input_output(netlist_input_t &in, netlist_output_t
if (out.isFamily(netlist_terminal_t::ANALOG) && in.isFamily(netlist_terminal_t::LOGIC))
{
nld_a_to_d_proxy *proxy = new nld_a_to_d_proxy(in);
astring x = "";
x.printf("proxy_ad_%d", m_proxy_cnt++);
pstring x = pstring::sprintf("proxy_ad_%d", m_proxy_cnt);
m_proxy_cnt++;
proxy->init(*this, x.cstr());
proxy->init(*this, x);
register_dev(proxy, x);
proxy->m_Q.net().register_con(in);
@ -296,9 +297,10 @@ void netlist_setup_t::connect_input_output(netlist_input_t &in, netlist_output_t
{
//printf("here 1\n");
nld_d_to_a_proxy *proxy = new nld_d_to_a_proxy(out);
astring x = "";
x.printf("proxy_da_%d", m_proxy_cnt++);
proxy->init(*this, x.cstr());
pstring x = pstring::sprintf("proxy_da_%d", m_proxy_cnt);
m_proxy_cnt++;
proxy->init(*this, x);
register_dev(proxy, x);
proxy->m_Q.net().register_con(in);
@ -320,9 +322,10 @@ void netlist_setup_t::connect_terminal_input(netlist_terminal_t &term, netlist_i
{
NL_VERBOSE_OUT(("connect_terminal_input: connecting proxy\n"));
nld_a_to_d_proxy *proxy = new nld_a_to_d_proxy(inp);
astring x = "";
x.printf("proxy_da_%d", m_proxy_cnt++);
proxy->init(*this, x.cstr());
pstring x = pstring::sprintf("proxy_da_%d", m_proxy_cnt);
m_proxy_cnt++;
proxy->init(*this, x);
register_dev(proxy, x);
connect_terminals(term, proxy->m_I);
@ -355,9 +358,10 @@ void netlist_setup_t::connect_terminal_output(netlist_terminal_t &in, netlist_ou
{
NL_VERBOSE_OUT(("connect_terminal_output: connecting proxy\n"));
nld_d_to_a_proxy *proxy = new nld_d_to_a_proxy(out);
astring x = "";
x.printf("proxy_da_%d", m_proxy_cnt++);
proxy->init(*this, x.cstr());
pstring x = pstring::sprintf("proxy_da_%d", m_proxy_cnt);
m_proxy_cnt++;
proxy->init(*this, x);
register_dev(proxy, x);
out.net().register_con(proxy->m_I);
@ -426,8 +430,8 @@ void netlist_setup_t::resolve_inputs(void)
NL_VERBOSE_OUT(("Resolving ...\n"));
for (tagmap_link_t::entry_t *entry = m_links.first(); entry != NULL; entry = m_links.next(entry))
{
const astring t1s = entry->object()->e1;
const astring t2s = entry->object()->e2;
const pstring t1s = entry->object().e1;
const pstring t2s = entry->object().e2;
netlist_terminal_t &t1 = find_terminal(t1s);
netlist_terminal_t &t2 = find_terminal(t2s);
@ -490,7 +494,7 @@ void netlist_setup_t::start_devices(void)
for (tagmap_devices_t::entry_t *entry = m_devices.first(); entry != NULL; entry = m_devices.next(entry))
{
netlist_device_t *dev = entry->object();
dev->init(*this, entry->tag());
dev->init(*this, entry->tag().cstr());
}
}
@ -518,7 +522,7 @@ void netlist_setup_t::parse(char *buf)
void netlist_setup_t::print_stats()
{
if (NL_KEEP_STATISTICS)
#if (NL_KEEP_STATISTICS)
{
for (netlist_setup_t::tagmap_devices_t::entry_t *entry = m_devices.first(); entry != NULL; entry = m_devices.next(entry))
{
@ -530,4 +534,5 @@ void netlist_setup_t::print_stats()
printf("Queue Sort %15d\n", m_netlist.queue().m_prof_sort);
printf("Queue Move %15d\n", m_netlist.queue().m_prof_sortmove);
}
#endif
}

View File

@ -68,42 +68,53 @@ public:
struct link_t
{
link_t(const astring &ae1, const astring &ae2)
link_t() { }
// Copy constructor
link_t(const link_t &from)
{
e1 = from.e1;
e2 = from.e2;
}
link_t(const pstring &ae1, const pstring &ae2)
{
e1 = ae1;
e2 = ae2;
}
astring e1;
astring e2;
pstring e1;
pstring e2;
bool operator==(const link_t &rhs) const { return (e1 == rhs.e1) && (e2 == rhs.e2); }
link_t &operator=(const link_t &rhs) { e1 = rhs.e1; e2 = rhs.e2; return *this; }
};
typedef tagmap_t<netlist_device_t *, 393> tagmap_devices_t;
typedef tagmap_t<link_t *, 393> tagmap_link_t;
typedef tagmap_t<const astring *, 393> tagmap_astring_t;
typedef tagmap_t<pstring, 393> tagmap_nstring_t;
typedef tagmap_t<netlist_param_t *, 393> tagmap_param_t;
typedef tagmap_t<netlist_terminal_t *, 393> tagmap_terminal_t;
typedef netlist_list_t<link_t> tagmap_link_t;
netlist_setup_t(netlist_base_t &netlist);
~netlist_setup_t();
netlist_base_t &netlist() { return m_netlist; }
netlist_device_t *register_dev(netlist_device_t *dev, const astring &name);
void remove_dev(const astring &name);
netlist_device_t *register_dev(netlist_device_t *dev, const pstring &name);
void remove_dev(const pstring &name);
void register_alias(const astring &alias, const astring &out);
void register_link(const astring &sin, const astring &sout);
void register_param(const astring &param, const astring &value);
void register_param(const astring &param, const double value);
void register_alias(const pstring &alias, const pstring &out);
void register_link(const pstring &sin, const pstring &sout);
void register_param(const pstring &param, const pstring &value);
void register_param(const pstring &param, const double value);
void register_object(netlist_device_t &dev, netlist_core_device_t &upd_dev, const astring &name, netlist_object_t &obj, netlist_input_t::state_e state);
void register_object(netlist_device_t &dev, netlist_core_device_t &upd_dev, const pstring &name, netlist_object_t &obj, netlist_input_t::state_e state);
netlist_terminal_t &find_terminal(const astring &outname_in);
netlist_terminal_t &find_terminal(const astring &outname_in, netlist_object_t::type_t atype);
netlist_terminal_t &find_terminal(const pstring &outname_in);
netlist_terminal_t &find_terminal(const pstring &outname_in, netlist_object_t::type_t atype);
netlist_param_t &find_param(const astring &param_in);
netlist_param_t &find_param(const pstring &param_in);
void register_callback(const astring &devname, netlist_output_delegate delegate);
void register_callback(const pstring &devname, netlist_output_delegate delegate);
void parse(char *buf);
@ -123,10 +134,10 @@ private:
netlist_base_t &m_netlist;
tagmap_devices_t m_devices;
tagmap_astring_t m_alias;
tagmap_nstring_t m_alias;
tagmap_param_t m_params;
tagmap_link_t m_links;
tagmap_astring_t m_params_temp;
tagmap_link_t m_links;
tagmap_nstring_t m_params_temp;
int m_proxy_cnt;
@ -136,9 +147,9 @@ private:
void connect_terminal_input(netlist_terminal_t &term, netlist_input_t &inp);
// helpers
astring objtype_as_astr(netlist_object_t &in);
pstring objtype_as_astr(netlist_object_t &in);
const astring resolve_alias(const astring &name) const;
const pstring resolve_alias(const pstring &name) const;
};
#endif /* NLSETUP_H_ */

View File

@ -26,50 +26,50 @@ struct netlist_time
{
public:
typedef UINT64 INTERNALTYPE;
typedef UINT64 INTERNALTYPE;
static const INTERNALTYPE RESOLUTION = NETLIST_INTERNAL_RES;
static const INTERNALTYPE RESOLUTION = NETLIST_INTERNAL_RES;
ATTR_HOT inline netlist_time() : m_time(0) {}
ATTR_HOT inline netlist_time() : m_time(0) {}
ATTR_HOT friend inline const netlist_time operator-(const netlist_time &left, const netlist_time &right);
ATTR_HOT friend inline const netlist_time operator+(const netlist_time &left, const netlist_time &right);
ATTR_HOT friend inline const netlist_time operator*(const netlist_time &left, const UINT32 factor);
ATTR_HOT friend inline const netlist_time operator-(const netlist_time &left, const netlist_time &right);
ATTR_HOT friend inline const netlist_time operator+(const netlist_time &left, const netlist_time &right);
ATTR_HOT friend inline const netlist_time operator*(const netlist_time &left, const UINT32 factor);
ATTR_HOT friend inline const UINT32 operator/(const netlist_time &left, const netlist_time &right);
ATTR_HOT friend inline bool operator>(const netlist_time &left, const netlist_time &right);
ATTR_HOT friend inline bool operator<(const netlist_time &left, const netlist_time &right);
ATTR_HOT friend inline bool operator>=(const netlist_time &left, const netlist_time &right);
ATTR_HOT friend inline bool operator<=(const netlist_time &left, const netlist_time &right);
ATTR_HOT friend inline bool operator>(const netlist_time &left, const netlist_time &right);
ATTR_HOT friend inline bool operator<(const netlist_time &left, const netlist_time &right);
ATTR_HOT friend inline bool operator>=(const netlist_time &left, const netlist_time &right);
ATTR_HOT friend inline bool operator<=(const netlist_time &left, const netlist_time &right);
ATTR_HOT inline const netlist_time &operator=(const netlist_time &right) { m_time = right.m_time; return *this; }
ATTR_HOT inline const netlist_time &operator+=(const netlist_time &right) { m_time += right.m_time; return *this; }
ATTR_HOT inline const netlist_time &operator=(const netlist_time &right) { m_time = right.m_time; return *this; }
ATTR_HOT inline const netlist_time &operator+=(const netlist_time &right) { m_time += right.m_time; return *this; }
ATTR_HOT inline const INTERNALTYPE as_raw() const { return m_time; }
ATTR_HOT inline const INTERNALTYPE as_raw() const { return m_time; }
ATTR_HOT inline const double as_double() const { return (double) m_time / (double) RESOLUTION; }
ATTR_HOT static inline const netlist_time from_nsec(const int ns) { return netlist_time((UINT64) ns * (RESOLUTION / U64(1000000000))); }
ATTR_HOT static inline const netlist_time from_usec(const int us) { return netlist_time((UINT64) us * (RESOLUTION / U64(1000000))); }
ATTR_HOT static inline const netlist_time from_msec(const int ms) { return netlist_time((UINT64) ms * (RESOLUTION / U64(1000))); }
ATTR_HOT static inline const netlist_time from_hz(const UINT64 hz) { return netlist_time(RESOLUTION / hz); }
ATTR_HOT static inline const netlist_time from_raw(const INTERNALTYPE raw) { return netlist_time(raw); }
ATTR_HOT static inline const netlist_time from_nsec(const int ns) { return netlist_time((UINT64) ns * (RESOLUTION / U64(1000000000))); }
ATTR_HOT static inline const netlist_time from_usec(const int us) { return netlist_time((UINT64) us * (RESOLUTION / U64(1000000))); }
ATTR_HOT static inline const netlist_time from_msec(const int ms) { return netlist_time((UINT64) ms * (RESOLUTION / U64(1000))); }
ATTR_HOT static inline const netlist_time from_hz(const UINT64 hz) { return netlist_time(RESOLUTION / hz); }
ATTR_HOT static inline const netlist_time from_raw(const INTERNALTYPE raw) { return netlist_time(raw); }
static const netlist_time zero;
static const netlist_time zero;
protected:
ATTR_HOT inline netlist_time(const INTERNALTYPE val) : m_time(val) {}
ATTR_HOT inline netlist_time(const INTERNALTYPE val) : m_time(val) {}
INTERNALTYPE m_time;
INTERNALTYPE m_time;
};
ATTR_HOT inline const netlist_time operator-(const netlist_time &left, const netlist_time &right)
{
return netlist_time::from_raw(left.m_time - right.m_time);
return netlist_time::from_raw(left.m_time - right.m_time);
}
ATTR_HOT inline const netlist_time operator*(const netlist_time &left, const UINT32 factor)
{
return netlist_time::from_raw(left.m_time * factor);
return netlist_time::from_raw(left.m_time * factor);
}
ATTR_HOT inline const UINT32 operator/(const netlist_time &left, const netlist_time &right)
@ -79,27 +79,27 @@ ATTR_HOT inline const UINT32 operator/(const netlist_time &left, const netlist_t
ATTR_HOT inline const netlist_time operator+(const netlist_time &left, const netlist_time &right)
{
return netlist_time::from_raw(left.m_time + right.m_time);
return netlist_time::from_raw(left.m_time + right.m_time);
}
ATTR_HOT inline bool operator<(const netlist_time &left, const netlist_time &right)
{
return (left.m_time < right.m_time);
return (left.m_time < right.m_time);
}
ATTR_HOT inline bool operator>(const netlist_time &left, const netlist_time &right)
{
return (left.m_time > right.m_time);
return (left.m_time > right.m_time);
}
ATTR_HOT inline bool operator<=(const netlist_time &left, const netlist_time &right)
{
return (left.m_time <= right.m_time);
return (left.m_time <= right.m_time);
}
ATTR_HOT inline bool operator>=(const netlist_time &left, const netlist_time &right)
{
return (left.m_time >= right.m_time);
return (left.m_time >= right.m_time);
}

218
src/emu/netlist/pstring.c Normal file
View File

@ -0,0 +1,218 @@
/*
* nl_string.c
*
*/
#include "pstring.h"
#include <cstdio>
//nstring::str_t *nstring::m_zero = NULL;
pstring::str_t *pstring::m_zero = pstring::salloc(0);
pstring::memblock *pstring::m_first = NULL;
#define IMMEDIATE_MODE (1)
#define DEBUG_MODE (0)
pstring::~pstring()
{
sfree(m_ptr);
}
void pstring::init()
{
if (m_zero == NULL)
{
m_zero = (str_t *) alloc_str(sizeof(str_t) + 1);
m_zero->reference_count = 1;
m_zero->m_len = 0;
m_zero->m_str[0] = 0;
}
m_ptr = m_zero;
m_ptr->reference_count++;
}
void pstring::pcat(const char *s)
{
int slen = strlen(s);
str_t *n = salloc(m_ptr->len() + slen);
if (m_ptr->len() > 0)
memcpy(n->str(), m_ptr->str(), m_ptr->len());
if (slen > 0)
memcpy(n->str() + m_ptr->len(), s, slen);
*(n->str() + n->len()) = 0;
sfree(m_ptr);
m_ptr = n;
}
void pstring::pcopy(const char *from, int size)
{
str_t *n = salloc(size);
if (size > 0)
memcpy(n->str(), from, size);
*(n->str() + size) = 0;
sfree(m_ptr);
m_ptr = n;
}
pstring pstring::substr(unsigned int start, int count) const
{
int alen = len();
if (start >= alen)
return pstring();
if (count <0 || start + count > alen)
count = alen - start;
pstring ret;
ret.pcopy(cstr() + start, count);
return ret;
}
pstring pstring::vprintf(va_list args) const
{
// sprintf into the temporary buffer
char tempbuf[4096];
vsprintf(tempbuf, cstr(), args);
return pstring(tempbuf);
}
// ----------------------------------------------------------------------------------------
// static stuff ...
// ----------------------------------------------------------------------------------------
void pstring::sfree(str_t *s)
{
s->reference_count--;
if (s->reference_count == 0)
dealloc_str(s);
}
pstring::str_t *pstring::salloc(int n)
{
str_t *ret = (str_t *) alloc_str(sizeof(str_t) + n + 1);
ret->reference_count = 1;
ret->m_len = n;
ret->m_str[0] = 0;
return ret;
//std::printf("old string %d <%s> %p %p\n", n, old, old, m_ptr);
}
pstring pstring::sprintf(const char *format, ...)
{
va_list ap;
va_start(ap, format);
pstring ret = pstring(format).vprintf(ap);
va_end(ap);
return ret;
}
char *pstring::alloc_str(int n)
{
#if (IMMEDIATE_MODE)
return (char *) malloc(n);
#else
#if (DEBUG_MODE)
int min_alloc = MAX(0, n+sizeof(memblock));
#else
int min_alloc = MAX(8192, n+sizeof(memblock));
#endif
char *ret = NULL;
//std::printf("m_first %p\n", m_first);
for (memblock *p = m_first; p != NULL && ret == NULL; p = p->next)
{
if (p->remaining > n)
{
ret = p->cur;
p->cur += n;
p->allocated += 1;
p->remaining -= n;
}
}
if (ret == NULL)
{
// need to allocate a new block
memblock *p = (memblock *) malloc(min_alloc); //new char[min_alloc];
p->allocated = 0;
p->cur = &p->data[0];
p->size = p->remaining = min_alloc - sizeof(memblock);
p->next = m_first;
//std::printf("allocated block size %d\n", p->size);
ret = p->cur;
p->cur += n;
p->allocated += 1;
p->remaining -= n;
m_first = p;
}
return ret;
#endif
}
void pstring::dealloc_str(void *ptr)
{
#if (IMMEDIATE_MODE)
free(ptr);
#else
for (memblock *p = m_first; p != NULL; p = p->next)
{
if (ptr >= &p->data[0] && ptr < &p->data[p->size])
{
p->allocated -= 1;
if (p->allocated < 0)
fatalerror("nstring: memory corruption\n");
if (p->allocated == 0)
{
//std::printf("Block entirely freed\n");
p->remaining = p->size;
p->cur = &p->data[0];
}
// shutting down ?
if (m_zero == NULL)
resetmem(); // try to free blocks
return;
}
}
fatalerror("nstring: string <%p> not found\n", ptr);
#endif
}
void pstring::resetmem()
{
#if (IMMEDIATE_MODE)
#else
memblock **p = &m_first;
int totalblocks = 0;
int freedblocks = 0;
// Release the 0 string
if (m_zero != NULL) sfree(m_zero);
m_zero = NULL;
while (*p != NULL)
{
totalblocks++;
memblock **next = &((*p)->next);
if ((*p)->allocated == 0)
{
//std::printf("freeing block %p\n", *p);
memblock *freeme = *p;
*p = *next;
free(freeme); //delete[] *p;
freedblocks++;
}
else
{
#if (DEBUG_MODE)
std::printf("Allocated: <%s>\n", ((str_t *)(&(*p)->data[0]))->str());
#endif
p = next;
}
}
#if (DEBUG_MODE)
std::printf("Freed %d out of total %d blocks\n", freedblocks, totalblocks);
#endif
#endif
}

164
src/emu/netlist/pstring.h Normal file
View File

@ -0,0 +1,164 @@
// license:GPL-2.0+
// copyright-holders:Couriersud
/*
* pstring.h
*/
#ifndef _PSTRING_H_
#define _PSTRING_H_
#include "nl_config.h"
// ----------------------------------------------------------------------------------------
// nstring: immutable strings ...
//
// nstrings are just a pointer to a "pascal-style" string representation.
// It uses reference counts and only uses new memory when a string changes.
// ----------------------------------------------------------------------------------------
struct pstring
{
public:
// simple construction/destruction
pstring()
{
init();
}
~pstring();
// construction with copy
pstring(const char *string) {init(); if (string != NULL) pcopy(string); }
pstring(const pstring &string) {init(); pcopy(string); }
// assignment operators
pstring &operator=(const char *string) { pcopy(string); return *this; }
pstring &operator=(const pstring &string) { pcopy(string); return *this; }
// C string conversion operators and helpers
operator const char *() const { return m_ptr->str(); }
inline const char *cstr() const { return m_ptr->str(); }
// concatenation operators
pstring& operator+=(const pstring &string) { pcat(string.cstr()); return *this; }
friend pstring operator+(const pstring &lhs, const pstring &rhs) { return pstring(lhs) += rhs; }
friend pstring operator+(const pstring &lhs, const char *rhs) { return pstring(lhs) += rhs; }
friend pstring operator+(const char *lhs, const pstring &rhs) { return pstring(lhs) += rhs; }
// comparison operators
bool operator==(const char *string) const { return (pcmp(string) == 0); }
bool operator==(const pstring &string) const { return (pcmp(string.cstr()) == 0); }
bool operator!=(const char *string) const { return (pcmp(string) != 0); }
bool operator!=(const pstring &string) const { return (pcmp(string.cstr()) != 0); }
bool operator<(const char *string) const { return (pcmp(string) < 0); }
bool operator<(const pstring &string) const { return (pcmp(string.cstr()) < 0); }
bool operator<=(const char *string) const { return (pcmp(string) <= 0); }
bool operator<=(const pstring &string) const { return (pcmp(string.cstr()) <= 0); }
bool operator>(const char *string) const { return (pcmp(string) > 0); }
bool operator>(const pstring &string) const { return (pcmp(string.cstr()) > 0); }
bool operator>=(const char *string) const { return (pcmp(string) >= 0); }
bool operator>=(const pstring &string) const { return (pcmp(string.cstr()) >= 0); }
//
inline const int len() const { return m_ptr->len(); }
inline bool equals(const pstring &string) { return (pcmp(string.cstr(), m_ptr->str()) == 0); }
int cmp(pstring &string) { return pcmp(string.cstr()); }
int find(const char *search, int start = 0) const
{
int alen = len();
const char *result = strstr(cstr() + MIN(start, alen), search);
return (result != NULL) ? (result - cstr()) : -1;
}
// various
bool startsWith(pstring &arg) { return (pcmp(cstr(), arg.cstr(), arg.len()) == 0); }
bool startsWith(const char *arg) { return (pcmp(cstr(), arg, strlen(arg)) == 0); }
// these return nstring ...
pstring cat(const pstring &s) const { return *this + s; }
pstring cat(const char *s) const { return *this + s; }
pstring substr(unsigned int start, int count = -1) const ;
pstring left(unsigned int count) const { return substr(0, count); }
pstring right(unsigned int count) const { return substr(len() - count, count); }
// printf using string as format ...
pstring vprintf(va_list args) const;
// static
static pstring sprintf(const char *format, ...);
static void resetmem();
protected:
struct str_t
{
int reference_count;
char *str() { return &m_str[0]; }
int len() { return m_len; }
//private:
int m_len;
char m_str[];
};
str_t *m_ptr;
private:
void init();
inline int pcmp(const char *right) const
{
return pcmp(m_ptr->str(), right);
}
inline int pcmp(const char *left, const char *right, int count = -1) const
{
if (count < 0)
return strcmp(left, right);
else
return strncmp(left, right, count);
}
void pcopy(const char *from, int size);
inline void pcopy(const char *from)
{
pcopy(from, strlen(from));
}
inline void pcopy(const pstring &from)
{
sfree(m_ptr);
m_ptr = from.m_ptr;
m_ptr->reference_count++;
}
void pcat(const char *s);
static str_t *m_zero;
static str_t *salloc(int n);
static void sfree(str_t *s);
struct memblock
{
memblock *next;
int size;
int allocated;
int remaining;
char *cur;
char data[];
};
static memblock *m_first;
static char *alloc_str(int n);
static void dealloc_str(void *ptr);
};
#endif /* _PSTRING_H_ */