diff options
author | 2015-05-26 11:40:35 +0200 | |
---|---|---|
committer | 2015-05-26 11:41:36 +0200 | |
commit | 2f3085aa17c9114bae206337be26424f9a8d29fe (patch) | |
tree | 2d011b621a9247da6b3a6b1f1f68cbb10827c9b6 | |
parent | a04189ad133547f2c7fb248b1b09ff12b6db90d9 (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.h | 4 | ||||
-rw-r--r-- | src/emu/netlist/devices/nld_7490.c | 2 | ||||
-rw-r--r-- | src/emu/netlist/nl_base.c | 2 | ||||
-rw-r--r-- | src/emu/netlist/palloc.c | 3 | ||||
-rw-r--r-- | src/emu/netlist/palloc.h | 2 | ||||
-rw-r--r-- | src/emu/netlist/poptions.h | 5 | ||||
-rw-r--r-- | src/emu/netlist/pparser.c | 25 | ||||
-rw-r--r-- | src/emu/netlist/pparser.h | 5 | ||||
-rw-r--r-- | src/emu/netlist/pstate.c | 6 | ||||
-rw-r--r-- | src/emu/netlist/pstate.h | 5 | ||||
-rw-r--r-- | src/emu/netlist/pstring.c | 178 | ||||
-rw-r--r-- | src/emu/netlist/pstring.h | 151 | ||||
-rw-r--r-- | src/tools/nltool.c | 21 |
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; } |