From 957d7edd645740989849146dca2bc36d41bd0987 Mon Sep 17 00:00:00 2001 From: "R. Timothy Edwards" Date: Fri, 7 Nov 2025 11:00:22 -0500 Subject: [PATCH] A number of things in one commit: 1) Added a "*showmem" "wizard" command to get a dump of all memory being used by tiles in the database. 2) Made a slight correction to the way magic detects exact overlap of instances of the same cell. This probably does not make any actual difference in practice. 3) Corrected an uninitialized variable in dbReComputeBboxFunc(). 4) Changes DBSrCellPlaneArea() to use a static BPEnum variable, so that it does not waste time allocating and freeing memory for the same thing over and over again. 5) Corrected a memory leak in the tech file "extract" section that loses memory every time the extraction style is changed. 6) Corrected the tile join routines to fix a bad memory leak in the tile allocation and recovery---a fix which was mentioned in issue #414 but which had not yet been implemented. This has now been tested and confirmed to work. --- VERSION | 2 +- cif/CIFint.h | 3 + commands/CmdWizard.c | 231 +++++++++++++++++++++++++++++++++++++++++ database/DBcell.c | 13 ++- database/DBcellbox.c | 5 +- database/DBcellsrch.c | 6 +- database/databaseInt.h | 2 + dbwind/DBWcommands.c | 4 + extract/ExtTech.c | 1 + tiles/tile.c | 6 ++ tiles/tile.h | 10 ++ 11 files changed, 275 insertions(+), 8 deletions(-) diff --git a/VERSION b/VERSION index c9e59e47..84b91e5d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.573 +8.3.574 diff --git a/cif/CIFint.h b/cif/CIFint.h index c7522b94..4f4f4a43 100644 --- a/cif/CIFint.h +++ b/cif/CIFint.h @@ -367,6 +367,9 @@ extern CellUse *CIFDummyUse; /* Used to dummy up a CellUse for a * def. */ +extern Plane *CIFTotalPlanes[]; /* Exported for diagnostics */ +extern Plane *CIFComponentPlanes[]; /* Exported for diagnostics */ + /* Valid values of CIFWarningLevel (see cif.h) */ typedef enum {CIF_WARN_DEFAULT, CIF_WARN_NONE, CIF_WARN_ALIGN, diff --git a/commands/CmdWizard.c b/commands/CmdWizard.c index 06ef55ab..e746943d 100644 --- a/commands/CmdWizard.c +++ b/commands/CmdWizard.c @@ -47,6 +47,10 @@ static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magi #include "utils/utils.h" #include "textio/txcommands.h" +/* For diagnostics */ +#include "cif/CIFint.h" +#include "database/databaseInt.h" + /* C99 compat */ #include "extract/extract.h" @@ -189,6 +193,233 @@ CmdExtractTest( } #endif +/* + * ---------------------------------------------------------------------------- + * + * tileCountProc -- + * + * Routine to count tiles. + * + * Return: + * 0 to keep the search going + * + * Side effects: + * Keeps count in clientData + * + * ---------------------------------------------------------------------------- + */ + +int +tileCountProc( + Tile *tile, + int *tcount) +{ + (*tcount)++; + return 0; +} + +/* + * ---------------------------------------------------------------------------- + * + * showMem -- + * CmdShowmem -- + * + * Usage: + * + * showmem [outfile] + * + * Display all the (principle) internal memory usage for tiles, including + * all cell defs, and all CIF generated planes. + * + * Results: + * None. + * + * Side effects: + * May write to a disk file. + * + * ---------------------------------------------------------------------------- + */ + +void +showMem( + FILE *outf, /* File to which information is to be output */ + bool verbose) /* If TRUE, output detailed erase table */ +{ + int ttotal, ttotal1, ttotal2; + int i; + Plane *plane; + CellDef *def; + int pNum; + HashSearch hs; + HashEntry *entry; + + fprintf(outf, "Tile memory usage summary\n"); + fprintf(outf, "Technology %s\n", DBTechName); + + /* Search every cell def (including internal ones), count tiles, + * and add up the tile memory usage on every plane. + */ + + /* Search the CIFPlanes and count tiles. */ + /* CIFPlanes, CIFTotalPlanes, CIFComponentPlanes */ + + ttotal2 = 0; + if (CIFCurStyle != NULL) + { + fprintf(outf, "\nCIFPlanes:\n"); + ttotal1 = 0; + for (i = 0; i < MAXCIFLAYERS; i++) + { + plane = CIFPlanes[i]; + if (plane != NULL) + { + ttotal = 0; + DBSrPaintArea((Tile *)NULL, plane, &TiPlaneRect, + &DBAllTypeBits, tileCountProc, &ttotal); + ttotal1 += ttotal; + + if (CIFCurStyle->cs_layers[i]) + fprintf(outf, " layer %s: %ld\n", + CIFCurStyle->cs_layers[i]->cl_name, + (long)ttotal * (long)sizeof(Tile)); + else + fprintf(outf, " layer %d: %d\n", i, + (long)ttotal * (long)sizeof(Tile)); + } + } + fprintf(outf, " Subtotal: %ld bytes\n", + (long)ttotal1 * (long)sizeof(Tile)); + ttotal2 += ttotal1; + + fprintf(outf, "\nCIFTotalPlanes\n"); + ttotal1 = 0; + for (i = 0; i < MAXCIFLAYERS; i++) + { + plane = CIFTotalPlanes[i]; + if (plane != NULL) + { + ttotal = 0; + DBSrPaintArea((Tile *)NULL, plane, &TiPlaneRect, + &DBAllTypeBits, tileCountProc, &ttotal); + ttotal1 += ttotal; + + if (CIFCurStyle->cs_layers[i]) + fprintf(outf, " layer %s: %ld\n", + CIFCurStyle->cs_layers[i]->cl_name, + (long)ttotal * (long)sizeof(Tile)); + else + fprintf(outf, " layer %d: %d\n", i, + (long)ttotal * (long)sizeof(Tile)); + } + } + fprintf(outf, " Subtotal: %ld bytes\n", + (long)ttotal1 * (long)sizeof(Tile)); + ttotal2 += ttotal1; + + fprintf(outf, "\nCIFComponentPlanes\n"); + ttotal1 = 0; + for (i = 0; i < MAXCIFLAYERS; i++) + { + plane = CIFComponentPlanes[i]; + if (plane != NULL) + { + ttotal = 0; + DBSrPaintArea((Tile *)NULL, plane, &TiPlaneRect, + &DBAllTypeBits, tileCountProc, &ttotal); + ttotal1 += ttotal; + + if (CIFCurStyle->cs_layers[i]) + fprintf(outf, " layer %s: %ld bytes\n", + CIFCurStyle->cs_layers[i]->cl_name, + (long)ttotal * (long)sizeof(Tile)); + else + fprintf(outf, " layer %d: %ld bytes\n", i, + (long)ttotal * (long)sizeof(Tile)); + } + } + fprintf(outf, " Subtotal: %ld bytes\n", + (long)ttotal1 * (long)sizeof(Tile)); + ttotal2 += ttotal1; + } + else + { + fprintf(outf, "CIF planes: No memory usage\n"); + } + + HashStartSearch(&hs); + while ((entry = HashNext(&dbCellDefTable, &hs)) != NULL) + { + def = (CellDef *)HashGetValue(entry); + if (def != (CellDef *)NULL) + { + fprintf(outf, "\nCell def %s\n", def->cd_name); + ttotal1 = 0; + for (pNum = 0; pNum < DBNumPlanes; pNum++) + { + plane = def->cd_planes[pNum]; + if (plane != NULL) + { + ttotal = 0; + DBSrPaintArea((Tile *)NULL, plane, &TiPlaneRect, + &DBAllTypeBits, tileCountProc, &ttotal); + + fprintf(outf, " plane %s: %ld bytes\n", + DBPlaneLongNameTbl[pNum], + (long)ttotal * (long)sizeof(Tile)); + ttotal1 += ttotal; + } + } + fprintf(outf, " Subtotal: %ld bytes\n", + (long)ttotal1 * (long)sizeof(Tile)); + ttotal2 += ttotal1; + } + } + fprintf(outf, " Grand total: %ld bytes\n", + (long)ttotal2 * (long)sizeof(Tile)); +} + +void +CmdShowmem( + MagWindow *w, + TxCommand *cmd) +{ + FILE *outf; + bool verbose; + char **av; + int ac; + + if (cmd->tx_argc > 3) + { + TxError("Usage: showmem [-v] [file]\n"); + return; + } + + verbose = FALSE; + av = &cmd->tx_argv[1]; + ac = cmd->tx_argc - 1; + + outf = stdout; + if (ac > 0 && strcmp(av[0], "-v") == 0) + { + verbose = TRUE; + av++, ac--; + } + + if (ac > 0) + { + outf = fopen(av[0], "w"); + if (outf == (FILE *) NULL) + { + perror(av[0]); + TxError("Nothing written\n"); + return; + } + } + + showMem(outf, verbose); + if (outf != stdout) + (void) fclose(outf); +} /* * ---------------------------------------------------------------------------- diff --git a/database/DBcell.c b/database/DBcell.c index a28d4493..3a9eca15 100644 --- a/database/DBcell.c +++ b/database/DBcell.c @@ -109,14 +109,23 @@ DBCellFindDup(use, parent) while ((dupUse = BPEnumNext(&bpe))) if (dupUse->cu_def == use->cu_def) /* Transforms must be equal---Aligned bounding boxes are - * an insufficient measure of exact overlap. + * an insufficient measure of exact overlap. Also, array + * counts and separation must match for arrayed devices */ if ((dupUse->cu_transform.t_a == use->cu_transform.t_a) && (dupUse->cu_transform.t_b == use->cu_transform.t_b) && (dupUse->cu_transform.t_c == use->cu_transform.t_c) && (dupUse->cu_transform.t_d == use->cu_transform.t_d) && (dupUse->cu_transform.t_e == use->cu_transform.t_e) && - (dupUse->cu_transform.t_f == use->cu_transform.t_f)) + (dupUse->cu_transform.t_f == use->cu_transform.t_f) && + ((dupUse->cu_xhi > dupUse->cu_xlo) && + ((dupUse->cu_xhi - dupUse->cu_xlo) == + (use->cu_xhi - use->cu_xlo)) && + (dupUse->cu_xsep == use->cu_xsep)) && + ((dupUse->cu_yhi > dupUse->cu_ylo) && + ((dupUse->cu_yhi - dupUse->cu_ylo) == + (use->cu_yhi - use->cu_ylo)) && + (dupUse->cu_ysep == use->cu_ysep))) break; BPEnumTerm(&bpe); diff --git a/database/DBcellbox.c b/database/DBcellbox.c index 82f8d026..82f65908 100644 --- a/database/DBcellbox.c +++ b/database/DBcellbox.c @@ -619,10 +619,9 @@ dbReComputeBboxFunc(cellDef, boundProc, recurseProc) /* * Include area of subcells separately */ - if ((foundAny = DBBoundCellPlane(cellDef, &extended, &rect)) > 0) - area = rect; - else + if (!((foundAny = DBBoundCellPlane(cellDef, &extended, &rect)) > 0)) extended = GeoNullRect; + area = rect; for (pNum = PL_PAINTBASE; pNum < DBNumPlanes; pNum++) if (pNum != PL_DRC_CHECK) diff --git a/database/DBcellsrch.c b/database/DBcellsrch.c index 83534bbe..84da70af 100644 --- a/database/DBcellsrch.c +++ b/database/DBcellsrch.c @@ -85,11 +85,13 @@ struct seeTypesArg int DBSrCellPlaneArea(BPlane *plane, const Rect *rect, int (*func)(), ClientData arg) { + BPEnum sbpe; BPEnum *bpe; CellUse *use; int rval = 0; - bpe = (BPEnum *)mallocMagic(sizeof(BPEnum)); + /* bpe = (BPEnum *)mallocMagic(sizeof(BPEnum)); */ + bpe = &sbpe; BPEnumInit(bpe, plane, rect, BPE_OVERLAP, "DBSrCellPlaneArea"); while ((use = BPEnumNext(bpe))) @@ -102,7 +104,7 @@ DBSrCellPlaneArea(BPlane *plane, const Rect *rect, int (*func)(), ClientData arg } BPEnumTerm(bpe); - freeMagic(bpe); + /* freeMagic(bpe); */ return rval; } diff --git a/database/databaseInt.h b/database/databaseInt.h index 556e573d..d8f5c736 100644 --- a/database/databaseInt.h +++ b/database/databaseInt.h @@ -194,6 +194,8 @@ typedef struct extern int dbNumSavedRules; extern Rule dbSavedRules[]; +extern HashTable dbCellDefTable; /* Exported for diagnostics */ + /* -------------------- Internal procedure headers -------------------- */ extern void DBUndoPutLabel(); diff --git a/dbwind/DBWcommands.c b/dbwind/DBWcommands.c index 8a506457..8995d854 100644 --- a/dbwind/DBWcommands.c +++ b/dbwind/DBWcommands.c @@ -75,6 +75,7 @@ extern void CmdExtResis(); extern void CmdPsearch(); extern void CmdPlowTest(); extern void CmdShowtech(); +extern void CmdShowmem(); extern void CmdTilestats(); extern void CmdTsearch(); extern void CmdWatch(); @@ -208,6 +209,9 @@ DBWInitCommands() WindAddCommand(DBWclientID, "*psearch plane count invoke point search over box area", CmdPsearch, FALSE); + WindAddCommand(DBWclientID, + "*showmem [file] print internal memory usage", + CmdShowmem, FALSE); WindAddCommand(DBWclientID, "*showtech [file] print internal technology tables", CmdShowtech, FALSE); diff --git a/extract/ExtTech.c b/extract/ExtTech.c index 8e333a48..493cbcc3 100644 --- a/extract/ExtTech.c +++ b/extract/ExtTech.c @@ -1119,6 +1119,7 @@ ExtTechInit() if (ExtCurStyle != NULL) { extTechStyleInit(ExtCurStyle); + freeMagic(ExtCurStyle); ExtCurStyle = NULL; } diff --git a/tiles/tile.c b/tiles/tile.c index 85938c44..778d1f9f 100644 --- a/tiles/tile.c +++ b/tiles/tile.c @@ -20,6 +20,10 @@ static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/tiles/tile.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ +/* Disable memory mapped tile allocation here and in tiles/tile.h + * #undef HAVE_SYS_MMAN_H + */ + #include #include #include @@ -816,6 +820,7 @@ TiJoinX1(Tile **delay1, Tile *tile1, Tile *tile2, Plane *plane) { TiFreeIf(*delay1); TiJoinX(tile1, tile2, plane); + *delay1 = tile2; } void @@ -823,6 +828,7 @@ TiJoinY1(Tile **delay1, Tile *tile1, Tile *tile2, Plane *plane) { TiFreeIf(*delay1); TiJoinY(tile1, tile2, plane); + *delay1 = tile2; } #endif diff --git a/tiles/tile.h b/tiles/tile.h index 4e6638d9..3acc23f0 100644 --- a/tiles/tile.h +++ b/tiles/tile.h @@ -23,6 +23,14 @@ #ifndef _MAGIC__TILES__TILE_H #define _MAGIC__TILES__TILE_H +/* Disable memory mapped tile allocation here and in tiles/tile.h + * #undef HAVE_SYS_MMAN_H + */ + + +#ifndef HAVE_SYS_MMAN_H +#include "utils/malloc.h" +#endif #ifndef _MAGIC__UTILS__MAGIC_H #include "utils/magic.h" #endif @@ -299,6 +307,7 @@ TiJoinX1(Tile **delay1, Tile *tile1, Tile *tile2, Plane *plane) { TiFreeIf(*delay1); TiJoinX(tile1, tile2, plane); + *delay1 = tile2; } inline void @@ -306,6 +315,7 @@ TiJoinY1(Tile **delay1, Tile *tile1, Tile *tile2, Plane *plane) { TiFreeIf(*delay1); TiJoinY(tile1, tile2, plane); + *delay1 = tile2; } #else /* To support older compilers (that don't auto emit based on -O level) */