From 92dcb76251ac5e26587f84e0f4924000773f09e5 Mon Sep 17 00:00:00 2001 From: Brian Taylor Date: Wed, 28 Jun 2023 22:11:11 -0700 Subject: [PATCH 1/4] Add DEVmodDelete functions to reduce memoory leaks in Cider models. The model memory was not freed during remcirc or quit. In the future, some of the code duplication could be refactored. The cmosinv.cir is now down to just 1 memory leak. --- src/spicelib/devices/nbjt/nbjtdel.c | 174 ++++++++++++++++++++++++ src/spicelib/devices/nbjt/nbjtext.h | 1 + src/spicelib/devices/nbjt/nbjtinit.c | 2 +- src/spicelib/devices/nbjt2/nbjt2ext.h | 1 + src/spicelib/devices/nbjt2/nbt2del.c | 175 ++++++++++++++++++++++++ src/spicelib/devices/nbjt2/nbt2init.c | 2 +- src/spicelib/devices/numd/numddel.c | 175 ++++++++++++++++++++++++ src/spicelib/devices/numd/numdext.h | 1 + src/spicelib/devices/numd/numdinit.c | 2 +- src/spicelib/devices/numd2/nud2del.c | 175 ++++++++++++++++++++++++ src/spicelib/devices/numd2/numd2ext.h | 1 + src/spicelib/devices/numd2/numd2init.c | 2 +- src/spicelib/devices/numos/nummdel.c | 176 +++++++++++++++++++++++++ src/spicelib/devices/numos/numosext.h | 1 + src/spicelib/devices/numos/numosinit.c | 2 +- 15 files changed, 885 insertions(+), 5 deletions(-) diff --git a/src/spicelib/devices/nbjt/nbjtdel.c b/src/spicelib/devices/nbjt/nbjtdel.c index b4997932e..976a88634 100644 --- a/src/spicelib/devices/nbjt/nbjtdel.c +++ b/src/spicelib/devices/nbjt/nbjtdel.c @@ -24,3 +24,177 @@ NBJTdelete(GENinstance *gen_inst) return OK; } + +int NBJTmodDelete(GENmodel *gen_model) +{ + NBJTmodel *model = (NBJTmodel *)gen_model; + MESHcard *xmesh = model->NBJTxMeshes; /* list of xmesh cards */ + MESHcard *ymesh = model->NBJTyMeshes; /* list of ymesh cards */ + DOMNcard *domains = model->NBJTdomains; /* list of domain cards */ + BDRYcard *boundaries = model->NBJTboundaries; /* list of boundary cards */ + DOPcard *dopings = model->NBJTdopings; /* list of doping cards */ + ELCTcard *electrodes = model->NBJTelectrodes; /* list of electrode cards */ + CONTcard *contacts = model->NBJTcontacts; /* list of contact cards */ + MODLcard *models = model->NBJTmodels; /* list of model cards */ + MATLcard *materials = model->NBJTmaterials; /* list of material cards */ + MOBcard *mobility = model->NBJTmobility; /* list of mobility cards */ + METHcard *methods = model->NBJTmethods; /* list of method cards */ + OPTNcard *options = model->NBJToptions; /* list of option cards */ + OUTPcard *outputs = model->NBJToutputs; /* list of output cards */ + TWOtranInfo *pInfo = model->NBJTpInfo; /* transient analysis information */ + DOPprofile *profiles = model->NBJTprofiles; /* expanded list of doping profiles */ + DOPtable *dopTables = model->NBJTdopTables; /* list of tables used by profiles */ + TWOmaterial *matlInfo = model->NBJTmatlInfo; /* list of material info structures */ + { + MESHcard *next = NULL, *this = NULL; + next = xmesh; + while (next) { + this = next; + next = next->MESHnextCard; + FREE(this); + } + } + { + MESHcard *next = NULL, *this = NULL; + next = ymesh; + while (next) { + this = next; + next = next->MESHnextCard; + FREE(this); + } + } + { + DOMNcard *next = NULL, *this = NULL; + next = domains; + while (next) { + this = next; + next = next->DOMNnextCard; + FREE(this); + } + } + { + BDRYcard *next = NULL, *this = NULL; + next = boundaries; + while (next) { + this = next; + next = next->BDRYnextCard; + FREE(this); + } + } + { + DOPcard *next = NULL, *this = NULL; + next = dopings; + while (next) { + this = next; + next = next->DOPnextCard; + if (this->DOPdomains) { + FREE(this->DOPdomains); + } + if (this->DOPinFile) { + FREE(this->DOPinFile); + } + FREE(this); + } + } + { + ELCTcard *next = NULL, *this = NULL; + next = electrodes; + while (next) { + this = next; + next = next->ELCTnextCard; + FREE(this); + } + } + { + CONTcard *next = NULL, *this = NULL; + next = contacts; + while (next) { + this = next; + next = next->CONTnextCard; + FREE(this); + } + } + { + MODLcard *next = NULL, *this = NULL; + next = models; + while (next) { + this = next; + next = next->MODLnextCard; + FREE(this); + } + } + { + MATLcard *next = NULL, *this = NULL; + next = materials; + while (next) { + this = next; + next = next->MATLnextCard; + FREE(this); + } + } + { + MOBcard *next = NULL, *this = NULL; + next = mobility; + while (next) { + this = next; + next = next->MOBnextCard; + FREE(this); + } + } + { + METHcard *next = NULL, *this = NULL; + next = methods; + while (next) { + this = next; + next = next->METHnextCard; + FREE(this); + } + } + { + OPTNcard *next = NULL, *this = NULL; + next = options; + while (next) { + this = next; + next = next->OPTNnextCard; + FREE(this); + } + } + { + OUTPcard *next = NULL, *this = NULL; + next = outputs; + while (next) { + this = next; + next = next->OUTPnextCard; + if (this->OUTProotFile) { + FREE(this->OUTProotFile); + } + FREE(this); + } + } + { + if (pInfo) { + FREE(pInfo); + } + } + { + DOPprofile *next = NULL, *this = NULL; + next = profiles; + while (next) { + this = next; + next = next->next; + FREE(this); + } + } + (void)dopTables; + { + TWOmaterial *next = NULL, *this = NULL; + next = matlInfo; + while (next) { + this = next; + next = next->next; + FREE(this); + } + } + + return OK; +} diff --git a/src/spicelib/devices/nbjt/nbjtext.h b/src/spicelib/devices/nbjt/nbjtext.h index 3d8f5d333..5e44a46cb 100644 --- a/src/spicelib/devices/nbjt/nbjtext.h +++ b/src/spicelib/devices/nbjt/nbjtext.h @@ -9,6 +9,7 @@ Author: 1987 Karti Mayaram extern int NBJTacLoad(GENmodel *, CKTcircuit *); extern int NBJTask(CKTcircuit *, GENinstance *, int, IFvalue *, IFvalue *); extern int NBJTdelete(GENinstance *); +extern int NBJTmodDelete(GENmodel *); extern int NBJTgetic(GENmodel *, CKTcircuit *); extern int NBJTload(GENmodel *, CKTcircuit *); extern int NBJTmParam(int, IFvalue *, GENmodel *); diff --git a/src/spicelib/devices/nbjt/nbjtinit.c b/src/spicelib/devices/nbjt/nbjtinit.c index 48378d766..b96e3cd7b 100644 --- a/src/spicelib/devices/nbjt/nbjtinit.c +++ b/src/spicelib/devices/nbjt/nbjtinit.c @@ -43,7 +43,7 @@ SPICEdev NBJTinfo = { .DEVacLoad = NBJTacLoad, .DEVaccept = NULL, .DEVdestroy = NULL, - .DEVmodDelete = NULL, + .DEVmodDelete = NBJTmodDelete, .DEVdelete = NBJTdelete, .DEVsetic = NULL, .DEVask = NBJTask, diff --git a/src/spicelib/devices/nbjt2/nbjt2ext.h b/src/spicelib/devices/nbjt2/nbjt2ext.h index 3e6ec0b96..121f3fbce 100644 --- a/src/spicelib/devices/nbjt2/nbjt2ext.h +++ b/src/spicelib/devices/nbjt2/nbjt2ext.h @@ -10,6 +10,7 @@ Author: 1987 Karti Mayaram extern int NBJT2acLoad(GENmodel *, CKTcircuit *); extern int NBJT2ask(CKTcircuit *, GENinstance *, int, IFvalue *, IFvalue *); extern int NBJT2delete(GENinstance *); +extern int NBJT2modDelete(GENmodel *); extern int NBJT2getic(GENmodel *, CKTcircuit *); extern int NBJT2load(GENmodel *, CKTcircuit *); extern int NBJT2mParam(int, IFvalue *, GENmodel *); diff --git a/src/spicelib/devices/nbjt2/nbt2del.c b/src/spicelib/devices/nbjt2/nbt2del.c index 4288abe46..7934e8079 100644 --- a/src/spicelib/devices/nbjt2/nbt2del.c +++ b/src/spicelib/devices/nbjt2/nbt2del.c @@ -14,6 +14,7 @@ Author: 1987 Kartikeya Mayaram, U. C. Berkeley CAD Group #include "../../../ciderlib/twod/twodext.h" #include "ngspice/sperror.h" #include "ngspice/suffix.h" +#include "ngspice/carddefs.h" int @@ -25,3 +26,177 @@ NBJT2delete(GENinstance *gen_inst) return OK; } + +int NBJT2modDelete(GENmodel *gen_model) +{ + NBJT2model *model = (NBJT2model *)gen_model; + MESHcard *xmesh = model->NBJT2xMeshes; /* list of xmesh cards */ + MESHcard *ymesh = model->NBJT2yMeshes; /* list of ymesh cards */ + DOMNcard *domains = model->NBJT2domains; /* list of domain cards */ + BDRYcard *boundaries = model->NBJT2boundaries; /* list of boundary cards */ + DOPcard *dopings = model->NBJT2dopings; /* list of doping cards */ + ELCTcard *electrodes = model->NBJT2electrodes; /* list of electrode cards */ + CONTcard *contacts = model->NBJT2contacts; /* list of contact cards */ + MODLcard *models = model->NBJT2models; /* list of model cards */ + MATLcard *materials = model->NBJT2materials; /* list of material cards */ + MOBcard *mobility = model->NBJT2mobility; /* list of mobility cards */ + METHcard *methods = model->NBJT2methods; /* list of method cards */ + OPTNcard *options = model->NBJT2options; /* list of option cards */ + OUTPcard *outputs = model->NBJT2outputs; /* list of output cards */ + TWOtranInfo *pInfo = model->NBJT2pInfo; /* transient analysis information */ + DOPprofile *profiles = model->NBJT2profiles; /* expanded list of doping profiles */ + DOPtable *dopTables = model->NBJT2dopTables; /* list of tables used by profiles */ + TWOmaterial *matlInfo = model->NBJT2matlInfo; /* list of material info structures */ + { + MESHcard *next = NULL, *this = NULL; + next = xmesh; + while (next) { + this = next; + next = next->MESHnextCard; + FREE(this); + } + } + { + MESHcard *next = NULL, *this = NULL; + next = ymesh; + while (next) { + this = next; + next = next->MESHnextCard; + FREE(this); + } + } + { + DOMNcard *next = NULL, *this = NULL; + next = domains; + while (next) { + this = next; + next = next->DOMNnextCard; + FREE(this); + } + } + { + BDRYcard *next = NULL, *this = NULL; + next = boundaries; + while (next) { + this = next; + next = next->BDRYnextCard; + FREE(this); + } + } + { + DOPcard *next = NULL, *this = NULL; + next = dopings; + while (next) { + this = next; + next = next->DOPnextCard; + if (this->DOPdomains) { + FREE(this->DOPdomains); + } + if (this->DOPinFile) { + FREE(this->DOPinFile); + } + FREE(this); + } + } + { + ELCTcard *next = NULL, *this = NULL; + next = electrodes; + while (next) { + this = next; + next = next->ELCTnextCard; + FREE(this); + } + } + { + CONTcard *next = NULL, *this = NULL; + next = contacts; + while (next) { + this = next; + next = next->CONTnextCard; + FREE(this); + } + } + { + MODLcard *next = NULL, *this = NULL; + next = models; + while (next) { + this = next; + next = next->MODLnextCard; + FREE(this); + } + } + { + MATLcard *next = NULL, *this = NULL; + next = materials; + while (next) { + this = next; + next = next->MATLnextCard; + FREE(this); + } + } + { + MOBcard *next = NULL, *this = NULL; + next = mobility; + while (next) { + this = next; + next = next->MOBnextCard; + FREE(this); + } + } + { + METHcard *next = NULL, *this = NULL; + next = methods; + while (next) { + this = next; + next = next->METHnextCard; + FREE(this); + } + } + { + OPTNcard *next = NULL, *this = NULL; + next = options; + while (next) { + this = next; + next = next->OPTNnextCard; + FREE(this); + } + } + { + OUTPcard *next = NULL, *this = NULL; + next = outputs; + while (next) { + this = next; + next = next->OUTPnextCard; + if (this->OUTProotFile) { + FREE(this->OUTProotFile); + } + FREE(this); + } + } + { + if (pInfo) { + FREE(pInfo); + } + } + { + DOPprofile *next = NULL, *this = NULL; + next = profiles; + while (next) { + this = next; + next = next->next; + FREE(this); + } + } + (void)dopTables; + { + TWOmaterial *next = NULL, *this = NULL; + next = matlInfo; + while (next) { + this = next; + next = next->next; + FREE(this); + } + } + + return OK; +} diff --git a/src/spicelib/devices/nbjt2/nbt2init.c b/src/spicelib/devices/nbjt2/nbt2init.c index d76e326ec..1e15f9cca 100644 --- a/src/spicelib/devices/nbjt2/nbt2init.c +++ b/src/spicelib/devices/nbjt2/nbt2init.c @@ -43,7 +43,7 @@ SPICEdev NBJT2info = { .DEVacLoad = NBJT2acLoad, .DEVaccept = NULL, .DEVdestroy = NULL, - .DEVmodDelete = NULL, + .DEVmodDelete = NBJT2modDelete, .DEVdelete = NBJT2delete, .DEVsetic = NULL, .DEVask = NBJT2ask, diff --git a/src/spicelib/devices/numd/numddel.c b/src/spicelib/devices/numd/numddel.c index fb1a42839..5e7824fa9 100644 --- a/src/spicelib/devices/numd/numddel.c +++ b/src/spicelib/devices/numd/numddel.c @@ -8,6 +8,7 @@ Author: 1987 Kartikeya Mayaram, U. C. Berkeley CAD Group #include "../../../ciderlib/oned/onedext.h" #include "ngspice/sperror.h" #include "ngspice/suffix.h" +#include "ngspice/carddefs.h" int @@ -19,3 +20,177 @@ NUMDdelete(GENinstance *gen_inst) return OK; } + +int NUMDmodDelete(GENmodel *gen_model) +{ + NUMDmodel *model = (NUMDmodel *)gen_model; + MESHcard *xmesh = model->NUMDxMeshes; /* list of xmesh cards */ + MESHcard *ymesh = model->NUMDyMeshes; /* list of ymesh cards */ + DOMNcard *domains = model->NUMDdomains; /* list of domain cards */ + BDRYcard *boundaries = model->NUMDboundaries; /* list of boundary cards */ + DOPcard *dopings = model->NUMDdopings; /* list of doping cards */ + ELCTcard *electrodes = model->NUMDelectrodes; /* list of electrode cards */ + CONTcard *contacts = model->NUMDcontacts; /* list of contact cards */ + MODLcard *models = model->NUMDmodels; /* list of model cards */ + MATLcard *materials = model->NUMDmaterials; /* list of material cards */ + MOBcard *mobility = model->NUMDmobility; /* list of mobility cards */ + METHcard *methods = model->NUMDmethods; /* list of method cards */ + OPTNcard *options = model->NUMDoptions; /* list of option cards */ + OUTPcard *outputs = model->NUMDoutputs; /* list of output cards */ + ONEtranInfo *pInfo = model->NUMDpInfo; /* transient analysis information */ + DOPprofile *profiles = model->NUMDprofiles; /* expanded list of doping profiles */ + DOPtable *dopTables = model->NUMDdopTables; /* list of tables used by profiles */ + ONEmaterial *matlInfo = model->NUMDmatlInfo; /* list of material info structures */ + { + MESHcard *next = NULL, *this = NULL; + next = xmesh; + while (next) { + this = next; + next = next->MESHnextCard; + FREE(this); + } + } + { + MESHcard *next = NULL, *this = NULL; + next = ymesh; + while (next) { + this = next; + next = next->MESHnextCard; + FREE(this); + } + } + { + DOMNcard *next = NULL, *this = NULL; + next = domains; + while (next) { + this = next; + next = next->DOMNnextCard; + FREE(this); + } + } + { + BDRYcard *next = NULL, *this = NULL; + next = boundaries; + while (next) { + this = next; + next = next->BDRYnextCard; + FREE(this); + } + } + { + DOPcard *next = NULL, *this = NULL; + next = dopings; + while (next) { + this = next; + next = next->DOPnextCard; + if (this->DOPdomains) { + FREE(this->DOPdomains); + } + if (this->DOPinFile) { + FREE(this->DOPinFile); + } + FREE(this); + } + } + { + ELCTcard *next = NULL, *this = NULL; + next = electrodes; + while (next) { + this = next; + next = next->ELCTnextCard; + FREE(this); + } + } + { + CONTcard *next = NULL, *this = NULL; + next = contacts; + while (next) { + this = next; + next = next->CONTnextCard; + FREE(this); + } + } + { + MODLcard *next = NULL, *this = NULL; + next = models; + while (next) { + this = next; + next = next->MODLnextCard; + FREE(this); + } + } + { + MATLcard *next = NULL, *this = NULL; + next = materials; + while (next) { + this = next; + next = next->MATLnextCard; + FREE(this); + } + } + { + MOBcard *next = NULL, *this = NULL; + next = mobility; + while (next) { + this = next; + next = next->MOBnextCard; + FREE(this); + } + } + { + METHcard *next = NULL, *this = NULL; + next = methods; + while (next) { + this = next; + next = next->METHnextCard; + FREE(this); + } + } + { + OPTNcard *next = NULL, *this = NULL; + next = options; + while (next) { + this = next; + next = next->OPTNnextCard; + FREE(this); + } + } + { + OUTPcard *next = NULL, *this = NULL; + next = outputs; + while (next) { + this = next; + next = next->OUTPnextCard; + if (this->OUTProotFile) { + FREE(this->OUTProotFile); + } + FREE(this); + } + } + { + if (pInfo) { + FREE(pInfo); + } + } + { + DOPprofile *next = NULL, *this = NULL; + next = profiles; + while (next) { + this = next; + next = next->next; + FREE(this); + } + } + (void)dopTables; + { + TWOmaterial *next = NULL, *this = NULL; + next = matlInfo; + while (next) { + this = next; + next = next->next; + FREE(this); + } + } + + return OK; +} diff --git a/src/spicelib/devices/numd/numdext.h b/src/spicelib/devices/numd/numdext.h index 39406ffca..5dc021bc9 100644 --- a/src/spicelib/devices/numd/numdext.h +++ b/src/spicelib/devices/numd/numdext.h @@ -10,6 +10,7 @@ Author: 1987 Karti Mayaram extern int NUMDacLoad(GENmodel *, CKTcircuit *); extern int NUMDask(CKTcircuit *, GENinstance *, int, IFvalue *, IFvalue *); extern int NUMDdelete(GENinstance *); +extern int NUMDmodDelete(GENmodel *); extern int NUMDgetic(GENmodel *, CKTcircuit *); extern int NUMDload(GENmodel *, CKTcircuit *); extern int NUMDmParam(int, IFvalue *, GENmodel *); diff --git a/src/spicelib/devices/numd/numdinit.c b/src/spicelib/devices/numd/numdinit.c index ba242600b..7200377e6 100644 --- a/src/spicelib/devices/numd/numdinit.c +++ b/src/spicelib/devices/numd/numdinit.c @@ -43,7 +43,7 @@ SPICEdev NUMDinfo = { .DEVacLoad = NUMDacLoad, .DEVaccept = NULL, .DEVdestroy = NULL, - .DEVmodDelete = NULL, + .DEVmodDelete = NUMDmodDelete, .DEVdelete = NUMDdelete, .DEVsetic = NULL, .DEVask = NUMDask, diff --git a/src/spicelib/devices/numd2/nud2del.c b/src/spicelib/devices/numd2/nud2del.c index 42d0ffdb8..0f04e7bbd 100644 --- a/src/spicelib/devices/numd2/nud2del.c +++ b/src/spicelib/devices/numd2/nud2del.c @@ -9,6 +9,7 @@ Author: 1987 Kartikeya Mayaram, U. C. Berkeley CAD Group #include "../../../ciderlib/twod/twodext.h" #include "ngspice/sperror.h" #include "ngspice/suffix.h" +#include "ngspice/carddefs.h" int @@ -20,3 +21,177 @@ NUMD2delete(GENinstance *gen_inst) return OK; } + +int NUMD2modDelete(GENmodel *gen_model) +{ + NUMD2model *model = (NUMD2model *)gen_model; + MESHcard *xmesh = model->NUMD2xMeshes; /* list of xmesh cards */ + MESHcard *ymesh = model->NUMD2yMeshes; /* list of ymesh cards */ + DOMNcard *domains = model->NUMD2domains; /* list of domain cards */ + BDRYcard *boundaries = model->NUMD2boundaries; /* list of boundary cards */ + DOPcard *dopings = model->NUMD2dopings; /* list of doping cards */ + ELCTcard *electrodes = model->NUMD2electrodes; /* list of electrode cards */ + CONTcard *contacts = model->NUMD2contacts; /* list of contact cards */ + MODLcard *models = model->NUMD2models; /* list of model cards */ + MATLcard *materials = model->NUMD2materials; /* list of material cards */ + MOBcard *mobility = model->NUMD2mobility; /* list of mobility cards */ + METHcard *methods = model->NUMD2methods; /* list of method cards */ + OPTNcard *options = model->NUMD2options; /* list of option cards */ + OUTPcard *outputs = model->NUMD2outputs; /* list of output cards */ + TWOtranInfo *pInfo = model->NUMD2pInfo; /* transient analysis information */ + DOPprofile *profiles = model->NUMD2profiles; /* expanded list of doping profiles */ + DOPtable *dopTables = model->NUMD2dopTables; /* list of tables used by profiles */ + TWOmaterial *matlInfo = model->NUMD2matlInfo; /* list of material info structures */ + { + MESHcard *next = NULL, *this = NULL; + next = xmesh; + while (next) { + this = next; + next = next->MESHnextCard; + FREE(this); + } + } + { + MESHcard *next = NULL, *this = NULL; + next = ymesh; + while (next) { + this = next; + next = next->MESHnextCard; + FREE(this); + } + } + { + DOMNcard *next = NULL, *this = NULL; + next = domains; + while (next) { + this = next; + next = next->DOMNnextCard; + FREE(this); + } + } + { + BDRYcard *next = NULL, *this = NULL; + next = boundaries; + while (next) { + this = next; + next = next->BDRYnextCard; + FREE(this); + } + } + { + DOPcard *next = NULL, *this = NULL; + next = dopings; + while (next) { + this = next; + next = next->DOPnextCard; + if (this->DOPdomains) { + FREE(this->DOPdomains); + } + if (this->DOPinFile) { + FREE(this->DOPinFile); + } + FREE(this); + } + } + { + ELCTcard *next = NULL, *this = NULL; + next = electrodes; + while (next) { + this = next; + next = next->ELCTnextCard; + FREE(this); + } + } + { + CONTcard *next = NULL, *this = NULL; + next = contacts; + while (next) { + this = next; + next = next->CONTnextCard; + FREE(this); + } + } + { + MODLcard *next = NULL, *this = NULL; + next = models; + while (next) { + this = next; + next = next->MODLnextCard; + FREE(this); + } + } + { + MATLcard *next = NULL, *this = NULL; + next = materials; + while (next) { + this = next; + next = next->MATLnextCard; + FREE(this); + } + } + { + MOBcard *next = NULL, *this = NULL; + next = mobility; + while (next) { + this = next; + next = next->MOBnextCard; + FREE(this); + } + } + { + METHcard *next = NULL, *this = NULL; + next = methods; + while (next) { + this = next; + next = next->METHnextCard; + FREE(this); + } + } + { + OPTNcard *next = NULL, *this = NULL; + next = options; + while (next) { + this = next; + next = next->OPTNnextCard; + FREE(this); + } + } + { + OUTPcard *next = NULL, *this = NULL; + next = outputs; + while (next) { + this = next; + next = next->OUTPnextCard; + if (this->OUTProotFile) { + FREE(this->OUTProotFile); + } + FREE(this); + } + } + { + if (pInfo) { + FREE(pInfo); + } + } + { + DOPprofile *next = NULL, *this = NULL; + next = profiles; + while (next) { + this = next; + next = next->next; + FREE(this); + } + } + (void)dopTables; + { + TWOmaterial *next = NULL, *this = NULL; + next = matlInfo; + while (next) { + this = next; + next = next->next; + FREE(this); + } + } + + return OK; +} diff --git a/src/spicelib/devices/numd2/numd2ext.h b/src/spicelib/devices/numd2/numd2ext.h index 618c4c7c4..94eef7e0e 100644 --- a/src/spicelib/devices/numd2/numd2ext.h +++ b/src/spicelib/devices/numd2/numd2ext.h @@ -10,6 +10,7 @@ Author: 1987 Karti Mayaram extern int NUMD2acLoad(GENmodel *, CKTcircuit *); extern int NUMD2ask(CKTcircuit *, GENinstance *, int, IFvalue *, IFvalue *); extern int NUMD2delete(GENinstance *); +extern int NUMD2modDelete(GENmodel *); extern int NUMD2getic(GENmodel *, CKTcircuit *); extern int NUMD2load(GENmodel *, CKTcircuit *); extern int NUMD2mParam(int, IFvalue *, GENmodel *); diff --git a/src/spicelib/devices/numd2/numd2init.c b/src/spicelib/devices/numd2/numd2init.c index 6b2ab458a..af82e3b78 100644 --- a/src/spicelib/devices/numd2/numd2init.c +++ b/src/spicelib/devices/numd2/numd2init.c @@ -43,7 +43,7 @@ SPICEdev NUMD2info = { .DEVacLoad = NUMD2acLoad, .DEVaccept = NULL, .DEVdestroy = NULL, - .DEVmodDelete = NULL, + .DEVmodDelete = NUMD2modDelete, .DEVdelete = NUMD2delete, .DEVsetic = NULL, .DEVask = NUMD2ask, diff --git a/src/spicelib/devices/numos/nummdel.c b/src/spicelib/devices/numos/nummdel.c index 850c806da..e7432ca8c 100644 --- a/src/spicelib/devices/numos/nummdel.c +++ b/src/spicelib/devices/numos/nummdel.c @@ -14,6 +14,7 @@ Author: 1987 Kartikeya Mayaram, U. C. Berkeley CAD Group #include "../../../ciderlib/twod/twodext.h" #include "ngspice/sperror.h" #include "ngspice/suffix.h" +#include "ngspice/carddefs.h" int @@ -25,3 +26,178 @@ NUMOSdelete(GENinstance *gen_inst) return OK; } + +int NUMOSmodDelete(GENmodel *gen_model) +{ + NUMOSmodel *model = (NUMOSmodel *)gen_model; + MESHcard *xmesh = model->NUMOSxMeshes; /* list of xmesh cards */ + MESHcard *ymesh = model->NUMOSyMeshes; /* list of ymesh cards */ + DOMNcard *domains = model->NUMOSdomains; /* list of domain cards */ + BDRYcard *boundaries = model->NUMOSboundaries; /* list of boundary cards */ + DOPcard *dopings = model->NUMOSdopings; /* list of doping cards */ + ELCTcard *electrodes = model->NUMOSelectrodes; /* list of electrode cards */ + CONTcard *contacts = model->NUMOScontacts; /* list of contact cards */ + MODLcard *models = model->NUMOSmodels; /* list of model cards */ + MATLcard *materials = model->NUMOSmaterials; /* list of material cards */ + MOBcard *mobility = model->NUMOSmobility; /* list of mobility cards */ + METHcard *methods = model->NUMOSmethods; /* list of method cards */ + OPTNcard *options = model->NUMOSoptions; /* list of option cards */ + OUTPcard *outputs = model->NUMOSoutputs; /* list of output cards */ + TWOtranInfo *pInfo = model->NUMOSpInfo; /* transient analysis information */ + DOPprofile *profiles = model->NUMOSprofiles; /* expanded list of doping profiles */ + DOPtable *dopTables = model->NUMOSdopTables; /* list of tables used by profiles */ + TWOmaterial *matlInfo = model->NUMOSmatlInfo; /* list of material info structures */ + { + MESHcard *next = NULL, *this = NULL; + next = xmesh; + while (next) { + this = next; + next = next->MESHnextCard; + FREE(this); + } + } + { + MESHcard *next = NULL, *this = NULL; + next = ymesh; + while (next) { + this = next; + next = next->MESHnextCard; + FREE(this); + } + } + { + DOMNcard *next = NULL, *this = NULL; + next = domains; + while (next) { + this = next; + next = next->DOMNnextCard; + FREE(this); + } + } + { + BDRYcard *next = NULL, *this = NULL; + next = boundaries; + while (next) { + this = next; + next = next->BDRYnextCard; + FREE(this); + } + } + { + DOPcard *next = NULL, *this = NULL; + next = dopings; + while (next) { + this = next; + next = next->DOPnextCard; + if (this->DOPdomains) { + FREE(this->DOPdomains); + } + if (this->DOPinFile) { + FREE(this->DOPinFile); + } + FREE(this); + } + } + { + ELCTcard *next = NULL, *this = NULL; + next = electrodes; + while (next) { + this = next; + next = next->ELCTnextCard; + FREE(this); + } + } + { + CONTcard *next = NULL, *this = NULL; + next = contacts; + while (next) { + this = next; + next = next->CONTnextCard; + FREE(this); + } + } + { + MODLcard *next = NULL, *this = NULL; + next = models; + while (next) { + this = next; + next = next->MODLnextCard; + FREE(this); + } + } + { + MATLcard *next = NULL, *this = NULL; + next = materials; + while (next) { + this = next; + next = next->MATLnextCard; + FREE(this); + } + } + { + MOBcard *next = NULL, *this = NULL; + next = mobility; + while (next) { + this = next; + next = next->MOBnextCard; + FREE(this); + } + } + { + METHcard *next = NULL, *this = NULL; + next = methods; + while (next) { + this = next; + next = next->METHnextCard; + FREE(this); + } + } + { + OPTNcard *next = NULL, *this = NULL; + next = options; + while (next) { + this = next; + next = next->OPTNnextCard; + FREE(this); + } + } + { + OUTPcard *next = NULL, *this = NULL; + next = outputs; + while (next) { + this = next; + next = next->OUTPnextCard; + if (this->OUTProotFile) { + FREE(this->OUTProotFile); + } + FREE(this); + } + } + { + if (pInfo) { + FREE(pInfo); + } + } + { + DOPprofile *next = NULL, *this = NULL; + next = profiles; + while (next) { + this = next; + next = next->next; + FREE(this); + } + } + (void)dopTables; + { + TWOmaterial *next = NULL, *this = NULL; + next = matlInfo; + while (next) { + this = next; + next = next->next; + FREE(this); + } + } + + return OK; +} + diff --git a/src/spicelib/devices/numos/numosext.h b/src/spicelib/devices/numos/numosext.h index 1aa2d4dd5..57941c459 100644 --- a/src/spicelib/devices/numos/numosext.h +++ b/src/spicelib/devices/numos/numosext.h @@ -10,6 +10,7 @@ Author: 1987 Karti Mayaram extern int NUMOSacLoad(GENmodel *, CKTcircuit *); extern int NUMOSask(CKTcircuit *, GENinstance *, int, IFvalue *, IFvalue *); extern int NUMOSdelete(GENinstance *); +extern int NUMOSmodDelete(GENmodel *); extern int NUMOSgetic(GENmodel *, CKTcircuit *); extern int NUMOSload(GENmodel *, CKTcircuit *); extern int NUMOSmParam(int, IFvalue *, GENmodel *); diff --git a/src/spicelib/devices/numos/numosinit.c b/src/spicelib/devices/numos/numosinit.c index c6d8026f0..e3201b3bd 100644 --- a/src/spicelib/devices/numos/numosinit.c +++ b/src/spicelib/devices/numos/numosinit.c @@ -43,7 +43,7 @@ SPICEdev NUMOSinfo = { .DEVacLoad = NUMOSacLoad, .DEVaccept = NULL, .DEVdestroy = NULL, - .DEVmodDelete = NULL, + .DEVmodDelete = NUMOSmodDelete, .DEVdelete = NUMOSdelete, .DEVsetic = NULL, .DEVask = NUMOSask, From 40a89b16e628078f747a1bc972dc2908dd4dc7b7 Mon Sep 17 00:00:00 2001 From: Brian Taylor Date: Thu, 29 Jun 2023 17:43:34 -0700 Subject: [PATCH 2/4] Fix the Cider memory leaks from setupContacts. TWOdestroy needed to free the contact nodes. --- src/ciderlib/twod/twodest.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ciderlib/twod/twodest.c b/src/ciderlib/twod/twodest.c index 2466eea44..6294b852d 100644 --- a/src/ciderlib/twod/twodest.c +++ b/src/ciderlib/twod/twodest.c @@ -85,6 +85,9 @@ TWOdestroy(TWOdevice *pDevice) struct sTWOcontact* pFCtmp = pDevice->pFirstContact; while (pFCtmp) { struct sTWOcontact* pFCtmpnext = pFCtmp->next; + if (pFCtmp->pNodes) { + FREE(pFCtmp->pNodes); + } FREE(pFCtmp); pFCtmp = pFCtmpnext; } From e83fae11bc5d229f7e7d0a268294d7225dd46229 Mon Sep 17 00:00:00 2001 From: dwarning Date: Sun, 2 Jul 2023 16:16:51 +0200 Subject: [PATCH 3/4] same array size for in- and output in inverse fft function from fftw3 --- src/maths/cmaths/cmath4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/maths/cmaths/cmath4.c b/src/maths/cmaths/cmath4.c index fa2b7cb6f..0f9078950 100644 --- a/src/maths/cmaths/cmath4.c +++ b/src/maths/cmaths/cmath4.c @@ -933,7 +933,7 @@ cx_ifft(void *data, short int type, int length, int *newlength, short int *newty printf("IFFT: Frequency span: %g Hz, input length: %d\n", 1/span*length, length); printf("IFFT: Time resolution: %g s, output length: %d\n", span/(tpts-1), tpts); - in = fftw_malloc(sizeof(fftw_complex) * (unsigned int) length); + in = fftw_malloc(sizeof(fftw_complex) * (unsigned int) tpts); out = fftw_malloc(sizeof(fftw_complex) * (unsigned int) tpts); for (i = 0; i < length; i++) { From 4c4a9c78ec48dc26837b4a1eba6a8017e9b37e48 Mon Sep 17 00:00:00 2001 From: dwarning Date: Mon, 3 Jul 2023 10:07:32 +0200 Subject: [PATCH 4/4] ifft: in case input array is smaller then output array - fill in the rest with zero to prevent uninitialzed plot variables --- src/maths/cmaths/cmath4.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/maths/cmaths/cmath4.c b/src/maths/cmaths/cmath4.c index 0f9078950..50d772761 100644 --- a/src/maths/cmaths/cmath4.c +++ b/src/maths/cmaths/cmath4.c @@ -940,6 +940,10 @@ cx_ifft(void *data, short int type, int length, int *newlength, short int *newty in[i][0] = indata[i].cx_real; in[i][1] = indata[i].cx_imag; } + for (i = length; i < tpts; i++) { + in[i][0] = 0.0; + in[i][1] = 0.0; + } plan_backward = fftw_plan_dft_1d(tpts, in, out, FFTW_BACKWARD, FFTW_ESTIMATE);