-- File: DisjointAlloc.mesa
-- Allocation routines for Disjoint
-- Written by Martin Newell/Dan Fitzpatrick June 1981
-- Last edited (Pilot): 16-Jul-81 11:00
:18

DIREC
TORY

DisjointTypes: FROM "DisjointTypes" USING [DisCell, DisCellRecord, Instance,
InstanceRecord, Symbol, SymbolRecord, Rectangle, RectangleRecord, PIP,
PIPRecord, Geometry, GeometryRecord, PropID, PropList, PropListRecord],
DisjointAllocDefs: FROM "DisjointAllocDefs",
DisjointPropDefs: FROM "DisjointPropDefs" USING [GetProp],
IODefs: FROM "IODefs" USING [WriteString, WriteLine,WriteDecimal],
String: FROM "String" USING [AppendString, EqualString],
SystemDefs: FROM "SystemDefs" USING [AllocateHeapString],
XFSPDefs: FROM "XFSPDefs" USING [XAllocateHeapNode];

Disj
ointAlloc: PROGRAM
IMPORTS DisjointPropDefs, IODefs, String, SystemDefs, XFSPDefs
EXPORTS DisjointAllocDefs =
BEGIN
OPEN DisjointPropDefs, DisjointTypes, IODefs, String, SystemDefs, XFSPDefs;

-- Allocation f
or symbols

MakeSymbol
: PUBLIC PROCEDURE [name: STRING, l,b,r,t: REAL] RETURNS[Symbol] =
BEGIN
s: Symbol ← LookupSymbol[name];
IF s=NIL THEN {
s ← AllocateSymbol[];
s.name ← AllocateHeapString[name.length];
AppendString[s.name, name];
};
s.windows ← MakeRectangle[l,b,r,t];
RETURN[s];
END;

AllocateSymb
ol: PUBLIC PROCEDURE[] RETURNS[symb: Symbol] =
BEGIN
symb ← GetSymbol[];
symb↑ ← [
next: SymbolList,
name: NIL,
geom: NIL,
insts: NIL,
windows: NIL
];
SymbolList ← symb;
END;

GetSymbol: P
UBLIC PROCEDURE[] RETURNS[symb: Symbol] =
-- More primiti
ve than AllocateSymbol, doesn’t put returned symbol on SymbolList
BEGIN
symbAllocCount ← symbAllocCount+1;
IF FreeSymbolList = NIL THEN symb ← XAllocateHeapNode[SIZE[SymbolRecord]]
ELSE {
symb ← FreeSymbolList;
FreeSymbolList ← FreeSymbolList.next;
};
symb.insts ← NIL;
END;

FreeSymbol:
PUBLIC PROCEDURE[symb: Symbol] =
BEGIN
sptr: LONG POINTER TO Symbol;
FOR sptr ← @SymbolList, @sptr.next UNTIL sptr↑=NIL DO
IF sptr↑ = symb THEN {
sptr↑ ← symb.next;
EXIT;
};
ENDLOOP;
symbAllocCount ← symbAllocCount-1;
symb.next ← FreeSymbolList; FreeSymbolList ← symb;
END;

FreeMarkedSy
mbols: PUBLIC PROCEDURE[id: PropID] =
BEGIN
sptr,next: Symbol;
FOR sptr ← SymbolList, next UNTIL sptr=NIL DO
next ← sptr.next;
IF GetProp[sptr.prop,id] # NIL THEN FreeSymbol[sptr];
ENDLOOP;
END;

LookupSymbol
: PUBLIC PROCEDURE [name: STRING] RETURNS[s: Symbol] =
BEGIN
FOR s ← SymbolList, s.next UNTIL s = NIL DO
IF EqualString[name,s.name] THEN RETURN;
ENDLOOP;
END;

EnumerateSym
bols: PUBLIC PROCEDURE[proc: PROC[s: Symbol]RETURNS[BOOLEAN]]
RETURNS[BOOLEAN] =
--BOOLEAN retu
rns are both abort flags
BEGIN
FOR s:Symbol ← SymbolList, s.next UNTIL s=NIL DO
IF proc[s] THEN RETURN[TRUE];
ENDLOOP;
RETURN[FALSE];
END;

InsertSymbol
List: PUBLIC PROCEDURE [list: Symbol] =
BEGIN
next: Symbol;

FOR s:Symbol ← list, next UNTIL s = NIL DO
next ← s.next;
s.next ← SymbolList;
SymbolList ← s;
ENDLOOP;
END;

