-- Copyright (C) 1981, 1982, 1984, 1985 by Xerox Corporation. All rights reserved.
-- File: VMPageMgr.mesa, HGM, 17-Sep-85 0:27:06
-- Last edited by Wobber: 2-Nov-82 10:39:22
-- Last edited by Gobbel: 18-May-81 14:16:35
-- Last edited by Levin: 30-Apr-81 13:07:52
DIRECTORY
VMDefs USING [Error, PageAddress, Page, Problem],
VMPrivate USING [
FileHandle, FileObject, PageHandle, PageState, WaitReason];
VMPageMgr: MONITOR IMPORTS VMDefs 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 THEN page.state ← unstable;
END;
GetOutcome[page];
SELECT outcome FROM
ok => RETURN[stable];
other => RETURN[unstable]; -- neverStarted
io =>
SELECT why FROM
reading => ERROR CantReadBackingStore[[page.file, page.page]];
writing =>
ERROR CantWriteBackingStore[
[page.file, page.page], page.pointer];
ENDCASE;
ENDCASE;
ERROR VMDefs.Error[outcome]
END;
END.