Fixed some netlist issues valgrind pointed me too. In addition, added a

strinb buffer class. (nw)
This commit is contained in:
couriersud 2015-05-26 11:40:35 +02:00
parent a04189ad13
commit 2f3085aa17
13 changed files with 209 additions and 204 deletions

View File

@ -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;
}
}

View File

@ -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] =

View File

@ -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),

View File

@ -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

View File

@ -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_ */

View File

@ -109,6 +109,11 @@ public:
}
}
~poptions()
{
m_opts.clear();
}
void register_option(poption *opt)
{
m_opts.add(opt);

View File

@ -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());
}

View File

@ -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:

View File

@ -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();
}

View File

@ -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)
{

View File

@ -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)
{
}
void *pblockpool::alloc(const std::size_t n)
{
if (IMMEDIATE_MODE)
return (char *) malloc(n);
else
if (m_ptr == NULL)
{
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;
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::dealloc(void *ptr)
void pstringbuffer::pcopy(const char *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 = strlen(from) + 1;
resize(nl);
std::strncpy(m_ptr, from, nl);
}
void pblockpool::resetmem()
void pstringbuffer::pcopy(const pstring &from)
{
if (!IMMEDIATE_MODE)
{
memblock **p = &m_first;
int totalblocks = 0;
int freedblocks = 0;
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);
}
std::size_t nl = from.len() + 1;
resize(nl);
std::strncpy(m_ptr, from.cstr(), nl);
}
void pstringbuffer::pcat(const char *s)
{
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;
}
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;
}

View File

@ -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_ */

View File

@ -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;
}