Corrected an error that (in a rare circumstance) can cause netgen
to go into an infinite loop and fill memory until it crashes, due to a complete pin mismatch between devices causing one device to have its pins removed and replaced with proxy pins.
This commit is contained in:
parent
402e1f0f25
commit
c7848c9c02
|
|
@ -1161,9 +1161,10 @@ int UniquePins(char *name, int filenum)
|
||||||
struct nlist *cleanuppins(struct hashlist *p, void *clientdata)
|
struct nlist *cleanuppins(struct hashlist *p, void *clientdata)
|
||||||
{
|
{
|
||||||
struct nlist *ptr;
|
struct nlist *ptr;
|
||||||
struct objlist *ob, *obt, *lob, *nob, *firstpin;
|
struct objlist *ob, *obt, *lob, *nob, *firstpin, *pob;
|
||||||
struct nlist *tc = (struct nlist *)clientdata;
|
struct nlist *tc = (struct nlist *)clientdata;
|
||||||
int pinnum;
|
int pinnum;
|
||||||
|
char *saveinst = NULL;
|
||||||
|
|
||||||
ptr = (struct nlist *)(p->ptr);
|
ptr = (struct nlist *)(p->ptr);
|
||||||
if (tc->file != ptr->file) return NULL;
|
if (tc->file != ptr->file) return NULL;
|
||||||
|
|
@ -1211,14 +1212,45 @@ struct nlist *cleanuppins(struct hashlist *p, void *clientdata)
|
||||||
}
|
}
|
||||||
|
|
||||||
FREE(ob->name);
|
FREE(ob->name);
|
||||||
if (ob->instance.name != NULL) FREE(ob->instance.name);
|
if (ob->instance.name != NULL) {
|
||||||
|
/* Keep a copy of the instance name (see below) */
|
||||||
|
if (saveinst != NULL) FREE(saveinst);
|
||||||
|
saveinst = ob->instance.name;
|
||||||
|
}
|
||||||
if (ob->model.class != NULL) FREE(ob->model.class);
|
if (ob->model.class != NULL) FREE(ob->model.class);
|
||||||
FREE(ob);
|
FREE(ob);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
if ((ob->type == PROPERTY) && (pinnum == 1))
|
||||||
|
{
|
||||||
|
/* If this happens, then all the pins got removed,
|
||||||
|
* and there is probably something very much wrong
|
||||||
|
* with the setup. However, to keep netgen from
|
||||||
|
* blowing up, add back a "proxy(no pins)" record
|
||||||
|
* in front; otherwise we'd have an orphaned
|
||||||
|
* property record.
|
||||||
|
*/
|
||||||
|
pob = GetObject();
|
||||||
|
pob->name = (char *)MALLOC(15);
|
||||||
|
sprintf(pob->name, "proxy(no pins)");
|
||||||
|
pob->model.class = strsave(ob->model.class);
|
||||||
|
if (saveinst != NULL)
|
||||||
|
pob->instance.name = strsave(saveinst);
|
||||||
|
else
|
||||||
|
/* This should never happen */
|
||||||
|
pob->instance.name = strsave("error");
|
||||||
|
pob->type = pinnum++;
|
||||||
|
pob->node = -1;
|
||||||
|
pob->next = ob;
|
||||||
|
lob->next = pob;
|
||||||
|
lob = ob;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
lob = ob;
|
lob = ob;
|
||||||
ob->type = pinnum++; // Renumber pins in order
|
ob->type = pinnum++; // Renumber pins in order
|
||||||
}
|
}
|
||||||
|
}
|
||||||
ob = nob;
|
ob = nob;
|
||||||
obt = obt->next;
|
obt = obt->next;
|
||||||
}
|
}
|
||||||
|
|
@ -1228,6 +1260,8 @@ struct nlist *cleanuppins(struct hashlist *p, void *clientdata)
|
||||||
HashPtrInstall(firstpin->instance.name, firstpin, &(ptr->instdict));
|
HashPtrInstall(firstpin->instance.name, firstpin, &(ptr->instdict));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (saveinst != NULL) FREE(saveinst);
|
||||||
return NULL; /* Keep the search going */
|
return NULL; /* Keep the search going */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6715,18 +6715,31 @@ struct nlist *addproxies(struct hashlist *p, void *clientdata)
|
||||||
firstpin = ob;
|
firstpin = ob;
|
||||||
while (tob && (tob->type == PORT || tob->type == UNKNOWN)) {
|
while (tob && (tob->type == PORT || tob->type == UNKNOWN)) {
|
||||||
if (tob->type == UNKNOWN) {
|
if (tob->type == UNKNOWN) {
|
||||||
/* ??? Do not do anything with (no pins) entries */
|
/* Do not do anything with (no pins) entries (in the reference cell) */
|
||||||
if (strcmp(tob->name, "proxy(no pins)")) {
|
if (strcmp(tob->name, "proxy(no pins)")) {
|
||||||
|
/* But if the target cell instance has proxy(no pins), then reuse
|
||||||
|
* the record and modify it.
|
||||||
|
*/
|
||||||
|
if (!strcmp(ob->name, "proxy(no pins)")) {
|
||||||
|
obn = ob;
|
||||||
|
FREE(ob->name);
|
||||||
|
obn->name = (char *)MALLOC(strlen(ob->instance.name)
|
||||||
|
+ strlen(tob->name) + 2);
|
||||||
|
sprintf(obn->name, "%s/%s", ob->instance.name, tob->name);
|
||||||
|
ob = obn->next;
|
||||||
|
}
|
||||||
|
else {
|
||||||
obn = (struct objlist *)CALLOC(1, sizeof(struct objlist));
|
obn = (struct objlist *)CALLOC(1, sizeof(struct objlist));
|
||||||
obn->name = (char *)MALLOC(strlen(firstpin->instance.name)
|
obn->name = (char *)MALLOC(strlen(firstpin->instance.name)
|
||||||
+ strlen(tob->name) + 2);
|
+ strlen(tob->name) + 2);
|
||||||
sprintf(obn->name, "%s/%s", firstpin->instance.name, tob->name);
|
sprintf(obn->name, "%s/%s", firstpin->instance.name, tob->name);
|
||||||
obn->instance.name = strsave(firstpin->instance.name);
|
obn->instance.name = strsave(firstpin->instance.name);
|
||||||
obn->model.class = strsave(tc->name);
|
obn->model.class = strsave(tc->name);
|
||||||
obn->type = i++;
|
|
||||||
obn->node = numnodes++;
|
|
||||||
obn->next = ob; // Splice into object list
|
obn->next = ob; // Splice into object list
|
||||||
lob->next = obn;
|
lob->next = obn;
|
||||||
|
}
|
||||||
|
obn->type = i++;
|
||||||
|
obn->node = numnodes++;
|
||||||
lob = obn;
|
lob = obn;
|
||||||
|
|
||||||
// Hash the new pin record for "LookupObject()"
|
// Hash the new pin record for "LookupObject()"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue