-- 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.