From dec524a15174105df24dbfbee1927536e9ac932e Mon Sep 17 00:00:00 2001 From: Cary R Date: Fri, 16 Oct 2009 14:18:00 -0700 Subject: [PATCH] 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. --- vvp/main.cc | 1 + vvp/sfunc.cc | 11 +++++++++++ vvp/ufunc.cc | 13 ++++++++++++- vvp/vpi_real.cc | 4 ++++ vvp/vpi_signal.cc | 11 +++++++++++ vvp/vvp_cleanup.h | 1 + vvp/vvp_net.cc | 21 ++++++++++++++++++++- 7 files changed, 60 insertions(+), 2 deletions(-) diff --git a/vvp/main.cc b/vvp/main.cc index c0847abfb..ece1faf53 100644 --- a/vvp/main.cc +++ b/vvp/main.cc @@ -452,6 +452,7 @@ int main(int argc, char*argv[]) island_delete(); signal_pool_delete(); vvp_net_pool_delete(); + ufunc_pool_delete(); #endif return vvp_return_value; diff --git a/vvp/sfunc.cc b/vvp/sfunc.cc index d242dffeb..3ef1e4540 100644 --- a/vvp/sfunc.cc +++ b/vvp/sfunc.cc @@ -18,6 +18,10 @@ */ # include "compile.h" +# include "config.h" +#ifdef CHECK_WITH_VALGRIND +# include "vvp_cleanup.h" +#endif # include "sfunc.h" #ifdef HAVE_MALLOC_H # include @@ -39,6 +43,13 @@ sfunc_core::sfunc_core(vvp_net_t*net, vpiHandle sys, 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_; } /* diff --git a/vvp/ufunc.cc b/vvp/ufunc.cc index ff2a10508..94f585069 100644 --- a/vvp/ufunc.cc +++ b/vvp/ufunc.cc @@ -35,6 +35,7 @@ # include # include # include +# include #ifdef __MINGW32__ #include @@ -204,8 +205,18 @@ void compile_ufunc(char*label, char*code, unsigned wid, } #ifdef CHECK_WITH_VALGRIND +static map ufunc_map; + 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::iterator iter; + for (iter = ufunc_map.begin(); iter != ufunc_map.end(); iter++) { + delete iter->first; + } } #endif diff --git a/vvp/vpi_real.cc b/vvp/vpi_real.cc index ff0681dcb..d4108960c 100644 --- a/vvp/vpi_real.cc +++ b/vvp/vpi_real.cc @@ -21,6 +21,9 @@ # include "vpi_priv.h" # include "vvp_net_sig.h" # include "schedule.h" +#ifdef CHECK_WITH_VALGRIND +# include "vvp_cleanup.h" +#endif # include # include # include @@ -198,6 +201,7 @@ void real_delete(vpiHandle item) struct __vpiRealVar*obj = (struct __vpiRealVar*) item; assert(obj->net->fil); obj->net->fil->clear_all_callbacks(); + vvp_net_delete(obj->net); free(obj); } diff --git a/vvp/vpi_signal.cc b/vvp/vpi_signal.cc index bfbff61b9..19294555c 100644 --- a/vvp/vpi_signal.cc +++ b/vvp/vpi_signal.cc @@ -903,6 +903,8 @@ vpiHandle vpip_make_reg(const char*name, int msb, int lsb, #ifdef CHECK_WITH_VALGRIND static struct __vpiSignal **signal_pool = 0; static unsigned signal_pool_count = 0; +static unsigned long signal_count = 0; +static unsigned long signal_dels = 0; #endif static struct __vpiSignal* allocate_vpiSignal(void) @@ -930,6 +932,7 @@ static struct __vpiSignal* allocate_vpiSignal(void) #ifdef CHECK_WITH_VALGRIND VALGRIND_MEMPOOL_ALLOC(alloc_array, cur, sizeof(struct __vpiSignal)); cur->pool = alloc_array; + signal_count += 1; #endif alloc_index += 1; return cur; @@ -942,15 +945,23 @@ void signal_delete(vpiHandle item) assert(obj->node->fil); obj->node->fil->clear_all_callbacks(); vvp_net_delete(obj->node); + signal_dels += 1; VALGRIND_MEMPOOL_FREE(obj->pool, obj); } 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) { VALGRIND_DESTROY_MEMPOOL(signal_pool[idx]); free(signal_pool[idx]); } + free(signal_pool); signal_pool = 0; signal_pool_count = 0; diff --git a/vvp/vvp_cleanup.h b/vvp/vvp_cleanup.h index b6ac04a47..03c220a53 100644 --- a/vvp/vvp_cleanup.h +++ b/vvp/vvp_cleanup.h @@ -37,6 +37,7 @@ extern void signal_pool_delete(void); extern void udp_defns_delete(void); extern void vpi_handle_delete(void); extern void vvp_net_pool_delete(void); +extern void ufunc_pool_delete(void); extern void A_delete(struct __vpiHandle *item); extern void PV_delete(struct __vpiHandle *item); diff --git a/vvp/vvp_net.cc b/vvp/vvp_net.cc index 9a8217154..a9ee5c207 100644 --- a/vvp/vvp_net.cc +++ b/vvp/vvp_net.cc @@ -33,6 +33,7 @@ #ifdef CHECK_WITH_VALGRIND # include # include +# include "sfunc.h" #endif permaheap vvp_net_fun_t::heap_; @@ -82,19 +83,37 @@ void* vvp_net_t::operator new (size_t size) #ifdef CHECK_WITH_VALGRIND static map vvp_net_map; +static map sfunc_map; void vvp_net_delete(vvp_net_t *item) { - vvp_net_map[item] = true; + vvp_net_map[item] = true; + if (sfunc_core*tmp = dynamic_cast (item->fun)) { + sfunc_map[tmp] = true; + } } void vvp_net_pool_delete() { + unsigned long vvp_nets_del = 0; + map::iterator 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); } + map::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) { VALGRIND_DESTROY_MEMPOOL(vvp_net_pool[idx]) ::delete [] vvp_net_pool[idx];