JunoStorageImpl.mesa
Coded June 81 by Greg Nelson.
Last edited by GNelson (?) January 19, 1984 1:52 pm
Last edited by Stolfi June 15, 1984 7:15:48 am PDT

Defines record types, allocation and deallocation functions.

TO FIX: Is it necessary for it to be a monitor?.

TO FIX: Frames in constraints --- pass them to NewXXX procedures?.

DIRECTORY

JunoStorage;

JunoStorageImpl: MONITOR

EXPORTS JunoStorage =

BEGIN OPEN JunoStorage;

- - - - POINTS

pointAvail: Point ← NIL;

nPoints, mPoints: INT ← 0;
nPoints counts calls to NewPoint, mPoints counts actual allocations

NewPoint
: PUBLIC ENTRY PROC [coords: Coords, visible: BOOLFALSE] 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;

- - - - ITEMS (CONSTRAINTS AND ACTIONS)

itemAvail: Item ← NIL;

nItems, mItems: INT ← 0;
nItems counts total allocations, mItems counts max in use at same time

NewItem: PUBLIC ENTRY PROC
[kind: ItemKind, args: ItemArgs, frame: Frame← nullFrame]
RETURNS
[item: Item] =

BEGIN
IF itemAvail = NIL THEN

BEGIN -- Create a bunch of new records
t: Item;
THROUGH [1..50] DO
t ← itemAvail;
itemAvail ← NEW[ItemRec ← [link: t, kind: draw, frame: nullFrame, args: NIL]];
itemAvail.link ← t;
mItems ← mItems+1
ENDLOOP
END;

item ← itemAvail;
itemAvail ← itemAvail.link;
item.link ← NIL;
item.kind ← kind; item.frame ← frame; item.args ← args;
nItems ← nItems+1
END;

DeleteItem: PUBLIC PROC [item, ant: Item, list: ItemList] RETURNS [newList: ItemList] =

BEGIN
IF item = list.first THEN
{IF ant # NIL THEN ERROR;
newList.first ← item.link}
ELSE
{IF ant = NIL THEN
{ant ← list.first;
WHILE ant.link # item DO ant ← ant.link ENDLOOP}
ELSE
{IF ant.link # item THEN ERROR};
ant.link ← item.link;
newList.first ← list.first};
newList.last ← IF item = list.last THEN ant ELSE list.last;
item.link ← NIL
END;

InsertItem: PUBLIC PROC [item, ant: Item, list: ItemList] RETURNS [newList: ItemList] =

BEGIN
IF ant = NIL THEN
{item.link ← list.first;
newList.first ← item}
ELSE
{item.link ← ant.link;
ant.link ← item;
newList.first ← list.first};
newList.last ← IF item.link = NIL THEN item ELSE list.last
END;

GcItems: PUBLIC PROC [start: Item, lim: Item ← NIL] =

BEGIN
t: Item;
GcIt: ENTRY PROC [z: Item] = {z.link ← itemAvail; itemAvail ← z};
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 ANYNIL] =

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];
GcItems[NewItem[kind: hor, args: NIL, frame: nullFrame], NIL];
GcList[Cons[NIL, NIL], NIL]
END;

InitStorage[]

END.