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