-- [Indigo]<Grapevine>VM>VMDefs.mesa -- Transport Mechanism - DEFS for simulated virtual memory -- -- Andrew Birrell 8-Feb-80 10:29 -- -- Roy Levin 2-Nov-81 16:07:14 -- VMDefs: DEFINITIONS = BEGIN -- Types -- CacheIndex: TYPE = [0..256); -- implementation limit on number of pages in cache. Page: TYPE = POINTER TO PageContents; PageContents: TYPE = RECORD [ SELECT OVERLAID * FROM words => [words: ARRAY PageIndex OF WORD], bytes => [bytes: PACKED ARRAY PageByteIndex OF [0..256)], chars => [chars: PACKED ARRAY PageByteIndex OF CHARACTER], ENDCASE]; PageNumber: TYPE = [0..LAST[CARDINAL]); -- PageNumber = 0 for the first data page of a file. -- Note: Notwithstanding this declaration, the implementation limits the maximum -- value of PageNumber to be 77777B. pageSize: CARDINAL = 256; -- the maximum number of words in a data page. pageByteSize: CARDINAL = 512; -- the maximum number of bytes in a data page. PageIndex: TYPE = [0..pageSize); -- PageIndex = 0 for the first data word of a page of a file. PageByteIndex: TYPE = [0..pageByteSize); -- PageByteIndex = 0 for the first data byte of a page of a file. PageAddress: TYPE = RECORD [file: FileHandle, page: PageNumber]; FullAddress: TYPE = RECORD [page: PageAddress, word: PageIndex]; -- Defines a data word within a file; the earliest data word occurs at page=0, word=0. Position: TYPE = RECORD [page: PageNumber, byte: PageByteIndex]; -- Defines a data byte index within a file; the earliest data byte occurs at page=0, -- byte=0. -- Global control -- InitializeVM: PROCEDURE [min, max: CacheIndex, numOps: CARDINAL ← 20]; -- Specifies number of pages to be allowed in cache; number may be reduced from in -- response to requests for storage for other reasons, but will not be allowed to drop -- below min. "numOps" is the maximum number of (local) disk operations that can be -- in progress simultaneously. This must be called before any other procedure in -- VMDefs. It is assumed that during InitializeVM no attempt is made to access -- other procedures of the virtual memory system. FinalizeVM: PROCEDURE; -- Tidies up and shuts down the virtual memory system. If any files remain open, -- an error is raised. It is assumed that during FinalizeVM no attempt is made to -- access other procedures of the virtual memory system. -- File system access -- FileSystemType: TYPE = {Alto, IFS, Juniper}; FileSystem: TYPE = POINTER TO FSInstance; FSInstance: TYPE; FSAlto: FileSystem = NIL; Login: PROCEDURE [system: FileSystemType, server, userName, password, secondaryName, secondaryPassword: STRING ← NIL] RETURNS [FileSystem]; -- Initiates activity with a file system of the indicated sort using the indicated -- server, and supplies user's credentials. The FileSystem returned -- is subsequently supplied to OpenFile to identify the file system (see below). -- The precise semantics of this procedure are file system dependent: -- Alto This operation has no effect and can be omitted. -- IFS Login is mandatory. The userName and password are passed -- to the indicated server (which cannot be defaulted) for validation. -- Juniper Login is mandatory. The userName and password are passed to the -- indicated server (or nearest one, if defaulted) for validation. If -- the login attempt succeeds, the FileSystem returned implicitly -- identifies a transaction under which subsequent file operations will -- be performed. It is permissable to have multiple FileSystems for -- Juniper, which represent multiple transactions. UnableToLogin: ERROR [reason: Problem]; -- raised by Login. Logout: PROCEDURE [FileSystem]; -- Terminates activity with the indicated file system. The precise semantics of -- this procedure are file system dependent: -- Alto This operation has no effect and can be omitted. -- IFS All files must previously have been closed. -- Juniper An implicit CheckpointTransaction occurs. -- After Logout, the FileSystem is no longer valid and must not be reused. Error: ERROR [reason: Problem]; -- Error conditions that are largely independent of the specific operation are -- reported by this signal. It can be raised by any of the file system access -- procedures defined in this interface or by ReadPage, Wait, StartWait, or -- MarkStartWait. The state of open files on the file system's backing store is -- file system dependent; local (cached) pages of the files are unaffected. The -- appropriate recovery strategy depends upon the specific problem; see below. Problem: TYPE = {ok, io, resources, credentials, other}; -- The general interpretations of these problems are as follows: -- ok (For internal convenience; never actually raised). -- io An I/O failure has occurred. For the local (Alto) file system, -- this indicates an unrecoverable disk error. For remote file -- systems, a communication failure or other problem (e.g., server -- crash) has rendered the file system unavailable. The use of -- AbandonFile to cleanup after this error is encouraged; in -- particular, subsequent page access operations (with certain -- explicitly noted exceptions, e.g., UsePage), CloseFile, or -- AbandonFile are likely to raise this signal again. -- resources The file system cannot perform the requested operation because -- of some sort of resource constraint. For the local (Alto) file -- system, this indicates the disk is full. For remote file -- systems, a storage quota may have been reached, or the storage -- resource may have been exhausted. -- credentials The file system has rejected the requested operation on the -- basis of access controls. The credentials presented at Login -- time were insufficient to permit the attempted operation. -- other This is a placeholder whose meaning is not specified. CheckpointTransaction: PROCEDURE [FileSystem]; -- If the argument FileSystem does not identify a Juniper file system, this operation -- has no effect. Otherwise, the caller is suspended until all previously initiated -- writes completed, at which time they become committed. The underlying transaction -- remains valid, and open files remain open. AbortTransaction: PROCEDURE [FileSystem]; -- If the argument FileSystem does not identify a Juniper file system, this operation -- has no effect. Otherwise, any writes started since the last CheckpointTransaction -- are canceled. Any files opened as part of this transaction are automatically -- closed. TransactionError: ERROR [reason: TransactionProblem]; -- raised by CheckpointTransaction (and therefore implicitly by Logout). TransactionProblem: TYPE = {ok, aborted, brokenReadLock, other}; -- File handling -- FileHandle: TYPE = POINTER TO FileObject; FileObject: TYPE; Percentage: TYPE = [0..100]; FileTime: TYPE = LONG CARDINAL; -- times are expressed in seconds since midnight, January 1, 1901 GMT. Note that -- this is compatible with the standard Time and TimeDefs interfaces. defaultTime: FileTime = 0; OpenOptions: TYPE = {old, oldReadOnly, new, oldOrNew}; -- defines how a file will be opened, as follows: -- old - file must exist, read/write/append -- oldReadOnly - file must exist, only read allowed -- new - file must not exist, read/write/append -- oldOrNew - created if needed, read/write/append OpenFile: PROCEDURE [ system: FileSystem ← FSAlto, name: STRING, options: OpenOptions ← oldReadOnly, cacheFraction: Percentage ← 0] RETURNS [FileHandle]; -- the file 'name' is assumed to be interpretable by the FileSystem 'system', which -- is requested to open the file under the conditions specified by 'options'. -- 'cacheFraction' suggests the proportion of the cache that should be allocated -- for this file. CantOpen: ERROR [reason: AccessFailure]; -- raised by OpenFile. AccessFailure: TYPE = {ok, io, notFound, alreadyExists, accessDenied, illegalFileName, other}; -- 'ok' and 'io' are for internal use only; they are never actually raised. -- 'notFound' applies if 'options' is either 'old' or 'oldReadOnly' and the file -- cannot be found. 'alreadyExists' applies if 'options' is 'new' and the file -- already exists. 'accessDenied' applies if granting access would violate -- the file system's guarantees of protection or file integrity. (This may -- mean that the file is temporarily unavailable or that the file system -- considers the credentials supplied by Login and 'options' to be incompatible.) -- 'illegalFileName' applies if the file system rejects the file name on -- syntactic grounds. GetOpenFileParameters: PROCEDURE [FileHandle] RETURNS [system: FileSystem, options: OpenOptions, cacheFraction: Percentage]; -- returns the values of the indicated parameters supplied at OpenFile time. CloseFile: PROCEDURE [FileHandle]; -- The FileHandle will no longer be used. An error will be raised if any unreleased -- pages remain for this file. Calls StartFile followed by WaitFile. GetFileSystem: PROCEDURE [file: FileHandle] RETURNS [FileSystem] = -- returns the 'system' argument supplied to OpenFile at the time that it returned -- the indicated FileHandle. INLINE {RETURN[GetOpenFileParameters[file].system]}; DestroyFile: PROCEDURE [FileHandle]; -- Calls CloseFile, then deletes the file from the file system. AbandonFile: PROCEDURE [FileHandle]; -- The FileHandle will no longer be used. Any unreleased pages of the file will -- be forcibly released. Dirty pages in the cache are not guaranteed to -- reach the backing file. This procedure is intended to be used to clean up after -- Error[io] has been raised. GetFileLength: PROCEDURE [FileHandle] RETURNS [Position]; -- Returns the page and byte number of the byte one beyond the last byte of the file. -- For an empty file, this is [0, 0]; for a file with 512 data bytes, this is [1, 0]; -- for a file with 612 data bytes, this is [1, 100]. SetFileLength: PROCEDURE [file: FileHandle, position: Position]; -- Sets the length of the file such that the Position argument refers to the byte -- one beyond the last byte of the file. SetFileLength performs atomic extension of -- the file if the new length implies a transfer of at most one page and the data -- for the extension is present in the cache. Otherwise, if the file is implicitly -- lengthened, new bytes have undefined content. StartFile: PROCEDURE [FileHandle]; -- Initiates transfers for all pages of the file marked as dirty in the cache. WaitFile: PROCEDURE [FileHandle]; -- The caller is suspended until all previously initiated transfers on this file -- have completed. This call may raise the signal CantWriteBackingStore. GetFileTimes: PROCEDURE [file: FileHandle] RETURNS [read, write, create: FileTime]; -- returns the associated times for the given file. SetCreationTime: PROCEDURE [file: FileHandle, create: FileTime ← defaultTime]; -- sets the creation time for the indicated file. If the time is defaulted, it is -- set to the current time. -- Access to pages -- -- The following procedures provide a means of accessing files similar to that -- available in an integrated virtual memory. While a page of the virtual memory -- is swapped in to physical memory, it is shared by all its users. Each page is -- locked in physical memory while anyone is using it. Anyone altering the contents -- of a page must notify this fact before releasing the page. -- If the page being manipulated is associated with a file that is part of a -- transaction, then operations that write the page to the file do not become -- permanent until the transaction is "committed" (see CheckpointTransaction and -- Logout, above). The comments below define the moment of committal for -- pages in files that are not part of a transaction, which includes all files on the -- local Alto disk. LookAheadCount: TYPE = CacheIndex; ReadPage: PROCEDURE [addr: PageAddress, lookAhead: LookAheadCount ← 0] RETURNS [Page]; -- Read specified page, waiting until the contents are available, and possibly -- initiating read-ahead. The memory is allocated by the virtual memory system, and -- is available to the caller until he calls ReleasePage with this page. Multiple -- users of the same page receive the same 'Page' value. Reading beyond the end -- of the file is not allowed. If an unrecoverable error has occurred when reading -- the data from the file, and has not been cleared (see UsePage), the signal -- CantReadBackingStore is raised. StartReading: PROCEDURE [addr: PageAddress, lookAhead: LookAheadCount ← 0]; -- Initiates reading the specified page, and "lookAhead" extra pages. addr.page -- may legitimately fall in the range [0..filesize). UsePage: PROCEDURE [addr: PageAddress] RETURNS [Page]; -- Return specified page, but its contents are undefined; no read operation occurs. -- The memory is allocated by the virtual memory system, and is available to the -- caller until he calls ReleasePage with this page. Multiple users of the same page -- receive the same 'Page' value. addr.page may legitimately fall in the range -- [0..filesize]. This call clears any unrecoverable errors which had previously -- occurred when reading the data for this page from the file. AllocatePage: PROCEDURE RETURNS [Page]; -- Allocate page in memory with undefined contents. The memory is allocated by the -- virtual memory system, and is available to the caller until he calls ReleasePage -- with this page. Before this page can passed to MarkStart or MarkStartWait, it must -- be associated with an address by passing it to RemapPage. RemapPage: PROCEDURE [page: Page, addr: PageAddress]; -- The given page is now to be considered as the contents of the address "addr". It -- is required that there be no other user of "page", and that there be no user of -- "addr". addr.page may legitimately fall in the range [0..filesize]. This call -- clears any unrecoverable errors which had previously occurred when reading the data -- for "addr" from the file. UnmapPage: PROCEDURE [Page]; -- The given page is disassociated from any backing storage. It is required that -- there be no other user of the argument Page. PageInCache: PROCEDURE [PageAddress] RETURNS [BOOLEAN]; -- This procedure permits clients to optimize performance by testing whether a ReadPage -- of the argument PageAddress is likely to be fast. A TRUE result from this procedure -- means a subsequent ReadPage will probably not require physical I/O. Mark: PROCEDURE [Page]; -- The contents of the given page have been altered. If the page is associated -- with a backing file page and is subsequently removed from the in-core cache, the -- new data will be written to the file. The implicitly associated PageNumber must be -- in the range [0..filesize). It is an error to invoke this operation on a page -- that is associated with a read-only file. MarkStart: PROCEDURE [Page]; -- The contents of the given page have been altered and are to be written to the -- associated page of backing file (it is an error to perform this operation on a page -- that has no backing storage). MarkStart initiates the transfer of the data -- to the file, but does not wait for it to complete. The implicitly associated -- PageNumber may legitimately fall in the range [0..filesize]. If it equals -- filesize, the file is implicitly extended during this call, although this fact may -- not yet be recorded on stable storage. It is an error to invoke this operation -- on a page that is associated with a read-only file. MarkStartWait: PROCEDURE [Page]; -- The contents of the given page have been altered and are to be written to the -- associated page of backing file (it is an error to perform this operation on a page -- that has no backing storage). MarkStartWait initiates the transfer of the data -- to the file, and waits for it to complete. The implicitly associated -- PageNumber may legitimately fall in the range [0..filesize]. If it equals -- filesize, the file is implicitly extended during this call. This call may raise -- the signal CantWriteBackingStore. It is an error to invoke this operation -- on a page that is associated with a read-only file. Start: PROCEDURE [Page]; -- If the contents of the given page have been marked as dirty, Start initiates the -- transfer of the data to the file (it is an error to perform this operation on a -- page that has no backing storage). The implicitly associated PageNumber may -- legitimately fall in the range [0..filesize]. If it equals filesize, the file is -- implicitly extended during this call. StartWait: PROCEDURE [Page]; -- If the contents of the given page have been marked as dirty, StartWait initiates -- the transfer of the data to the file, and wait for it to complete (it is an error -- to perform this operation on a page that has no backing storage). The implicitly -- associated PageNumber may legitimately fall in the range [0..filesize]. If it -- equals filesize, the file is implicitly extended during this call. This call may -- raise the signal CantWriteBackingStore. Wait: PROCEDURE [Page]; -- If a transfer of the data to the file has previously been initiated, then wait -- for it to complete. This call may raise the signal CantWriteBackingStore. Release: PROCEDURE [Page]; -- The caller is no longer reading or writing the page of memory indicated, although -- others may be doing so. The data contents of the page are preserved, although -- they are not necessarily written to the file unless MarkStart or MarkStartWait has -- previously been called for this page. Deactivate: PROCEDURE [Page]; -- This operation is logically equivalent to Release, but additionally suggests to -- the implementation that the argument Page be removed from the in-core cache. -- Deactivate can produce better cache performance during extended "streaming" -- operations. PageToPageAddress: PROCEDURE [Page] RETURNS [PageAddress]; -- delivers the PageAddress corresponding to Page. The page must be associated with -- a backing storage location. -- Errors -- CantWriteBackingStore: ERROR [badAddress: PageAddress, badPage: Page]; -- the data for this page could not be written to the file, because of persistent -- errors; this is raised if the user waits for the page to reach the file. CantReadBackingStore: ERROR [badAddress: PageAddress]; -- the data for this page could not be read from the file; this is raised whenever -- the user asks for the data (see ReadPage and UsePage). END.