summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author couriersud <couriersud@arcor.de>2015-05-26 11:40:35 +0200
committer couriersud <couriersud@arcor.de>2015-05-26 11:41:36 +0200
commit2f3085aa17c9114bae206337be26424f9a8d29fe (patch)
tree2d011b621a9247da6b3a6b1f1f68cbb10827c9b6
parenta04189ad133547f2c7fb248b1b09ff12b6db90d9 (diff)
Fixed some netlist issues valgrind pointed me too. In addition, added a
strinb buffer class. (nw)
-rw-r--r--src/emu/netlist/analog/nld_ms_direct.h4
-rw-r--r--src/emu/netlist/devices/nld_7490.c2
-rw-r--r--src/emu/netlist/nl_base.c2
-rw-r--r--src/emu/netlist/palloc.c3
-rw-r--r--src/emu/netlist/palloc.h2
-rw-r--r--src/emu/netlist/poptions.h5
-rw-r--r--src/emu/netlist/pparser.c25
-rw-r--r--src/emu/netlist/pparser.h5
-rw-r--r--src/emu/netlist/pstate.c6
-rw-r--r--src/emu/netlist/pstate.h5
-rw-r--r--src/emu/netlist/pstring.c178
-rw-r--r--src/emu/netlist/pstring.h151
-rw-r--r--src/tools/nltool.c21
13 files changed, 207 insertions, 202 deletions
diff --git a/src/emu/netlist/analog/nld_ms_direct.h b/src/emu/netlist/analog/nld_ms_direct.h
index cef321de60e..835d241d1d7 100644
--- a/src/emu/netlist/analog/nld_ms_direct.h
+++ b/src/emu/netlist/analog/nld_ms_direct.h
@@ -429,6 +429,8 @@ netlist_matrix_solver_direct_t<m_N, _storage_N>::netlist_matrix_solver_direct_t(
for (int k = 0; k < N(); k++)
{
m_terms[k] = palloc(terms_t);
+ m_last_RHS[k] = 0.0;
+ m_last_V[k] = 0.0;
}
}
@@ -444,6 +446,8 @@ netlist_matrix_solver_direct_t<m_N, _storage_N>::netlist_matrix_solver_direct_t(
for (int k = 0; k < N(); k++)
{
m_terms[k] = palloc(terms_t);
+ m_last_RHS[k] = 0.0;
+ m_last_V[k] = 0.0;
}
}
diff --git a/src/emu/netlist/devices/nld_7490.c b/src/emu/netlist/devices/nld_7490.c
index ad8a222928f..03317c96040 100644
--- a/src/emu/netlist/devices/nld_7490.c
+++ b/src/emu/netlist/devices/nld_7490.c
@@ -30,6 +30,8 @@ NETLIB_START(7490)
NETLIB_RESET(7490)
{
m_cnt = 0;
+ m_last_A = 0;
+ m_last_B = 0;
}
static const netlist_time delay[4] =
diff --git a/src/emu/netlist/nl_base.c b/src/emu/netlist/nl_base.c
index 090b9fe1a7d..55209337b86 100644
--- a/src/emu/netlist/nl_base.c
+++ b/src/emu/netlist/nl_base.c
@@ -184,7 +184,7 @@ ATTR_COLD void netlist_owned_object_t::init_object(netlist_core_device_t &dev,
// ----------------------------------------------------------------------------------------
netlist_base_t::netlist_base_t()
- : netlist_object_t(NETLIST, GENERIC),
+ : netlist_object_t(NETLIST, GENERIC), pstate_manager_t(),
m_stop(netlist_time::zero),
m_time(netlist_time::zero),
m_queue(*this),
diff --git a/src/emu/netlist/palloc.c b/src/emu/netlist/palloc.c
index 176a1968a9e..5f9dbc5fee7 100644
--- a/src/emu/netlist/palloc.c
+++ b/src/emu/netlist/palloc.c
@@ -13,14 +13,11 @@
void *palloc_raw(const size_t size)
{
- //size_t asize = ((size + 63) / 64) * 64;
- //return aligned_alloc(64, asize);
return _mm_malloc(size, 64);
}
void pfree_raw(void *p)
{
- //free(p);
_mm_free(p);
}
#endif
diff --git a/src/emu/netlist/palloc.h b/src/emu/netlist/palloc.h
index 7b6106aa73e..e78bbc6e3ab 100644
--- a/src/emu/netlist/palloc.h
+++ b/src/emu/netlist/palloc.h
@@ -100,8 +100,10 @@ inline void pfree_array_t(T *p)
#include "corealloc.h"
#define palloc(T, ...) global_alloc(T(__VA_ARGS__))
#define pfree(_ptr) global_free(_ptr)
+
#define palloc_array(T, N) global_alloc_array(T, N)
#define pfree_array(_ptr) global_free_array(_ptr)
+
#endif
#endif /* NLCONFIG_H_ */
diff --git a/src/emu/netlist/poptions.h b/src/emu/netlist/poptions.h
index 475bef2a719..f9929928731 100644
--- a/src/emu/netlist/poptions.h
+++ b/src/emu/netlist/poptions.h
@@ -109,6 +109,11 @@ public:
}
}
+ ~poptions()
+ {
+ m_opts.clear();
+ }
+
void register_option(poption *opt)
{
m_opts.add(opt);
diff --git a/src/emu/netlist/pparser.c b/src/emu/netlist/pparser.c
index d2f926a38bd..88bc822e52b 100644
--- a/src/emu/netlist/pparser.c
+++ b/src/emu/netlist/pparser.c
@@ -5,6 +5,8 @@
*
*/
+#include <cstdio>
+
#include "pparser.h"
//#undef NL_VERBOSE_OUT
@@ -218,6 +220,12 @@ ppreprocessor::ppreprocessor()
m_expr_sep.add("\t");
}
+void ppreprocessor::error(const pstring &err)
+{
+ fprintf(stderr, "PREPRO ERROR: %s\n", err.cstr());
+}
+
+
double ppreprocessor::expr(const nl_util::pstring_list &sexpr, int &start, int prio)
{
@@ -281,22 +289,22 @@ ppreprocessor::define_t *ppreprocessor::get_define(const pstring &name)
pstring ppreprocessor::replace_macros(const pstring &line)
{
nl_util::pstring_list elems = nl_util::splitexpr(line, m_expr_sep);
- pstring ret = "";
+ pstringbuffer ret = "";
for (int i=0; i<elems.count(); i++)
{
define_t *def = get_define(elems[i]);
if (def != NULL)
- ret = ret + def->m_replace;
+ ret.cat(def->m_replace);
else
- ret = ret + elems[i];
+ ret.cat(elems[i]);
}
- return ret;
+ return pstring(ret.cstr());
}
pstring ppreprocessor::process(const pstring &contents)
{
- pstring ret = "";
+ pstringbuffer ret = "";
nl_util::pstring_list lines = nl_util::split(contents,"\n", false);
UINT32 ifflag = 0; // 31 if levels
int level = 0;
@@ -346,9 +354,12 @@ pstring ppreprocessor::process(const pstring &contents)
//if (ifflag == 0 && level > 0)
// fprintf(stderr, "conditional: %s\n", line.cstr());
if (ifflag == 0)
- ret = ret + line + "\n";
+ {
+ ret.cat(line);
+ ret.cat("\n");
+ }
}
i++;
}
- return ret;
+ return pstring(ret.cstr());
}
diff --git a/src/emu/netlist/pparser.h b/src/emu/netlist/pparser.h
index 4a76aeb3d6b..3f287953df3 100644
--- a/src/emu/netlist/pparser.h
+++ b/src/emu/netlist/pparser.h
@@ -167,10 +167,7 @@ protected:
pstring replace_macros(const pstring &line);
- virtual void error(const pstring &err)
- {
- fprintf(stderr, "PREPRO ERROR: %s\n", err.cstr());
- }
+ virtual void error(const pstring &err);
private:
diff --git a/src/emu/netlist/pstate.c b/src/emu/netlist/pstate.c
index 84beaf7d622..0d2573592f3 100644
--- a/src/emu/netlist/pstate.c
+++ b/src/emu/netlist/pstate.c
@@ -7,7 +7,11 @@
#include "pstate.h"
-ATTR_COLD pstate_manager_t::~pstate_manager_t()
+pstate_manager_t::pstate_manager_t()
+{
+}
+
+pstate_manager_t::~pstate_manager_t()
{
m_save.clear_and_free();
}
diff --git a/src/emu/netlist/pstate.h b/src/emu/netlist/pstate.h
index 6b07ef40e72..faedcd9307e 100644
--- a/src/emu/netlist/pstate.h
+++ b/src/emu/netlist/pstate.h
@@ -98,6 +98,8 @@ struct pstate_entry_t
pstate_entry_t(const pstring &stname, const void *owner, pstate_callback_t *callback)
: m_name(stname), m_dt(DT_CUSTOM), m_owner(owner), m_callback(callback), m_size(0), m_count(0), m_ptr(NULL), m_is_ptr(false) { }
+ ~pstate_entry_t() { }
+
pstring m_name;
const pstate_data_type_e m_dt;
const void *m_owner;
@@ -121,7 +123,8 @@ class pstate_manager_t
{
public:
- ATTR_COLD ~pstate_manager_t();
+ pstate_manager_t();
+ ~pstate_manager_t();
template<typename C> ATTR_COLD void save_item(C &state, const void *owner, const pstring &stname)
{
diff --git a/src/emu/netlist/pstring.c b/src/emu/netlist/pstring.c
index bf49bb689ec..c5482e0f9b2 100644
--- a/src/emu/netlist/pstring.c
+++ b/src/emu/netlist/pstring.c
@@ -13,20 +13,20 @@
#include <cstdlib>
#include "pstring.h"
+#include "palloc.h"
// The following will work on linux, however not on Windows ....
//pblockpool *pstring::m_pool = new pblockpool;
//pstring::str_t *pstring::m_zero = new(pstring::m_pool, 0) pstring::str_t(0);
-pblockpool pstring::m_pool;
-pstring::str_t pstring::m_zero;
+pstring::str_t pstring::m_zero = str_t(0);
/*
* Uncomment the following to override defaults
*/
-//#define IMMEDIATE_MODE (1)
+#define IMMEDIATE_MODE (1)
//#define DEBUG_MODE (0)
#ifdef MAME_DEBUG
@@ -75,12 +75,12 @@ void pstring::pcopy(const char *from, int size)
pstring pstring::substr(unsigned int start, int count) const
{
+ pstring ret;
int alen = len();
if (start >= alen)
- return pstring();
+ return ret;
if (count <0 || start + count > alen)
count = alen - start;
- pstring ret;
ret.pcopy(cstr() + start, count);
return ret;
}
@@ -90,7 +90,7 @@ pstring pstring::ucase() const
pstring ret = *this;
ret.pcopy(cstr(), len());
for (int i=0; i<ret.len(); i++)
- ret.m_ptr->m_str[i] = toupper((unsigned) ret.m_ptr->m_str[i]);
+ ret.m_ptr->str()[i] = toupper((unsigned) ret.m_ptr->str()[i]);
return ret;
}
@@ -100,7 +100,7 @@ int pstring::find_first_not_of(const pstring no) const
{
bool f = true;
for (int j=0; j < no.len(); j++)
- if (m_ptr->m_str[i] == no.m_ptr->m_str[j])
+ if (m_ptr->str()[i] == no.m_ptr->str()[j])
f = false;
if (f)
return i;
@@ -114,7 +114,7 @@ int pstring::find_last_not_of(const pstring no) const
{
bool f = true;
for (int j=0; j < no.len(); j++)
- if (m_ptr->m_str[i] == no.m_ptr->m_str[j])
+ if (m_ptr->str()[i] == no.m_ptr->str()[j])
f = false;
if (f)
return i;
@@ -235,20 +235,24 @@ void pstring::sfree(str_t *s)
{
s->m_ref_count--;
if (s->m_ref_count == 0 && s != &m_zero)
- m_pool.dealloc(s);
+ {
+ pfree_array(((char *)s));
+ //_mm_free(((char *)s));
+ }
}
pstring::str_t *pstring::salloc(int n)
{
- str_t *ret = new(m_pool, n+1) str_t(n);
- return ret;
+ int size = sizeof(str_t) + n + 1;
+ str_t *p = (str_t *) palloc_array(char, size);
+ // str_t *p = (str_t *) _mm_malloc(size, 8);
+ p->init(n);
+ return p;
}
void pstring::resetmem()
{
// Release the 0 string
- m_pool.m_shutdown = true;
- m_pool.resetmem();
}
// ----------------------------------------------------------------------------------------
@@ -293,125 +297,65 @@ int pstring::pcmp(const char *left, const char *right, int count) const
}
// ----------------------------------------------------------------------------------------
-// block allocation pool
+// pstringbuffer
// ----------------------------------------------------------------------------------------
-
-pblockpool::pblockpool()
- : m_shutdown(false)
- , m_first(NULL)
- , m_blocksize((DEBUG_MODE) ? 16384 : 16384)
- , m_align(8)
+pstringbuffer::~pstringbuffer()
{
+ if (m_ptr != NULL)
+ pfree_array(m_ptr);
}
-pblockpool::~pblockpool()
+void pstringbuffer::resize(const std::size_t size)
{
+ if (m_ptr == NULL)
+ {
+ m_size = DEFAULT_SIZE;
+ while (m_size <= size)
+ m_size *= 2;
+ m_ptr = palloc_array(char, m_size);
+ m_len = 0;
+ }
+ else if (m_size < size)
+ {
+ while (m_size < size)
+ m_size *= 2;
+ char *new_buf = palloc_array(char, m_size);
+ std::strncpy(new_buf, m_ptr, m_len + 1);
+ pfree_array(m_ptr);
+ m_ptr = new_buf;
+ }
}
-
-void *pblockpool::alloc(const std::size_t n)
+void pstringbuffer::pcopy(const char *from)
{
- if (IMMEDIATE_MODE)
- return (char *) malloc(n);
- else
- {
- std::size_t memsize = ((n + m_align - 1) / m_align) * m_align;
- std::size_t min_alloc = std::max(m_blocksize, memsize+sizeof(memblock)-MINDATASIZE);
- 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 > memsize)
- {
- ret = p->cur;
- p->cur += memsize;
- p->allocated += 1;
- p->remaining -= memsize;
- }
- }
-
- 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)-MINDATASIZE);
- p->next = m_first;
- //std::printf("allocated block size %d\n", sizeof(p->data));
-
- ret = p->cur;
- p->cur += memsize;
- p->allocated += 1;
- p->remaining -= memsize;
-
- m_first = p;
- }
-
- return ret;
- }
+ std::size_t nl = strlen(from) + 1;
+ resize(nl);
+ std::strncpy(m_ptr, from, nl);
}
-void pblockpool::dealloc(void *ptr)
+void pstringbuffer::pcopy(const pstring &from)
{
- 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)
- std::fprintf(stderr, "nstring: memory corruption - crash likely\n");
- if (p->allocated == 0)
- {
- //std::printf("Block entirely freed\n");
- p->remaining = p->size;
- p->cur = &p->data[0];
- }
- // shutting down ?
- if (m_shutdown)
- resetmem(); // try to free blocks
- return;
- }
- }
- std::fprintf(stderr, "nstring: string <%p> not found on free\n", ptr);
- }
+ std::size_t nl = from.len() + 1;
+ resize(nl);
+ std::strncpy(m_ptr, from.cstr(), nl);
}
-void pblockpool::resetmem()
+void pstringbuffer::pcat(const char *s)
{
- if (!IMMEDIATE_MODE)
- {
- memblock **p = &m_first;
- int totalblocks = 0;
- int freedblocks = 0;
+ std::size_t slen = std::strlen(s);
+ std::size_t nl = m_len + slen + 1;
+ resize(nl);
+ std::strncpy(m_ptr + m_len, s, slen + 1);
+ m_len += slen;
+}
- 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());
-
- p = next;
- }
- }
- if (DEBUG_MODE)
- std::printf("Freed %d out of total %d blocks\n", freedblocks, totalblocks);
- }
+void pstringbuffer::pcat(const pstring &s)
+{
+ std::size_t slen = s.len();
+ std::size_t nl = m_len + slen + 1;
+ resize(nl);
+ std::strncpy(m_ptr + m_len, s.cstr(), slen + 1);
+ m_len += slen;
}
diff --git a/src/emu/netlist/pstring.h b/src/emu/netlist/pstring.h
index c17251c575c..ed1adbc9422 100644
--- a/src/emu/netlist/pstring.h
+++ b/src/emu/netlist/pstring.h
@@ -10,66 +10,9 @@
#include "pconfig.h"
// ----------------------------------------------------------------------------------------
-// pblockbool: allocate small memory more efficiently at the expense of some overhead
-// ----------------------------------------------------------------------------------------
-
-struct pblockpool {
-
-public:
- static const int MINDATASIZE = 8;
-
- pblockpool();
- ~pblockpool();
-
- void resetmem();
-
- void *alloc(std::size_t n);
- void dealloc(void *ptr);
-
- template<class T>
- void destroy(T* object)
- {
- object->~T();
- dealloc(object);
- }
- bool m_shutdown;
-
-private:
- struct memblock
- {
- memblock *next;
- int size;
- int allocated;
- int remaining;
- char *cur;
- char data[MINDATASIZE];
- };
-
- memblock *m_first;
- std::size_t m_blocksize;
- int m_align;
-};
-
-/* objects must be destroyed using destroy above */
-
-inline void *operator new(std::size_t size, pblockpool &pool, int extra = 0) throw (std::bad_alloc)
-{
- void *result = pool.alloc(size + extra);
- //std::printf("allocating %ld + %d\n", size, extra);
- if (result == NULL)
- throw std::bad_alloc();
- return result;
-}
-
-inline void operator delete(void *pMem, pblockpool &pool, ATTR_UNUSED int extra)
-{
- pool.dealloc(pMem);
-}
-
-// ----------------------------------------------------------------------------------------
-// nstring: immutable strings ...
+// pstring: immutable strings ...
//
-// nstrings are just a pointer to a "pascal-style" string representation.
+// pstrings are just a pointer to a "pascal-style" string representation.
// It uses reference counts and only uses new memory when a string changes.
// ----------------------------------------------------------------------------------------
@@ -98,6 +41,7 @@ public:
// concatenation operators
pstring& operator+=(const char c) { char buf[2] = { c, 0 }; pcat(buf); return *this; }
pstring& operator+=(const pstring &string) { pcat(string.cstr()); return *this; }
+ pstring& operator+=(const char *string) { pcat(string); 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 pstring &lhs, const char rhs) { return pstring(lhs) += rhs; }
@@ -117,7 +61,6 @@ public:
bool operator>=(const char *string) const { return (pcmp(string) >= 0); }
bool operator>=(const pstring &string) const { return (pcmp(string.cstr()) >= 0); }
- //
inline int len() const { return m_ptr->len(); }
inline bool equals(const pstring &string) const { return (pcmp(string.cstr(), m_ptr->str()) == 0); }
@@ -182,21 +125,27 @@ protected:
struct str_t
{
- str_t() : m_ref_count(1), m_len(0) { m_str[0] = 0; }
- str_t(int alen) : m_ref_count(1), m_len(alen) { m_str[0] = 0; }
-
+ //str_t() : m_ref_count(1), m_len(0) { m_str[0] = 0; }
+ str_t(const int alen)
+ {
+ init(alen);
+ }
+ void init(const int alen)
+ {
+ m_ref_count = 1;
+ m_len = alen;
+ m_str[0] = 0;
+ }
char *str() { return &m_str[0]; }
int len() { return m_len; }
- //private:
int m_ref_count;
+ private:
int m_len;
char m_str[1];
};
str_t *m_ptr;
- static pblockpool m_pool;
-
private:
inline void init()
{
@@ -232,6 +181,76 @@ private:
static str_t m_zero;
};
+// ----------------------------------------------------------------------------------------
+// pstringbuffer: a string buffer implementation
+//
+// string buffer are optimized to handle concatenations. This implementation is designed
+// to specifically interact with pstrings nicely.
+// ----------------------------------------------------------------------------------------
+
+struct pstringbuffer
+{
+public:
+ static const int DEFAULT_SIZE = 2048;
+ // simple construction/destruction
+ pstringbuffer()
+ {
+ init();
+ resize(DEFAULT_SIZE);
+ }
+
+ ~pstringbuffer();
+
+ // construction with copy
+ pstringbuffer(const char *string) {init(); if (string != NULL) pcopy(string); }
+ pstringbuffer(const pstring &string) {init(); pcopy(string); }
+
+ // assignment operators
+ pstringbuffer &operator=(const char *string) { pcopy(string); return *this; }
+ pstringbuffer &operator=(const pstring &string) { pcopy(string); return *this; }
+ pstringbuffer &operator=(const pstringbuffer &string) { pcopy(string.cstr()); return *this; }
+
+ // C string conversion operators and helpers
+ operator const char *() const { return m_ptr; }
+ inline const char *cstr() const { return m_ptr; }
+
+ operator pstring() const { return pstring(m_ptr); }
+
+ // concatenation operators
+ pstringbuffer& operator+=(const char c) { char buf[2] = { c, 0 }; pcat(buf); return *this; }
+ pstringbuffer& operator+=(const pstring &string) { pcat(string.cstr()); return *this; }
+
+ inline std::size_t len() const { return m_len; }
+
+ inline void cat(const pstring &s) { pcat(s); }
+ inline void cat(const char *s) { pcat(s); }
+
+ pstring substr(unsigned int start, int count = -1)
+ {
+ return pstring(m_ptr).substr(start, count);
+ }
+
+private:
+
+ inline void init()
+ {
+ m_ptr = NULL;
+ m_size = 0;
+ m_len = 0;
+ }
+
+ void resize(const std::size_t size);
+
+ void pcopy(const char *from);
+ void pcopy(const pstring &from);
+ void pcat(const char *s);
+ void pcat(const pstring &s);
+
+ char *m_ptr;
+ std::size_t m_size;
+ std::size_t m_len;
+
+};
#endif /* _PSTRING_H_ */
diff --git a/src/tools/nltool.c b/src/tools/nltool.c
index a2e70ced243..9b5a69c0dd6 100644
--- a/src/tools/nltool.c
+++ b/src/tools/nltool.c
@@ -175,7 +175,11 @@ public:
{
}
- virtual ~netlist_tool_t() { };
+ ~netlist_tool_t()
+ {
+ if (m_setup != NULL)
+ pfree(m_setup);
+ };
void init()
{
@@ -347,6 +351,13 @@ class convert_t
{
public:
+ convert_t() {};
+ ~convert_t()
+ {
+ nets.clear_and_free();
+ devs.clear_and_free();
+ }
+
void convert(const pstring &contents)
{
nl_util::pstring_list spnl = nl_util::split(contents, "\n");
@@ -650,8 +661,13 @@ convert_t::sp_unit convert_t::m_sp_units[] = {
main - primary entry point
-------------------------------------------------*/
+#include "corealloc.h"
+
int main(int argc, char *argv[])
{
+
+ track_memory(true);
+ {
tool_options_t opts;
int ret;
@@ -686,6 +702,7 @@ int main(int argc, char *argv[])
usage(opts);
return 1;
}
-
+ }
+ dump_unfreed_mem();
return 0;
}