-- Allocation f
or instances

MakeInstan
ce: PUBLIC PROCEDURE[parent: Symbol, name: STRING, x,y: REAL]
RETURNS[Instance] =
BEGIN
in: Instance;
s: Symbol ← LookupSymbol[name];
IF s=NIL THEN { -- a forward reference
s ← AllocateSymbol[];
s.name ← AllocateHeapString[name.length];
AppendString[s.name, name];
};
in ← AllocateInstance[];
in ↑ ← [
next: NIL,
symbol: s,
xOffset: x,
yOffset: y
];
in.next ← parent.insts;
parent.insts ← in;
RETURN[in];
END;

AllocateInst
ance: PUBLIC PROCEDURE[] RETURNS[inst: Instance] =
BEGIN
instAllocCount ← instAllocCount+1;
IF FreeInstanceList = NIL THEN inst ← XAllocateHeapNode[SIZE[InstanceRecord]]
ELSE {
inst ← FreeInstanceList;
FreeInstanceList ← FreeInstanceList.next;
};
END;

FreeInstance
: PUBLIC PROCEDURE[inst: Instance] =
BEGIN
instAllocCount ← instAllocCount-1;
inst.next ← FreeInstanceList; FreeInstanceList ← inst;
END;

-- Allocation f
or Geometry

MakeGeomet
ry: PUBLIC PROCEDURE[parent: Symbol, layer: CARDINAL, l,b,r,t: REAL]
RETURNS[Geometry] =
BEGIN
g: Geometry ← AllocateGeometry[];
g ↑ ← [
next: NIL,
layer: layer,
l: l,
b: b,
r: r,
t: t
];
g.next ← parent.geom;
parent.geom ← g;
RETURN[g];
END;

AllocateGeom
etry: PUBLIC PROCEDURE[] RETURNS[g: Geometry] =
BEGIN
gAllocCount ← gAllocCount+1;
IF FreeGeometryList = NIL THEN g ← XAllocateHeapNode[SIZE[GeometryRecord]]
ELSE {
g ← FreeGeometryList;
FreeGeometryList ← FreeGeometryList.next;
};
END;

FreeGeometry
: PUBLIC PROCEDURE[g: Geometry] =
BEGIN
gAllocCount ← gAllocCount-1;
g.next ← FreeGeometryList; FreeGeometryList ← g;
END;

-- Allocation f
or PIP’s

AllocatePI
P: PUBLIC PROCEDURE[] RETURNS[pip: PIP] =
BEGIN
pipAllocCount ← pipAllocCount+1;
IF FreePIPList = NIL THEN pip ← XAllocateHeapNode[SIZE[PIPRecord]]
ELSE {
pip ← FreePIPList;
FreePIPList ← FreePIPList.next;
};
END;

FreePIP: PUB
LIC PROCEDURE[pip: PIP] =
BEGIN
pip.next ← FreePIPList; FreePIPList ← pip;
pipAllocCount ← pipAllocCount-1;
END;

-- Allocation f
or DisCells

AllocateDi
sCell: PUBLIC PROCEDURE[] RETURNS[dc: DisCell] =
BEGIN
discellAllocCount ← discellAllocCount+1;
IF FreeDisCellList = NIL THEN dc ← XAllocateHeapNode[SIZE[DisCellRecord]]
ELSE {
dc ← FreeDisCellList;
FreeDisCellList ← FreeDisCellList.next;
};
END;

FreeDisCell:
PUBLIC PROCEDURE[dc: DisCell] =
BEGIN
dc.next ← FreeDisCellList; FreeDisCellList ← dc;
discellAllocCount ← discellAllocCount-1;
END;

-- Allocation f
or Windows

MakeRectan
gle: PUBLIC PROCEDURE[l,b,r,t: REAL]
RETURNS[rec: DisjointTypes.Rectangle] =
BEGIN
rec ← AllocateRectangle[];
rec↑ ← [
next: NIL,
l: l,
b: b,
r: r,
t: t
];
END;

AllocateRect
angle: PUBLIC PROCEDURE[] RETURNS[r: DisjointTypes.Rectangle] =
BEGIN
recAllocCount ← recAllocCount+1;
IF FreeRectangleList = NIL THEN r ← XAllocateHeapNode[SIZE[RectangleRecord]]
ELSE {
r ← FreeRectangleList;
FreeRectangleList ← FreeRectangleList.next;
};
END;

