-- File: VMPageMgr.mesa
-- Last edited by Levin: 30-Oct-81 16:02:15
DIRECTORY
VMDefs USING [Error, PageAddress, Page, Problem],
VMPrivate USING [
FileHandle, FileObject, HandleToAddress, PageHandle, PageState, WaitReason];
VMPageMgr: MONITOR
IMPORTS VMDefs, VMPrivate
EXPORTS VMDefs, VMPrivate =
BEGIN OPEN VMPrivate;
-- This monitor synchronizes access to PageObjects by main memory address, and
-- therefore is implicitly concerned with pages for which useCount > 0. For this
-- reason, the AddressToHandle mapping is assumed to be stable and can be safely used
-- outside the cache monitor.
-- Procedures and Signals Exported to VMDefs --
FileObject: PUBLIC TYPE = VMPrivate.FileObject;
CantReadBackingStore: PUBLIC ERROR [badAddress: VMDefs.PageAddress] = CODE;
CantWriteBackingStore: PUBLIC ERROR [
badAddress: VMDefs.PageAddress, badPage: VMDefs.Page] = CODE;
-- Procedures and Signals Exported to VMPrivate --
InitializeVMPageMgr: PUBLIC PROCEDURE =
{NULL};
FinalizeVMPageMgr: PUBLIC PROCEDURE =
{NULL};
-- Synchronization --
AcquirePage: PUBLIC ENTRY PROCEDURE [page: PageHandle] =
BEGIN
UNTIL page.state = stable DO WAIT page.pageStable; ENDLOOP;
page.state ← unstable;
END;
ReleasePage: PUBLIC ENTRY PROCEDURE [page: PageHandle] =
{page.state ← stable; BROADCAST page.pageStable};
WaitUntilStable: PUBLIC PROCEDURE [page: PageHandle, why: WaitReason]
RETURNS [PageState] =
BEGIN
outcome: VMDefs.Problem ← ok;
GetOutcome: ENTRY PROCEDURE [page: PageHandle] = INLINE
-- waits until page is in an acceptable state as required by 'why'.
BEGIN
IF why = reading AND page.dirty THEN RETURN; -- writing underway; reading ok
UNTIL page.state = stable DO WAIT page.pageStable; ENDLOOP;
IF (outcome ← page.errorStatus) = other AND page.file.altoFile THEN
page.state ← unstable;
END;
GetOutcome[page];
SELECT outcome FROM
ok => RETURN[stable];
other => IF page.file.altoFile THEN RETURN[unstable]; -- neverStarted
io =>
SELECT why FROM
reading => ERROR CantReadBackingStore[[page.file, page.page]];
writing =>
ERROR CantWriteBackingStore[[page.file, page.page], HandleToAddress[page]];
ENDCASE;
ENDCASE;
ERROR VMDefs.Error[outcome]
END;
END.