mirror of
https://github.com/RTimothyEdwards/magic.git
synced 2026-09-04 00:31:02 +02:00
Added a ARG_UNUSED macro in utils/magic.h, which produces a simple cast to void to silence the warnings. The reasons this is used as opposed to an attribute is that most compilers should support this. Besides this, the macro can be easily searched for in the future to potentially remove (where possible) the unused parameters.
286 lines
7.8 KiB
C
286 lines
7.8 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. *
|
|
* *********************************************************************
|
|
*/
|
|
|
|
#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;
|
|
}
|