-- File: DynamicZoneCold.mesa
-- Last edited by Levin: 6-Oct-80 8:33:18
DIRECTORY
AltoDefs USING [PageSize],
DynamicZone USING [PageCount],
DynamicZonePrivate USING [
AllocateNode, AllocProcs, DeallocateNode, GetPages, MDSZoneHandle, MDSZoneObject,
SegTypeIndex],
FSPDefs USING [DestroyZone, MakeNewZone, PruneZone, ZonePointer],
SegmentDefs USING [DataSegmentType, HeapDS],
Storage USING [FreePages],
StringDefs USING [AppendString],
SystemDefs USING [HeapZone];
DynamicZoneCold: MONITOR
IMPORTS DynamicZonePrivate, FSPDefs, Storage, StringDefs, SystemDefs
EXPORTS DynamicZone =
BEGIN OPEN DynamicZone, DynamicZonePrivate, FSPDefs, SegmentDefs;
-- Global Variables --
sysZone: MDSZone;
allocProcs: AllocProcs;
availableTypes: PACKED ARRAY SegTypeIndex OF BOOLEAN;
rover: SegTypeIndex;
-- Miscellaneous Declarations --
ZoneStillInUse: ERROR = CODE;
-- Externally Visible Procedures --
InitializeZones: PUBLIC ENTRY PROCEDURE =
-- must be called before any other procedures in this interface.
BEGIN
availableTypes ← ALL[TRUE];
rover ← LAST[SegTypeIndex];
allocProcs ← [AllocateNode, DeallocateNode];
sysZone ← InitZone[SystemDefs.HeapZone[], HeapDS, NIL];
END;
FinalizeZones: PUBLIC ENTRY PROCEDURE =
-- caled to clean up zone allocator. Note: it is the client's responsibility
-- to destroy any zones previously created with CreateZone.
BEGIN
tempZone: MDSZone = sysZone;
FOR segIndex: SegTypeIndex IN SegTypeIndex DO
IF ~availableTypes[segIndex] THEN RETURN WITH ERROR ZoneStillInUse;
ENDLOOP;
tempZone.FREE[@LOOPHOLE[sysZone, MDSZoneHandle]];
END;
CreateZone: PUBLIC PROCEDURE [initialPages: PageCount ← 1, id: STRING ← NIL]
RETURNS [MDSZone] =
-- creates a new zone whose allocation behavior is determined by 'initialPages'.
-- 'id' is for assistance in debugging.
BEGIN
segType: DataSegmentType = AllocateSegmentType[];
fspZone: ZonePointer ← MakeNewZone[
base: GetPages[initialPages, segType], length: initialPages*AltoDefs.PageSize,
deallocate: Storage.FreePages];
RETURN[InitZone[fspZone, segType + 1, id]];
END;
TooManyZones: PUBLIC ERROR = CODE;
SystemZone: PUBLIC PROCEDURE RETURNS [MDSZone] =
-- returns the shared system zone
BEGIN
RETURN[sysZone]
END;
DestroyZone: PUBLIC PROCEDURE [zone: MDSZone] =
-- unconditionally destroys the zone. It is the client's responsibility to ensure
-- that no dangling pointers remain.
BEGIN
z: MDSZoneHandle = LOOPHOLE[zone];
FreeSegmentType[z.segType];
FSPDefs.DestroyZone[z.fspZone];
END;
PruneZone: PUBLIC PROCEDURE [zone: MDSZone] =
-- attempts to eliminate excessive space allocated to the zone.
BEGIN
[] ← FSPDefs.PruneZone[LOOPHOLE[zone, MDSZoneHandle].fspZone];
END;
-- Internal Procedures --
InitZone: PROCEDURE [fspZone: ZonePointer, segType: DataSegmentType, id: STRING]
RETURNS [MDSZone] =
BEGIN
tempZoneObject: MDSZoneObject ← MDSZoneObject[
procs: @allocProcs, fspZone: fspZone, segType: segType, id: NIL];
tempZone: MDSZone = LOOPHOLE[@tempZoneObject];
zone: MDSZoneHandle = tempZone.NEW[MDSZoneObject];
IF id ~= NIL AND id.length ~= 0 THEN
BEGIN
tempZoneObject.id ← tempZone.NEW[StringBody[id.length]];
StringDefs.AppendString[tempZoneObject.id, id];
END;
zone↑ ← tempZoneObject;
RETURN[LOOPHOLE[zone]]
END;
AllocateSegmentType: ENTRY PROCEDURE RETURNS [DataSegmentType] =
BEGIN
last: SegTypeIndex = rover;
DO
rover ← IF rover = LAST [SegTypeIndex] THEN FIRST[SegTypeIndex] ELSE SUCC[rover];
IF rover = last THEN EXIT;
IF availableTypes[rover] THEN {availableTypes[rover] ← FALSE; RETURN[rover*2]};
ENDLOOP;
RETURN WITH ERROR TooManyZones;
END;
FreeSegmentType: ENTRY PROCEDURE [segType: DataSegmentType] =
BEGIN
availableTypes[segType/2] ← TRUE;
END;
END.