<> <> <> <> <> <> <> <> <<>> <> <<>> DIRECTORY Basics USING [bytesPerPage, logBytesPerPage, logWordsPerPage, wordsPerPage]; <> <> <<>> YggDummyVM: CEDAR DEFINITIONS = BEGIN <> PageNumber: TYPE = INT; -- [0..2^24) PageCount: TYPE = INT; -- [0..2^24] <> <> <<>> Interval: TYPE = RECORD [page: PageNumber, count: PageCount]; nullInterval: Interval = [page: 0, count: 0]; <> <> PageState: TYPE = RECORD [ dataState: DataState, -- state of the contents of the page (see below) readOnly: BOOL, -- altered only by MakeReadOnly and MakeReadWrite hasRealMemory: BOOL, -- altered only by SwapIn and MakeUndefined needsCleaning: BOOL, -- a hint for clients of "Clean" pinCount: INT -- altered only by Pin and Unpin ]; <> <> DataState: TYPE = { none, -- page is unallocated; it has no associated backing storage undefined, -- page is allocated, but content is undefined unchanged, -- page content has not changed since MakeUnchanged was last called changed -- page content has changed }; <> <> State: PROC [page: PageNumber] RETURNS [state: PageState]; <<... returns the current PageState of the indicated page.>> <> <<... sets the dataState of all pages in the indicated interval.>> <> <<>> <> <<>> <> VMPartition: TYPE = {lowCore, pda, mds, normalVM}; <> <<>> LogPageCount: TYPE = NAT[0..23--LogBase2[PageCount.LAST]-1--]; Allocate: PROC [count: PageCount, partition: VMPartition _ normalVM, subRange: Interval _ nullInterval, start: PageNumber _ 0, alignment: LogPageCount _ 0, in64K: BOOL _ FALSE] RETURNS [interval: Interval]; <> <<(1) for each page in "interval", State[page].dataState = none,>> <<(2) interval.count = count,>> <<(3) if subRange.count >= count, then "interval" is contained in "subRange",>> <<(4) interval.page MOD 2alignment is zero, and>> <<(5) if start is non-zero, then interval.page-start is minimal, and>> <<(6) if in64K is TRUE, then the interval does not cross a 64K word boundary.>> <> <> <> <<(1) for each page in "bestInterval", State[page].dataState = none,>> <<(2) bestInterval.count < count with count-bestInterval.count minimal, and>> <<(3) if subRange.count >= count, then "bestInterval" is contained in "subRange",>> <> SimpleAllocate: PROC [count: PageCount] RETURNS [interval: Interval]; <<... equivalent to Allocate[count: count], defaulting all other parameters.>> <<>> CantAllocate: ERROR [bestInterval: Interval]; <<... raised by Allocate; bestInterval is the largest available interval within the requested one.>> <<>> Free: UNSAFE PROC [interval: Interval]; <<... performs SetDataState[interval, none].>> <> <> <<>> <> <> <> SwapIn: UNSAFE PROC [interval: Interval, kill: BOOL _ FALSE, pin: BOOL _ FALSE, nextPage: PageNumber _ 0]; <> <> <> <> <> <> <> <> <> <> <> Kill, MakeUndefined: UNSAFE PROC [interval: Interval]; <<... performs SetDataState[interval, undefined].>> <> <> Touch: PROC [interval: Interval]; <<... performs SwapIn[interval: interval].>> <> <> <> <<>> <> Pin: PROC [interval: Interval]; <<... performs SwapIn[interval: interval, pin: TRUE].>> <> <> <> <> Unpin: PROC [interval: Interval]; <> <> <> <<>> <> <> <<>> MakeReadOnly: PROC [interval: Interval]; <> <> <> <<>> MakeReadWrite: PROC [interval: Interval]; <> <> <<>> <<>> <> <<>> MakeUnchanged: PROC [interval: Interval]; <<... performs SetDataState[interval, unchanged].>> <> <> <> <<>> MakeChanged: PROC [interval: Interval]; <<... performs SetDataState[interval, changed].>> <> <> <<>> <> <> <<>> Clean: PROC [interval: Interval]; <<... ensures that the backing storage for each page in the interval contains the same information as the associated real memory (if any).>> <> <<>> Age: PROC [interval: Interval]; <<... increases the likelihood that the backing storage associated with pages in the interval will be selected for replacement. However, this procedure does not initiate any I/O operations.>> <> <<>> ForceCleaning: PROC; <<... forces the VM laundry process to clean some memory.>> <<>> <> AddressFault: ERROR [address: LONG POINTER]; WriteProtectFault: ERROR [address: LONG POINTER]; <> <<>> IOErrorType: TYPE = {software, hardware}; CantDoIO: ERROR [reason: IOErrorType, page: PageNumber]; <> <<>> LaundryError: TYPE = RECORD [ errorType: IOErrorType, -- error classification page: PageNumber -- page that gave trouble ]; <<>> LastLaundryError: PROC RETURNS [LaundryError]; <> <> <> <<>> wordsPerPage: NAT = Basics.wordsPerPage; logWordsPerPage: NAT = Basics.logWordsPerPage; bytesPerPage: NAT = Basics.bytesPerPage; logBytesPerPage: NAT = Basics.logBytesPerPage; PagesForWords: PROC [words: INT] RETURNS [pages: PageCount]; WordsForPages: PROC [pages: PageCount] RETURNS [words: INT] ; PagesForBytes: PROC [bytes: INT] RETURNS [pages: PageCount] ; BytesForPages: PROC [pages: PageCount] RETURNS [bytes: INT] ; <<>> AddressForPageNumber: PROC [page: PageNumber] RETURNS [address: LONG POINTER] ; PageNumberForAddress: PROC [address: LONG POINTER] RETURNS [page: PageNumber] ; END. <<>> <> <> <> <<>> <> <> <<>> <> <> <>