290 lines
7.9 KiB
C
290 lines
7.9 KiB
C
/*
|
||
* groutePath.c -
|
||
*
|
||
* Global signal router code for low-level manipulation of GlPoints.
|
||
*
|
||
* *********************************************************************
|
||
* * Copyright (C) 1985, 1990 Regents of the University of California. *
|
||
* * Permission to use, copy, modify, and distribute this *
|
||
* * software and its documentation for any purpose and without *
|
||
* * fee is hereby granted, provided that the above copyright *
|
||
* * notice appear in all copies. The University of California *
|
||
* * makes no representations about the suitability of this *
|
||
* * software for any purpose. It is provided "as is" without *
|
||
* * express or implied warranty. Export of this software outside *
|
||
* * of the United States of America may require an export license. *
|
||
* *********************************************************************
|
||
*/
|
||
|
||
#ifndef lint
|
||
static char sccsid[] = "@(#)groutePoint.c 4.9 MAGIC (Berkeley) 12/6/85";
|
||
#endif /* not lint */
|
||
|
||
#include <stdio.h>
|
||
#include "utils/magic.h"
|
||
#include "utils/geometry.h"
|
||
#include "utils/hash.h"
|
||
#include "utils/heap.h"
|
||
#include "tiles/tile.h"
|
||
#include "debug/debug.h"
|
||
#include "database/database.h"
|
||
#include "gcr/gcr.h"
|
||
#include "windows/windows.h"
|
||
#include "utils/main.h"
|
||
#include "dbwind/dbwind.h"
|
||
#include "utils/signals.h"
|
||
#include "router/router.h"
|
||
#include "grouter/grouter.h"
|
||
#include "textio/textio.h"
|
||
#include "utils/malloc.h"
|
||
|
||
/* First, last, and current GlPages on list for allocating GlPoints */
|
||
GlPage *glPathFirstPage = NULL;
|
||
GlPage *glPathLastPage = NULL;
|
||
GlPage *glPathCurPage = NULL;
|
||
|
||
/*
|
||
* ----------------------------------------------------------------------------
|
||
*
|
||
* glListAdd --
|
||
*
|
||
* Add a point to the head of the given linked list of points,
|
||
* with a given cost. To free the list when done, pass it to
|
||
* glPathFreePerm() below. Lists are linked using the gl_path
|
||
* field of a GlPoint, just like paths, but the order of the
|
||
* points is unimportant and the cost reflects the cost of
|
||
* using a GlPoint as a starting point, rather than the cost
|
||
* of reaching it via a particular path.
|
||
*
|
||
* Results:
|
||
* None.
|
||
*
|
||
* Side effects:
|
||
* Memory is allocated for the new point using mallocMagic(),
|
||
* rather than using the mechanism of glPathNew(). Hence the
|
||
* list built with glListAdd() persists through calls to
|
||
* glPathFreeTemp() and must be freed explicitly using glPathFreePerm().
|
||
*
|
||
* ----------------------------------------------------------------------------
|
||
*/
|
||
|
||
void
|
||
glListAdd(list, pin, cost)
|
||
GlPoint **list; /* Linked via gl_path pointers */
|
||
GCRPin *pin;
|
||
int cost;
|
||
{
|
||
GlPoint *newPt;
|
||
|
||
newPt = (GlPoint *) mallocMagic((unsigned) (sizeof (GlPoint)));
|
||
newPt->gl_tile = (Tile *) NULL;
|
||
newPt->gl_pin = pin;
|
||
newPt->gl_cost = cost;
|
||
newPt->gl_path = *list;
|
||
*list = newPt;
|
||
}
|
||
|
||
/*
|
||
* ----------------------------------------------------------------------------
|
||
*
|
||
* glListToHeap --
|
||
*
|
||
* Copy crossing points from the list of starting points for a net
|
||
* into the global heap. The heap cost of the copied point includes
|
||
* the Manhattan distance from the point to the destination. We
|
||
* recompute the hint tiles for points when we copy them, since
|
||
* the tile structure of glChanPlane may have changed since list
|
||
* was built.
|
||
*
|
||
* Results:
|
||
* None.
|
||
*
|
||
* Side effects:
|
||
* Memory is allocated. Structs are added to the global heap.
|
||
*
|
||
* ----------------------------------------------------------------------------
|
||
*/
|
||
|
||
void
|
||
glListToHeap(list, destPt)
|
||
GlPoint *list; /* List of points linked via gl_path pointers */
|
||
Point *destPt;
|
||
{
|
||
GlPoint *temp, *new;
|
||
GCRPin *pin;
|
||
Tile *tp;
|
||
int dist;
|
||
|
||
for (temp = list; temp; temp = temp->gl_path)
|
||
{
|
||
/*
|
||
* Only copy to heap if this pin doesn't lie within a blocked
|
||
* region (a pin can lie in a blocked region when the density
|
||
* for a portion of a channel is reached, and the pin happens
|
||
* to lie along that channel portion).
|
||
*/
|
||
pin = temp->gl_pin;
|
||
if (tp = glChanPinToTile((Tile *) NULL, pin))
|
||
{
|
||
new = glPathNew(pin, temp->gl_cost, (GlPoint *) NULL);
|
||
new->gl_tile = tp;
|
||
dist = ABSDIFF(pin->gcr_point.p_x, destPt->p_x) +
|
||
ABSDIFF(pin->gcr_point.p_y, destPt->p_y) +
|
||
temp->gl_cost;
|
||
HeapAddInt(&glMazeHeap, dist, (char *) new);
|
||
}
|
||
}
|
||
}
|
||
|
||
/*
|
||
* ----------------------------------------------------------------------------
|
||
*
|
||
* glPathCopyPerm --
|
||
* glPathFreePerm --
|
||
*
|
||
* The first procedure copies a path into a mallocMagic()'d list.
|
||
* All points from 'list' are copied; the copy of the point whose
|
||
* gl_path field pointed to root has its gl_path field pointing
|
||
* to NULL.
|
||
*
|
||
* The second procedure frees a list allocated in this fashion.
|
||
*
|
||
* Results:
|
||
* glPathCopyPerm returns a pointer to the new GlPoint path;
|
||
* glPathFreePerm returns nothing.
|
||
*
|
||
* Side effects:
|
||
* Memory is allocated for the new point for real,
|
||
* using mallocMagic(), rather than using the mechanism
|
||
* of glPathNew(). Hence the list built with glPathCopyPerm
|
||
* persists through calls to glPathFreeTemp() and must be
|
||
* freed explicitly using glPathFreePerm().
|
||
*
|
||
* ----------------------------------------------------------------------------
|
||
*/
|
||
|
||
GlPoint *
|
||
glPathCopyPerm(list)
|
||
GlPoint *list;
|
||
{
|
||
GlPoint *new, *prev, *first;
|
||
|
||
for (first = prev = NULL; list; prev = new, list = list->gl_path)
|
||
{
|
||
new = (GlPoint *) mallocMagic((unsigned) (sizeof (GlPoint)));
|
||
*new = *list;
|
||
if (first == NULL) first = new;
|
||
if (prev) prev->gl_path = new;
|
||
}
|
||
|
||
if (prev) prev->gl_path = (GlPoint *) NULL;
|
||
|
||
return first;
|
||
}
|
||
|
||
int
|
||
glPathFreePerm(list)
|
||
GlPoint *list;
|
||
{
|
||
GlPoint *p;
|
||
|
||
for (p = list; p; p = p->gl_path)
|
||
freeMagic((char *) p);
|
||
return 0;
|
||
}
|
||
|
||
/*
|
||
* ----------------------------------------------------------------------------
|
||
*
|
||
* glPathNew --
|
||
*
|
||
* Create a new GlPoint and link it to the GlPoint from which
|
||
* it was visited.
|
||
*
|
||
* Results:
|
||
* Pointer to the newly allocated struct.
|
||
*
|
||
* Side effects:
|
||
* Memory is allocated.
|
||
*
|
||
* ----------------------------------------------------------------------------
|
||
*/
|
||
|
||
GlPoint *
|
||
glPathNew(pin, cost, prev)
|
||
GCRPin *pin; /* Pin at the crossing point (mustn't be NULL) */
|
||
int cost; /* The cost to get here from source */
|
||
GlPoint *prev; /* Point from which the new one was visited */
|
||
{
|
||
GlPoint *result;
|
||
|
||
ASSERT(pin != NULL, "glPathNew");
|
||
if (glPathCurPage == NULL || glPathCurPage->glp_free >= POINTSPERSEG)
|
||
{
|
||
/* Skip to next page if this one is full */
|
||
if (glPathCurPage && glPathCurPage->glp_free >= POINTSPERSEG)
|
||
glPathCurPage = glPathCurPage->glp_next;
|
||
|
||
/* If out of pages, allocate a new one */
|
||
if (glPathCurPage == NULL)
|
||
{
|
||
glPathCurPage = (GlPage *) mallocMagic((unsigned) (sizeof (GlPage)));
|
||
glPathCurPage->glp_next = (GlPage *) NULL;
|
||
glPathCurPage->glp_free = 0;
|
||
if (glPathLastPage == NULL)
|
||
{
|
||
glPathFirstPage = glPathCurPage;
|
||
glPathLastPage = glPathCurPage;
|
||
}
|
||
else
|
||
{
|
||
glPathLastPage->glp_next = glPathCurPage;
|
||
glPathLastPage = glPathCurPage;
|
||
}
|
||
}
|
||
}
|
||
|
||
result = &glPathCurPage->glp_array[glPathCurPage->glp_free++];
|
||
result->gl_path = prev;
|
||
result->gl_cost = cost;
|
||
result->gl_pin = pin;
|
||
result->gl_tile = (Tile *) NULL;
|
||
|
||
return result;
|
||
}
|
||
|
||
/*
|
||
* ----------------------------------------------------------------------------
|
||
*
|
||
* glPathFreeTemp --
|
||
*
|
||
* Reset the temporary arena used for allocating GlPoints.
|
||
*
|
||
* Results:
|
||
* None.
|
||
*
|
||
* Side effects:
|
||
* Memory is freed.
|
||
*
|
||
* ----------------------------------------------------------------------------
|
||
*/
|
||
|
||
void
|
||
glPathFreeTemp()
|
||
{
|
||
GlPage *gpage;
|
||
|
||
for (gpage = glPathFirstPage; gpage; gpage = gpage->glp_next)
|
||
{
|
||
/* Mark page of RoutePaths as being free */
|
||
gpage->glp_free = 0;
|
||
|
||
/* Can stop after processing the last page used in this cycle */
|
||
if (gpage == glPathCurPage)
|
||
break;
|
||
}
|
||
|
||
/* Start allocating again from the first page on the list */
|
||
glPathCurPage = glPathFirstPage;
|
||
}
|