-- ResidentMemory.mesa (last edited by Knutsen on November 5, 1980 10:44 AM)
-- Some ResidentMemory procedures are involved in recovering from the frame heap becoming exhausted. Because of this, invoking these procedures must not cause any frame allocations. This means that these procedures (and any that they call) must be INLINEs or coroutines. Since there is no such thing as an ENTRY coroutine, it must be simulated by an ENTRY INLINE procedure (which acquires the monitor lock) which itself calls the coroutine. To have an ENTRY INLINE PROCEDURE, the monitor lock must be available in the DEFINITIONS module. To allow a coroutine to be called as a public procedure, the procedure descriptor must be bundled into a record to force it to be a procedure variable.
DIRECTORY
Environment USING [PageCount];
ResidentMemory: DEFINITIONS
LOCKS residentMemoryLock =
BEGIN OPEN Environment;
Location: TYPE = {first64K, mds, hyperspace};
--Allocation of resident memory for I/O and miscellaneous use:
Allocate: ENTRY PROCEDURE [where: Location, pages: PageCount] RETURNS [lp: LONG POINTER TO UNSPECIFIED] = INLINE
-- Guaranteed not to do an ALLOC from the frame heap.
{ RETURN[allocateInternal[where, pages]] };
Free: ENTRY PROCEDURE [where: Location, pages: PageCount, lp: LONG POINTER TO UNSPECIFIED] = INLINE
-- Guaranteed not to do an ALLOC from the frame heap.
{ freeInternal[where, pages, lp] };
--Allocation of resident memory within the MDS:
AllocateMDS: ENTRY PROCEDURE [pages: PageCount] RETURNS [p: POINTER TO UNSPECIFIED] = INLINE
-- Guaranteed not to do an ALLOC from the frame heap.
{ RETURN[allocateMDSInternal[pages]] };
FreeMDS: ENTRY PROCEDURE [base: POINTER TO UNSPECIFIED, pages: PageCount] = INLINE
-- Guaranteed not to do an ALLOC from the frame heap.
{ freeInternal[mds, pages, LONG[base]] };
residentMemoryLock: PRIVATE MONITORLOCK;
AllocateInternal: PRIVATE TYPE = RECORD[
proc: PROCEDURE [where: Location, pages: PageCount] RETURNS [lp: LONG POINTER TO UNSPECIFIED] ];
allocateInternal: PRIVATE AllocateInternal;
AllocateMDSInternal: PRIVATE TYPE = RECORD[
proc: PROCEDURE [pages: PageCount] RETURNS [p: POINTER TO UNSPECIFIED] ];
allocateMDSInternal: PRIVATE AllocateMDSInternal;
FreeInternal: PRIVATE TYPE = RECORD[
proc: PROCEDURE [where: Location, pages: PageCount, lp: LONG POINTER TO UNSPECIFIED]];
freeInternal: PRIVATE FreeInternal;
END.
LOG
June 9, 1978 11:04 AMLauerCreated file.
June 22, 1978 11:38 AMLauerSeparated allocation from MDS and elsewhere; added FreeMDSPages; moved Pin and Unpin to module "Special".
January 25, 1980 2:33 PMKnutsenNamed return parameters.
April 16, 1980 8:47 AMKnutsenExpanded Location to include MDS. Added Free. Renamed to AllocateMDS, FreeMDS. Added residentMemoryLock, made Allocate, AllocateMDS ENTRY INLINEs.
November 5, 1980 10:44 AMKnutsenMade Free, FreeMDS ENTRY INLINEs.