DIRECTORY Basics USING [BITLSHIFT, BITRSHIFT]; VM: CEDAR DEFINITIONS IMPORTS Basics = BEGIN PageNumber: TYPE = INT; -- INT[0..2­(32-logBytesPerPage)) PageCount: TYPE = INT; -- INT[0..2­(32-logBytesPerPage)) Interval: TYPE = RECORD [page: PageNumber, count: PageCount]; nullInterval: Interval = [page: 0, count: 0]; ZeroPageCount: TYPE = PageCount[0..0]; NullInterval: TYPE = RECORD [page: PageNumber, count: ZeroPageCount]; FalseBool: TYPE = BOOL[FALSE..FALSE]; ZeroPageNumber: TYPE = PageNumber[0..0]; VMPartition: TYPE = { normalVM }; LogPageCount: TYPE = NAT[0..31--LogBase2[PageCount.LAST]-1--]; Allocate: PROC [count: PageCount, partition: VMPartition ¬ normalVM, subRange: NullInterval ¬ [0, 0], start: ZeroPageNumber ¬ 0, alignment: LogPageCount ¬ 0, in64K: FalseBool ¬ FALSE] RETURNS [interval: Interval]; SimpleAllocate: PROC [count: PageCount] RETURNS [interval: Interval]; CantAllocate: ERROR [bestInterval: Interval]; Free: UNSAFE PROC [interval: Interval]; Touch: PROC [interval: Interval]; AddressFault: ERROR [address: LONG POINTER]; WriteProtectFault: ERROR [address: LONG POINTER]; wordsPerPage: READONLY NAT; logWordsPerPage: READONLY NAT; bytesPerPage: READONLY NAT; logBytesPerPage: READONLY NAT; unitsPerPage: READONLY NAT; logUnitsPerPage: READONLY NAT; PagesForWords: PROC [words: INT] RETURNS [pages: PageCount] = INLINE { RETURN[LOOPHOLE[Basics.BITRSHIFT[words+(wordsPerPage-1), logWordsPerPage]]] }; WordsForPages: PROC [pages: PageCount] RETURNS [words: INT] = INLINE { RETURN[Basics.BITLSHIFT[pages, logWordsPerPage]] }; PagesForBytes: PROC [bytes: INT] RETURNS [pages: PageCount] = INLINE { RETURN[LOOPHOLE[Basics.BITRSHIFT[bytes+(bytesPerPage-1), logBytesPerPage]]] }; BytesForPages: PROC [pages: PageCount] RETURNS [bytes: INT] = INLINE { RETURN[Basics.BITLSHIFT[pages, logBytesPerPage]] }; PageNumberForAddress: PROC [address: POINTER] RETURNS [page: PageNumber] = INLINE { RETURN[LOOPHOLE[Basics.BITRSHIFT[LOOPHOLE[address], logUnitsPerPage]]] }; AddressForPageNumber: PROC [page: PageNumber] RETURNS [address: POINTER] = INLINE { RETURN[LOOPHOLE[Basics.BITLSHIFT[page, logUnitsPerPage]]] }; END. P VM.mesa Copyright Σ 1985, 1986, 1988, 1991 by Xerox Corporation. All rights reserved. Levin on September 20, 1983 11:56 am Beach, February 21, 1985 9:30:27 am PST Russ Atkinson (RRA) February 27, 1985 8:55:14 pm PST Willie-Sue, October 28, 1986 1:54:57 pm PST Bob Hagmann November 14, 1986 7:23:19 am PST Carl Hauser, March 24, 1988 3:03:13 pm PST Willie-s, February 19, 1991 5:54 pm PST Doug Wyatt, August 27, 1991 2:02 pm PDT The Cedar client interface to virtual memory. See VMDoc.tioga for more information. Basic Types The fundamental entities in which the VM traffics are page numbers and page counts. They are defined as INTs, but in reality they lie in the indicated subranges. An Interval refers to a sequence of consecutive pages IN [page .. page+count). Types for confining requests to what can be supported on Unix, while retaining client compatibility for simple clients. Virtual Memory Allocation Virtual memory is no longer divided into partitions, but the notion is retained for backward source compatibility for clients with no interest in the other partitions. Allocate returns an interval such that (1) each page in it was previously unallocated (2) interval.count = count, (3) interval.page MOD 2alignment is zero If no such interval can be found, CantAllocate is raised, passing an interval "bestInterval" such that bestInterval = nullInterval (i.e. no hint is given in this implementation as to the best available interval). Note that subRange, start, and in64K are meaningless and retained only for source compatibility with Cedar7.0 client programs supplying the default values. ... equivalent to Allocate[count: count], defaulting all other parameters. ... raised by Allocate; ... performs SetDataState[interval, none]. Free makes previously allocated memory again available for allocation. ! AddressFault if State[page].dataState = none for any page in interval. Procedures that may affect the virtual-real memory correspondence ... performs SwapIn[interval: interval]. For each page in "interval", State[page].hasRealMemory becomes TRUE, causing memory accesses to the page to proceed without delay. Since the real memory has not been pinned (see below), the real memory may be reclaimed by the replacement algorithm at any time. Touch would typically be used by a client who plans to reference an interval in the near future and wants to avoid the delay of a page fault: Process.Detach[FORK Touch[interval]]. ! AddressFault if State[page].dataState = none for any page in interval. Errors The above errors generally arise from erroneous memory accesses to virtual memory. AddressFault means that an unallocated page (i.e., one for which State[page].dataState = none) has been referenced. (The name AddressFault is intended to suggest that the program performing the access has an incorrect address.) Following this model, the operations in this interface raise AddressFault if any page they are asked to manipulate is unallocated. WriteProtectFault is raised by an attempt to store into a page for which State[page].readOnly is TRUE. No operations in this interface raise WriteProtectFault explicitly. Utilities It is frequently necessary to convert between counts in different units (pages, words, bytes) and between counts and addresses. Since the page size varies among machines, clients should always obtain these conversions through this interface. Κ­–(cedarcode) style•NewlineDelimiter ™codešœ™Kšœ ΟeœC™NKšΟy$™$J™'K™4K™+K™,K™*K™'K™'—˜šΟk ˜ KšœŸœŸ œŸ œ˜$——K˜K™-K™%K™šΡbklœŸœŸ ˜KšŸœŸœŸ˜—head™ Kšœ ŸœŸœΟc!˜9šœ ŸœŸœ‘!˜8KšœS™SKšœM™M—K™K˜šœ ŸœŸœ&˜=Kšœ6Ÿœ™NK™—Kšœ-˜-K˜™wKšœŸœ˜&KšœŸœŸœ*˜EKš œ ŸœŸœŸœŸœ˜%KšœŸœ˜(——™šœ Ÿœ˜"Kšœ§™§—K™KšœŸœŸœ‘œ˜>K˜šΟnœŸœ₯ŸœŸœ˜Ψšœ&™&Kšœ.™.Kšœ™KšœŸœΟu œ™(—šœf™fJ™m—Jšœ›™›K˜—š’œŸœŸœ˜EKšœJ™JK™—š’ œŸœ˜-Kšœ™—K™š’œŸœŸœ˜'Kšœ*™*KšœF™FKšœH™HK™——™AK˜š’œŸœ˜!Kšœ(™(Kšœ?ŸœΒ™…KšœŸœ™³KšœH™H——™Kš’ œŸœ ŸœŸœ˜,š’œŸœ ŸœŸœ˜1KšœŸŸœF™ιK™——™ Kšœς™ςK™šœŸœŸœ˜KšœŸœŸœ˜—šœŸœŸœ˜KšœŸœŸœ˜—šœŸœŸœ˜KšœŸœŸœ˜—K˜š’ œŸœ ŸœŸœ˜;KšœŸœ˜ KšŸœŸœŸ œ+˜KKšœ˜K˜—š’ œŸœŸœ Ÿœ˜;KšœŸœ˜ KšŸœŸ œ˜0Kšœ˜K˜—š’ œŸœ ŸœŸœ˜;KšœŸœ˜ KšŸœŸœŸ œ+˜KKšœ˜K˜—š’ œŸœŸœ Ÿœ˜;KšœŸœ˜ KšŸœŸ œ˜0Kšœ˜K™—š’œŸœ ŸœŸœ˜HKšœŸœ˜ KšŸœŸœŸ œŸœ˜FKšœ˜K˜—š’œŸœŸœ Ÿœ˜HKšœŸœ˜ KšŸœŸœŸ œ˜9Kšœ˜K˜——KšŸœ˜—…—da