More valgrind cleanup.

This patch adds code to cleanup system functions driving a
continuous assignment. It also modifies the user function
cleanup to not interfere with this. It also adds a count
of the nets and signals that were not cleaned up that is
pnly printed when running valgrind. They are not flagged
y valgrind since they are pool managed objects. There are
a few signals that need to be cleaned up and local nets
are missed so there are a lot of nets.
This commit is contained in:
Cary R 2009-10-16 14:18:00 -07:00 committed by Stephen Williams
parent c54cd4b473
commit dec524a151
7 changed files with 60 additions and 2 deletions

View File

@ -452,6 +452,7 @@ int main(int argc, char*argv[])
island_delete(); island_delete();
signal_pool_delete(); signal_pool_delete();
vvp_net_pool_delete(); vvp_net_pool_delete();
ufunc_pool_delete();
#endif #endif
return vvp_return_value; return vvp_return_value;

View File

@ -18,6 +18,10 @@
*/ */
# include "compile.h" # include "compile.h"
# include "config.h"
#ifdef CHECK_WITH_VALGRIND
# include "vvp_cleanup.h"
#endif
# include "sfunc.h" # include "sfunc.h"
#ifdef HAVE_MALLOC_H #ifdef HAVE_MALLOC_H
# include <malloc.h> # include <malloc.h>
@ -39,6 +43,13 @@ sfunc_core::sfunc_core(vvp_net_t*net, vpiHandle sys,
sfunc_core::~sfunc_core() sfunc_core::~sfunc_core()
{ {
delete sys_;
#ifdef CHECK_WITH_VALGRIND
for (unsigned i = 0; i < argc_; i += 1) {
constant_delete(argv_[i]);
}
#endif
delete [] argv_;
} }
/* /*

View File

@ -35,6 +35,7 @@
# include <string.h> # include <string.h>
# include <iostream> # include <iostream>
# include <assert.h> # include <assert.h>
# include <map>
#ifdef __MINGW32__ #ifdef __MINGW32__
#include <windows.h> #include <windows.h>
@ -204,8 +205,18 @@ void compile_ufunc(char*label, char*code, unsigned wid,
} }
#ifdef CHECK_WITH_VALGRIND #ifdef CHECK_WITH_VALGRIND
static map<ufunc_core*, bool> ufunc_map;
void exec_ufunc_delete(vvp_code_t euf_code) void exec_ufunc_delete(vvp_code_t euf_code)
{ {
delete euf_code->ufunc_core_ptr; ufunc_map[euf_code->ufunc_core_ptr] = true;
}
void ufunc_pool_delete(void)
{
map<ufunc_core*, bool>::iterator iter;
for (iter = ufunc_map.begin(); iter != ufunc_map.end(); iter++) {
delete iter->first;
}
} }
#endif #endif

View File

@ -21,6 +21,9 @@
# include "vpi_priv.h" # include "vpi_priv.h"
# include "vvp_net_sig.h" # include "vvp_net_sig.h"
# include "schedule.h" # include "schedule.h"
#ifdef CHECK_WITH_VALGRIND
# include "vvp_cleanup.h"
#endif
# include <stdio.h> # include <stdio.h>
# include <stdlib.h> # include <stdlib.h>
# include <string.h> # include <string.h>
@ -198,6 +201,7 @@ void real_delete(vpiHandle item)
struct __vpiRealVar*obj = (struct __vpiRealVar*) item; struct __vpiRealVar*obj = (struct __vpiRealVar*) item;
assert(obj->net->fil); assert(obj->net->fil);
obj->net->fil->clear_all_callbacks(); obj->net->fil->clear_all_callbacks();
vvp_net_delete(obj->net);
free(obj); free(obj);
} }

View File

@ -903,6 +903,8 @@ vpiHandle vpip_make_reg(const char*name, int msb, int lsb,
#ifdef CHECK_WITH_VALGRIND #ifdef CHECK_WITH_VALGRIND
static struct __vpiSignal **signal_pool = 0; static struct __vpiSignal **signal_pool = 0;
static unsigned signal_pool_count = 0; static unsigned signal_pool_count = 0;
static unsigned long signal_count = 0;
static unsigned long signal_dels = 0;
#endif #endif
static struct __vpiSignal* allocate_vpiSignal(void) static struct __vpiSignal* allocate_vpiSignal(void)
@ -930,6 +932,7 @@ static struct __vpiSignal* allocate_vpiSignal(void)
#ifdef CHECK_WITH_VALGRIND #ifdef CHECK_WITH_VALGRIND
VALGRIND_MEMPOOL_ALLOC(alloc_array, cur, sizeof(struct __vpiSignal)); VALGRIND_MEMPOOL_ALLOC(alloc_array, cur, sizeof(struct __vpiSignal));
cur->pool = alloc_array; cur->pool = alloc_array;
signal_count += 1;
#endif #endif
alloc_index += 1; alloc_index += 1;
return cur; return cur;
@ -942,15 +945,23 @@ void signal_delete(vpiHandle item)
assert(obj->node->fil); assert(obj->node->fil);
obj->node->fil->clear_all_callbacks(); obj->node->fil->clear_all_callbacks();
vvp_net_delete(obj->node); vvp_net_delete(obj->node);
signal_dels += 1;
VALGRIND_MEMPOOL_FREE(obj->pool, obj); VALGRIND_MEMPOOL_FREE(obj->pool, obj);
} }
void signal_pool_delete() void signal_pool_delete()
{ {
if (RUNNING_ON_VALGRIND && (signal_count != signal_dels)) {
fflush(NULL);
VALGRIND_PRINTF("Error: vvp missed deleting %lu signal(s).",
signal_count - signal_dels);
}
for (unsigned idx = 0; idx < signal_pool_count; idx += 1) { for (unsigned idx = 0; idx < signal_pool_count; idx += 1) {
VALGRIND_DESTROY_MEMPOOL(signal_pool[idx]); VALGRIND_DESTROY_MEMPOOL(signal_pool[idx]);
free(signal_pool[idx]); free(signal_pool[idx]);
} }
free(signal_pool); free(signal_pool);
signal_pool = 0; signal_pool = 0;
signal_pool_count = 0; signal_pool_count = 0;

View File

@ -37,6 +37,7 @@ extern void signal_pool_delete(void);
extern void udp_defns_delete(void); extern void udp_defns_delete(void);
extern void vpi_handle_delete(void); extern void vpi_handle_delete(void);
extern void vvp_net_pool_delete(void); extern void vvp_net_pool_delete(void);
extern void ufunc_pool_delete(void);
extern void A_delete(struct __vpiHandle *item); extern void A_delete(struct __vpiHandle *item);
extern void PV_delete(struct __vpiHandle *item); extern void PV_delete(struct __vpiHandle *item);

View File

@ -33,6 +33,7 @@
#ifdef CHECK_WITH_VALGRIND #ifdef CHECK_WITH_VALGRIND
# include <valgrind/memcheck.h> # include <valgrind/memcheck.h>
# include <map> # include <map>
# include "sfunc.h"
#endif #endif
permaheap vvp_net_fun_t::heap_; permaheap vvp_net_fun_t::heap_;
@ -82,19 +83,37 @@ void* vvp_net_t::operator new (size_t size)
#ifdef CHECK_WITH_VALGRIND #ifdef CHECK_WITH_VALGRIND
static map<vvp_net_t*, bool> vvp_net_map; static map<vvp_net_t*, bool> vvp_net_map;
static map<sfunc_core*, bool> sfunc_map;
void vvp_net_delete(vvp_net_t *item) void vvp_net_delete(vvp_net_t *item)
{ {
vvp_net_map[item] = true; vvp_net_map[item] = true;
if (sfunc_core*tmp = dynamic_cast<sfunc_core*> (item->fun)) {
sfunc_map[tmp] = true;
}
} }
void vvp_net_pool_delete() void vvp_net_pool_delete()
{ {
unsigned long vvp_nets_del = 0;
map<vvp_net_t*, bool>::iterator iter; map<vvp_net_t*, bool>::iterator iter;
for (iter = vvp_net_map.begin(); iter != vvp_net_map.end(); iter++) { for (iter = vvp_net_map.begin(); iter != vvp_net_map.end(); iter++) {
vvp_nets_del += 1;
VALGRIND_MEMPOOL_FREE(iter->first->pool, iter->first); VALGRIND_MEMPOOL_FREE(iter->first->pool, iter->first);
} }
map<sfunc_core*, bool>::iterator siter;
for (siter = sfunc_map.begin(); siter != sfunc_map.end(); siter++) {
delete siter->first;
}
if (RUNNING_ON_VALGRIND && (vvp_nets_del != count_vvp_nets)) {
fflush(NULL);
VALGRIND_PRINTF("Error: vvp missed deleting %lu net(s).",
count_vvp_nets - vvp_nets_del);
}
for (unsigned idx = 0; idx < vvp_net_pool_count; idx += 1) { for (unsigned idx = 0; idx < vvp_net_pool_count; idx += 1) {
VALGRIND_DESTROY_MEMPOOL(vvp_net_pool[idx]) VALGRIND_DESTROY_MEMPOOL(vvp_net_pool[idx])
::delete [] vvp_net_pool[idx]; ::delete [] vvp_net_pool[idx];