FreeRectangl
e: PUBLIC PROCEDURE[r: DisjointTypes.Rectangle] =
BEGIN
r.next ← FreeRectangleList; FreeRectangleList ← r;
recAllocCount ← recAllocCount-1;
END;

-- Allocation f
or Property Cells

AllocatePr
op: PUBLIC PROCEDURE[] RETURNS[p: PropList] =
BEGIN
propAllocCount ← propAllocCount+1;
IF FreePropList = NIL THEN p ← XAllocateHeapNode[SIZE[PropListRecord]]
ELSE {
p ← FreePropList;
FreePropList ← FreePropList.next;
};
END;

FreeProp: PU
BLIC PROCEDURE[p: PropList] =
BEGIN
p.next ← FreePropList; FreePropList ← p;
propAllocCount ← propAllocCount-1;
END;

PrintAlloc:
PUBLIC PROCEDURE =
BEGIN
free: CARDINAL;
CheckAlloc[];
WriteLine["Alloc summary"];
free ← 0;
FOR s:Symbol ← FreeSymbolList, s.next UNTIL s=NIL DO free←free+1; ENDLOOP;
WriteAlloc["Symbols", symbAllocCount, free, usedSymb];
free ← 0;
FOR s:Instance ← FreeInstanceList, s.next UNTIL s=NIL
DO free←free+1; ENDLOOP;
WriteAlloc["Instances", instAllocCount, free, usedInst];
free ← 0;
FOR s:PIP ← FreePIPList, s.next UNTIL s=NIL
DO free←free+1; ENDLOOP;
WriteAlloc["PIPs", pipAllocCount, free, 0];
free ← 0;
FOR s:DisCell ← FreeDisCellList, s.next UNTIL s=NIL
DO free←free+1; ENDLOOP;
WriteAlloc["DisCells", discellAllocCount, free, 0];
free ← 0;
FOR s:Rectangle ← FreeRectangleList, s.next UNTIL s=NIL
DO free←free+1; ENDLOOP;
WriteAlloc["Windows", recAllocCount, free, usedWind];
free ← 0;
FOR s:Geometry ← FreeGeometryList, s.next UNTIL s=NIL
DO free←free+1; ENDLOOP;
WriteAlloc["Geometrys", gAllocCount, free, usedGeom];
END;

WriteAlloc:
PROCEDURE[s: STRING, nAlloc,nFree,nUsed: CARDINAL] =
BEGIN
WriteString[s];WriteString[": "];WriteDecimal[nAlloc];
WriteString[" allocated, "]; WriteDecimal[nUsed];
WriteString[" used ("]; WriteDecimal[nFree]; WriteLine[" free)"];
END;

CheckAlloc:
PUBLIC PROCEDURE =
BEGIN

Count: PROC[s: Symbol] RETURNS [BOOLEAN] =
BEGIN
usedSymb ← usedSymb + 1;
FOR i: Instance ← s.insts,i.next UNTIL i = NIL DO
usedInst ← usedInst + 1;
ENDLOOP;
FOR i: Rectangle ← s.windows,i.next UNTIL i = NIL DO
usedWind ← usedWind + 1;
ENDLOOP;
FOR i: Geometry ← s.geom,i.next UNTIL i = NIL DO
usedGeom ← usedGeom + 1;
ENDLOOP;
RETURN[FALSE];
END;

usedSymb ← 0;
usedInst ← 0;
usedWind ← 0;
usedGeom ← 0;
[] ← EnumerateSymbols[Count];
END;

usedSymb:CARDINAL;
usedInst:CARDINAL;
usedWind:CARDINAL;
usedGeom:CARDINAL;

SymbolList: Symbol ← NIL;

symbAllocCount: CARDINAL ← 0;
instAllocCount: CARDINAL ← 0;
gAllocCount: CARDINAL ← 0;
pipAllocCount: CARDINAL ← 0;
discellAllocCount: CARDINAL ← 0;
recAllocCount: CARDINAL ← 0;
propAllocCount: CARDINAL ← 0;

-- Free lists
FreeSymbolList: Symbol ← NIL;
FreeInstanceList: Instance ← NIL;
FreeGeometryList: Geometry ← NIL;
FreePIPList: PIP ← NIL;
FreeDisCellList: DisCell ← NIL;
FreeRectangleList: Rectangle ← NIL;
FreePropList: PropList ← NIL;


END.