JunoStorageImpl.mesa
Coded June 81 by Greg Nelson.
Last edited by GNelson (?) January 19, 1984 1:52 pm
Last edited by Stolfi June 2, 1984 8:14:56 am PDT
Defines record types, allocation and deallocation functions.
- - - - POINTS
pointAvail: Point ← NIL;
nPoints, mPoints:
INT ← 0;
nPoints counts calls to NewPoint, mPoints counts actual allocations
NewPoint:
PUBLIC ENTRY PROC [coords: Coords, visible:
BOOL ←
FALSE]
RETURNS [p: Point]
=
BEGIN
IF pointAvail = NIL THEN
THROUGH [1..50] DO
pointAvail ← NEW [PointRec ← [link: pointAvail]];
mPoints ← mPoints+1
ENDLOOP;
p ← pointAvail;
pointAvail ← pointAvail.link;
p.link ← NIL;
p^ ← [coords: coords, visible: visible, link: NIL];
nPoints ← nPoints+1
END;
DeletePoint:
PUBLIC
PROC [p, ant: Point, list: PointList]
RETURNS [newList: PointList] =
BEGIN
IF p = list.first THEN
{IF ant # NIL THEN ERROR;
newList.first ← p.link}
ELSE
{IF ant = NIL THEN
{ant ← list.first;
WHILE ant.link # p DO ant ← ant.link ENDLOOP}
ELSE
{IF ant.link # p THEN ERROR};
ant.link ← p.link;
newList.first ← list.first};
newList.last ← IF p = list.last THEN ant ELSE list.last;
p.link ← NIL
END;
InsertPoint:
PUBLIC
PROC [p, ant: Point, list: PointList]
RETURNS [newList: PointList] =
BEGIN
IF ant = NIL THEN
{p.link ← list.first;
newList.first ← p}
ELSE
{p.link ← ant.link;
ant.link ← p;
newList.first ← list.first};
newList.last ← IF p.link = NIL THEN p ELSE list.last
END;
GcPoints:
PUBLIC
PROC [start: Point, lim: Point ←
NIL] =
BEGIN
t: Point;
GcIt: ENTRY PROC [p: Point] = {p^ ← [link: pointAvail]; pointAvail ← p};
WHILE start # lim DO
t ← start.link; GcIt[start]; start ← t
ENDLOOP
END;
- - - - CONSTRAINTS
constrAvail: ARRAY ConstrKind OF Constr ← ALL[NIL];
nConstrs, mConstrs:
ARRAY ConstrKind
OF
INT ←
ALL[0];
nConstrs counts total allocations, mConstrs counts max in use at same time
NewConstr:
ENTRY PROC [kind: ConstrKind]
RETURNS [cp: Constr] =
BEGIN
IF constrAvail[kind] =
NIL
THEN
BEGIN -- Create a bunch of new records
t: Constr;
THROUGH [1..50] DO
t ← constrAvail[kind];
constrAvail[kind] ←
SELECT kind FROM
ver => NEW[ver ConstrRec],
ccw => NEW[ccw ConstrRec],
para => NEW[para ConstrRec],
perp => NEW[perp ConstrRec],
cong => NEW[cong ConstrRec],
at => NEW[at ConstrRec],
hor => NEW[hor ConstrRec],
ENDCASE => ERROR;
constrAvail[kind].link ← t;
mConstrs[kind] ← mConstrs[kind]+1
ENDLOOP
END;
cp ← constrAvail[kind];
constrAvail[kind] ← constrAvail[kind].link;
cp.link ← NIL;
nConstrs[kind] ← nConstrs[kind]+1
END;
DeleteConstr:
PUBLIC
PROC [c, ant: Constr, list: ConstrList]
RETURNS [newList: ConstrList] =
BEGIN
IF c = list.first THEN
{IF ant # NIL THEN ERROR;
newList.first ← c.link}
ELSE
{IF ant = NIL THEN
{ant ← list.first;
WHILE ant.link # c DO ant ← ant.link ENDLOOP}
ELSE
{IF ant.link # c THEN ERROR};
ant.link ← c.link;
newList.first ← list.first};
newList.last ← IF c = list.last THEN ant ELSE list.last;
c.link ← NIL
END;
InsertConstr:
PUBLIC
PROC [c, ant: Constr, list: ConstrList]
RETURNS [newList: ConstrList] =
BEGIN
IF ant = NIL THEN
{c.link ← list.first;
newList.first ← c}
ELSE
{c.link ← ant.link;
ant.link ← c;
newList.first ← list.first};
newList.last ← IF c.link = NIL THEN c ELSE list.last
END;
GcConstrs:
PUBLIC
PROC [start: Constr, lim: Constr ←
NIL] =
BEGIN
t: Constr;
GcIt: ENTRY PROC [c: Constr] = {c.link ← constrAvail[c.kind]; constrAvail[c.kind] ← c};
WHILE start # lim DO
t ← start.link;
GcIt[start];
start ← t
ENDLOOP
END;
NewHor:
PUBLIC
PROC [i,j: Point]
RETURNS [cp: HorConstr] =
BEGIN
IF i = NIL OR j = NIL THEN ERROR;
cp ← NARROW [NewConstr[hor]];
cp.i ← i;
cp.j ← j
END;
NewVer:
PUBLIC
PROC [i,j: Point]
RETURNS [cp: VerConstr] =
BEGIN
IF i = NIL OR j = NIL THEN ERROR;
cp ← NARROW [NewConstr[ver]];
cp.i ← i;
cp.j ← j;
END;
NewPara:
PUBLIC
PROC [i,j,k,l: Point]
RETURNS [cp: ParaConstr] =
BEGIN
IF i = NIL OR j = NIL OR k = NIL OR l=NIL THEN ERROR;
cp ← NARROW [NewConstr[para]];
cp.i ← i;
cp.j ← j;
cp.k ← k;
cp.l ← l
END;
NewPerp:
PUBLIC
PROC [i,j,k,l: Point]
RETURNS [cp: PerpConstr] =
BEGIN
IF i = NIL OR j = NIL OR k = NIL OR l=NIL THEN ERROR;
cp ← NARROW [NewConstr[perp]];
cp.i ← i;
cp.j ← j;
cp.k ← k;
cp.l ← l
END;
NewCong:
PUBLIC
PROC [i,j,k,l: Point]
RETURNS [cp: CongConstr] =
BEGIN
IF i = NIL OR j = NIL OR k = NIL OR l=NIL THEN ERROR;
cp ← NARROW [NewConstr[cong]];
cp.i ← i;
cp.j ← j;
cp.k ← k;
cp.l ← l
END;
NewAt:
PUBLIC
PROC [p: Point, coords: Coords]
RETURNS [cp: AtConstr] =
BEGIN
IF p = NIL THEN ERROR;
cp ← NARROW [NewConstr[at]];
cp.p ← p;
cp.coords ← coords;
END;
NewCcw:
PUBLIC
PROC [i,j,k: Point]
RETURNS [cp: CcwConstr] =
BEGIN
IF i = NIL OR j = NIL OR k = NIL THEN ERROR;
cp ← NARROW [NewConstr[ccw]];
cp.i ← i;
cp.j ← j;
cp.k ← k
END;
- - - - ACTIONS
actionAvail: Action ← NIL;
nActions, mActions:
INT ← 0;
nActions counts total allocations, mActions counts max in use at same time
NewAction:
PUBLIC
ENTRY PROC [kind: ActionKind, args: ActionArgs]
RETURNS [ap: Action] =
BEGIN
IF actionAvail =
NIL
THEN
BEGIN
t: Action;
THROUGH [1..50] DO
t ← actionAvail;
actionAvail ← NEW[ActionRec];
actionAvail.link ← t;
mActions ← mActions + 1
ENDLOOP
END;
ap ← actionAvail;
actionAvail ← actionAvail.link;
ap^ ← [link: NIL, kind: kind, args: args];
nActions ← nActions+1
END;
DeleteAction:
PUBLIC
PROC [a, ant: Action, list: ActionList]
RETURNS [newList: ActionList] =
BEGIN
IF a = list.first THEN
{IF ant # NIL THEN ERROR;
newList.first ← a.link}
ELSE
{IF ant = NIL THEN
{ant ← list.first;
WHILE ant.link # a DO ant ← ant.link ENDLOOP}
ELSE
{IF ant.link # a THEN ERROR};
ant.link ← a.link;
newList.first ← list.first};
newList.last ← IF a = list.last THEN ant ELSE list.last;
a.link ← NIL
END;
InsertAction:
PUBLIC
PROC [a, ant: Action, list: ActionList]
RETURNS [newList: ActionList] =
BEGIN
IF ant = NIL THEN
{a.link ← list.first;
newList.first ← a}
ELSE
{a.link ← ant.link;
ant.link ← a;
newList.first ← list.first};
newList.last ← IF a.link = NIL THEN a ELSE list.last
END;
GcActions:
PUBLIC
PROC [start: Action, lim: Action ←
NIL] =
BEGIN
t: Action;
GcIt: ENTRY PROC [a: Action] =
{a^ ← [link: actionAvail, kind: draw, args: NIL]; actionAvail ← a};
WHILE start # lim DO
t ← start.link;
GcList[start.args, NIL];
GcIt[start];
start ← t
ENDLOOP
END;
- - - - LISTS
listAvail: List ← NIL;
nLists, mLists:
INT ← 0;
nLists counts total list cell allocations, mLists counts max in use at same time
Cons:
PUBLIC
ENTRY
PROC [first:
REF
ANY, rest: List]
RETURNS [cons: List] =
BEGIN
IF listAvail =
NIL
THEN
BEGIN
THROUGH [1..100] DO
listAvail ← CONS[NIL, listAvail];
mLists ← mLists+1
ENDLOOP
END;
cons ← listAvail;
listAvail ← listAvail.rest;
cons.first ← first; cons.rest ← rest;
nLists ← nLists+1
END;
GcList:
PUBLIC PROC [start:
LIST
OF
REF
ANY, lim:
LIST
OF
REF
ANY ←
NIL] =
BEGIN
t: LIST OF REF ANY;
GcIt: ENTRY PROC [s: LIST OF REF ANY] = {s.first ← NIL; s.rest ← listAvail; listAvail ← s};
WHILE start # lim DO
t ← start.rest;
GcIt[start];
start ← t
ENDLOOP
END;
- - - - INITIALIZATION
InitStorage:
PROC =
Allocator warming-up exercises
BEGIN
GcPoints[NewPoint[[0, 0]], NIL];
FOR kind: ConstrKind IN ConstrKind DO
GcConstrs[NewConstr[kind], NIL]
ENDLOOP;
GcActions[NewAction[kind: draw, args: NIL], NIL];
GcList[Cons[NIL, NIL], NIL]
END;
InitStorage[]