-- Swapper>MStore.mesa (last edited by Knutsen on December 2, 1980 9:36 AM)
-- This interface defines operations for managing main storage (real memory).
-- Some MStore 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
PageMap USING [Flags],
VM USING [Interval, PageCount, PageNumber];
MStore: DEFINITIONS
LOCKS mStoreLock =
BEGIN OPEN VM;
Allocate: PROCEDURE [interval: Interval];
-- Allocates and maps real memory to all of the specified interval.
AllocateIfFree: ENTRY PROCEDURE [interval: Interval] RETURNS [countAllocated: PageCount] = INLINE
-- Allocates and maps real memory to as much of the specified interval as available real memory allows.
-- Guaranteed not to do an ALLOC from the frame heap.
BEGIN RETURN[allocateIfFreeInternal[interval]] END;
AwaitBelowThreshold: PROCEDURE RETURNS [newCycle: BOOLEAN];
-- Returns when the amount of free plu promised real memory is less than the current threshold setting.
-- newCycle is TRUE if, when AwaitBelowThreshold was called, the amount of memory was greater/equal than threshold (and hence we really did wait). newCycle is FALSE if, when AwaitBelowThreshold was called, the amount of memory was already less than threshold (and hence we did not wait but returned immediately).
Deallocate: ENTRY PROCEDURE [interval: Interval, promised: BOOLEAN] = INLINE
-- Frees any real memory currently mapped to pages of the specified virtual memory interval. The interval may have unmapped holes.
-- Guaranteed not to do an ALLOC from the frame heap.
BEGIN deallocateInternal[interval, promised] END;
Promise: PROCEDURE [count: PageCount];
-- Increases the amount of promised real memory by count pages. (Promised memory is memory that will be deallocated soon.)
Relocate: PROCEDURE [interval: Interval, pageDest: PageNumber, flagsKeep, flagsAdd: PageMap.Flags]
RETURNS [flags: PageMap.Flags, anyVacant: BOOLEAN];
-- For each page in interval, clear those flags not in flagsKeep (a bit mask), then set those flags in flagsAdd, and then relocate the (real) pages in interval to their corresponding spots in the interval [pageDest, interval.count].
-- Note: The implementation of Relocate may make the affected pages temporarily "vacant". The only case in which it does not is when the interval is not being moved (pageDest=interval.page) and the old flags are being totally overwritten (flagsKeep = flagsNone). In particular, this is the only case in which it can be applied to pinned pages.
SetThreshold: PROCEDURE [count: PageCount];
-- Sets the threshold value used by AwaitBelowThreshold.
mStoreLock: PRIVATE MONITORLOCK;
AllocateIfFreeInternal: PRIVATE TYPE = RECORD[
proc: PROCEDURE [interval: Interval] RETURNS [countAllocated: PageCount]];
allocateIfFreeInternal: PRIVATE AllocateIfFreeInternal;
DeallocateInternal: PRIVATE TYPE = RECORD[
proc: PROCEDURE [interval: Interval, promised: BOOLEAN]];
deallocateInternal: PRIVATE DeallocateInternal;
END.
LOG
March 30, 1978 12:00 AMMcJonesCreated file.
September 5, 1978 3:40 PMRedellAdded anyVacant result to Relocate
September 26, 1979 3:32 PMKnutsenAdded GetState, documentation
October 25, 1979 1:32 PMMcJonesAR2449: Added Recover (; add AllocateIfFree)
November 8, 1979 11:56 AMMcJonesAR2768: Allocated must not wait in fixed frame
March 20, 1980 9:35 AMKnutsenMade Deallocate, GetState ENTRY INLINEs. Added newCycle to AwaitBelowThreshold. Recover moved to StoragePrograms.
December 2, 1980 9:37 AMKnutsenRetired GetState.