magic/grouter/groutePath.c

290 lines
7.9 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* 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;
}