-- VMMgr>STLeafImpl.mesa (last edited by Levin on August 3, 1982 4:08 pm) DIRECTORY Environment USING [Base, bitsPerWord, first64K], File USING [Capability, Create, Delete, GetSize, ID, LimitPermissions, MakePermanent, PageCount, PageNumber, read, SetSize, Unknown, write], Inline USING [LowHalf], KernelFile USING [GetRootFile], PilotFileTypes USING [tAnonymousFile, tVMBackingFile], PilotSwitches USING [switches --.v--], ResidentHeap USING [MakeNode], Runtime USING [CallDebugger], SimpleSpace USING [Create, Page, Map], Space USING [Handle, PageNumber, WindowOrigin], StoragePrograms USING [LongPointerFromPage], STLeaf, Utilities USING [BitIndex], Volume USING [ID, GetAttributes, SystemID], VM USING [PageCount, PageNumber, PageOffset], VMMgrStore, VMMPrograms, Zone USING [Status]; STLeafImpl: PROGRAM -- logically, this should be a MONITOR, but at present all procedures (in STLeaf and VMMgrStore) in this module are only called from within the SpaceImpl monitor. IMPORTS File, Inline, KernelFile, PilotSwitches, ResidentHeap, Runtime, SimpleSpace, StoragePrograms, Volume EXPORTS STLeaf, VMMgrStore, VMMPrograms SHARES File --USING[fID]-- = BEGIN Bug: PRIVATE --PROGRAMMING-- ERROR [BugType] = CODE; BugType: TYPE = {bug0, bug1, bug2, bug3, bug4, bug5, bug6}; -- -- VMMgrStore -- Layout of VM backing file: -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- | MapLog | Space B-trees | backing pool for Data Spaces | -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ countLog: VM.PageCount = 40; countSpaceBTreesMax: VM.PageCount = 300; -- allows increasing countSpaceBTrees -- from the debugger, if necessary CountSpaceBTreesRange: TYPE = CARDINAL [0..countSpaceBTreesMax); countSpaceBTrees: CountSpaceBTreesRange ← 250; -- must be big enough to satisfy -- any Pilot client. minCountDataPool: VM.PageCount = 250; -- enough space for a (Dolphin) bitmap. maxCountDataPool: VM.PageCount = 1000; -- (arbitrary) countDataPool: VM.PageCount; -- depends on space available on volume. minBackFileSize: VM.PageCount = countLog + countSpaceBTrees + minCountDataPool; -- minimum size for backing file. backFileSize: File.PageCount; pageLog: VM.PageNumber = 0; pageSpaceBTrees: VM.PageNumber = pageLog + countLog; pageDataPool: VM.PageNumber = pageSpaceBTrees + countSpaceBTrees; systemVolume: Volume.ID; backingFile: File.Capability; -- data for Data Pool: fractionThreshold: CARDINAL = 10; -- windows larger than countDataPool / -- fractionThreshold will be allocated as separate files. countThreshold: VM.PageCount; pageDataPoolAvailable: LONG POINTER TO PACKED ARRAY [0..0) OF BOOLEAN; nSatisfiedFromDataPool, nCreated, currentUtilization: CARDINAL ← 0; -- usage -- statistics. InitVMMgrStore: PROCEDURE = BEGIN volSize, freePages, desiredBackFileSize: File.PageCount; systemVolume ← Volume.SystemID[]; [volSize, freePages, ] ← Volume.GetAttributes[volume: systemVolume]; desiredBackFileSize ← MAX[ minBackFileSize, MIN[maxCountDataPool, volSize/16, freePages/10]]; backingFile ← KernelFile.GetRootFile[ PilotFileTypes.tVMBackingFile, systemVolume]; BEGIN backFileSize ← File.GetSize[backingFile ! File.Unknown => GO TO Create]; IF backFileSize < minBackFileSize THEN File.SetSize[backingFile, backFileSize ← minBackFileSize]; EXITS Create => { backingFile ← File.Create[ systemVolume, backFileSize ← desiredBackFileSize, PilotFileTypes.tVMBackingFile]; File.MakePermanent[backingFile]; } END; IF backFileSize > LAST[VM.PageCount] THEN ERROR Bug[bug0]; countDataPool ← Inline.LowHalf[backFileSize] - countLog - countSpaceBTrees; -- initialize Data Pool: BEGIN size: CARDINAL = (countDataPool + Environment.bitsPerWord - 1)/Environment.bitsPerWord; node: Environment.Base RELATIVE POINTER; s: Zone.Status; k: CARDINAL; [node, s] ← ResidentHeap.MakeNode[size]; IF s ~= okay THEN ERROR Bug[bug1]; pageDataPoolAvailable ← @Environment.first64K[node]; IF maxCountDataPool > LAST[Utilities.BitIndex] THEN ERROR Bug[bug2]; -- restriction of Mesa 6. FOR k IN [0..countDataPool) DO pageDataPoolAvailable[k] ← TRUE ENDLOOP; countThreshold ← countDataPool/fractionThreshold; END; END; AllocateWindow: PUBLIC PROCEDURE [ pWindowResult: LONG POINTER TO Space.WindowOrigin, count: VM.PageCount] = BEGIN offsetPage: VM.PageCount; -- offset of first free page of current run. offsetOffset: VM.PageCount; -- offset of current free page from offsetPage. IF count <= countThreshold THEN FOR offsetPage ← 0, offsetOffset + 1 WHILE offsetPage + count <= countDataPool DO -- scope of HoleTooSmall -- BEGIN FOR offsetOffset IN [offsetPage..offsetPage + count) DO -- search for big enough run of free pages.. IF ~pageDataPoolAvailable[offsetOffset] THEN GO TO HoleTooSmall; -- (value of offsetOffset must survive loop exit.) ENDLOOP; FOR offsetOffset IN [offsetPage..offsetPage + count) DO -- mark run busy.. pageDataPoolAvailable[offsetOffset] ← FALSE; ENDLOOP; nSatisfiedFromDataPool ← nSatisfiedFromDataPool + 1; -- tally usage statistics. currentUtilization ← currentUtilization + count; pWindowResult↑ ← [File.LimitPermissions[backingFile, File.read + File.write], LONG[ pageDataPool + offsetPage]]; RETURN; EXITS HoleTooSmall => NULL; END; ENDLOOP; -- contiguous space not available from Data Pool. Allocate a new file: nCreated ← nCreated + 1; -- tally usage statistics. pWindowResult↑ ← [File.Create[systemVolume, count, PilotFileTypes.tAnonymousFile], 0]; END; DeallocateWindow: PUBLIC PROCEDURE [ pWindow: LONG POINTER TO Space.WindowOrigin, count: VM.PageCount] = BEGIN OPEN pWindow --USING[file, base]--; IF file.fID = backingFile.fID THEN BEGIN offsetPage, offsetOffset: VM.PageOffset; offsetPage ← Inline.LowHalf[base] - pageDataPool; IF base > LAST[VM.PageOffset] OR ~(offsetPage IN [0..countDataPool)) OR ~(offsetPage + count IN [0..countDataPool]) THEN ERROR Bug[bug3]; FOR offsetOffset IN [offsetPage..offsetPage + count) DO IF pageDataPoolAvailable[offsetOffset] THEN ERROR Bug[bug4]; pageDataPoolAvailable[offsetOffset] ← TRUE; ENDLOOP; currentUtilization ← currentUtilization - count; END ELSE File.Delete[file]; END; AllocateMapLogFile: PUBLIC PROCEDURE [ pWindowResult: LONG POINTER TO Space.WindowOrigin] RETURNS [size: VM.PageCount] = { pWindowResult↑ ← Space.WindowOrigin[backingFile, pageLog]; RETURN[countLog]}; -- -- STLeaf SpaceBTreeOverflow: PRIVATE --PROGRAMMING-- ERROR = CODE; spaceBTree: Space.Handle; pageBTree: Space.PageNumber; -- the starting page of the BTree area. leafAvailable: PACKED ARRAY CountSpaceBTreesRange OF BOOLEAN; InitSTLeaf: PROCEDURE = BEGIN IF countSpaceBTrees > countSpaceBTreesMax THEN ERROR; -- in case runtime checks are off leafAvailable ← ALL[TRUE]; spaceBTree ← SimpleSpace.Create[ countSpaceBTrees, hyperspace, --sizeSwapUnit:--1]; SimpleSpace.Map[ handle: spaceBTree, window: [backingFile, pageSpaceBTrees], andPin: FALSE]; pageBTree ← SimpleSpace.Page[spaceBTree]; END; Close: PUBLIC PROCEDURE [iLeaf: STLeaf.ILeaf] = BEGIN END; -- this procedure is now functionless, and therefore obsolete. Create: PUBLIC PROCEDURE RETURNS [iLeaf: STLeaf.ILeaf] = BEGIN k: CARDINAL; FOR k IN [0..countSpaceBTrees) DO IF leafAvailable[k] THEN { leafAvailable[k] ← FALSE; RETURN[STLeaf.ILeaf[k]]}; ENDLOOP; ERROR SpaceBTreeOverflow; END; Delete: PUBLIC PROCEDURE [iLeaf: STLeaf.ILeaf] = BEGIN IF leafAvailable[iLeaf] THEN ERROR Bug[bug5]; leafAvailable[iLeaf] ← TRUE; END; Open: PUBLIC PROCEDURE [iLeaf: STLeaf.ILeaf] RETURNS [STLeaf.PLeaf] = BEGIN IF leafAvailable[iLeaf] THEN ERROR Bug[bug6]; RETURN[StoragePrograms.LongPointerFromPage[pageBTree + iLeaf]]; END; -- -- Initialization IF PilotSwitches.switches.v = down THEN Runtime.CallDebugger["Key Stop V"L]; InitVMMgrStore[]; -- 1 of 2. InitSTLeaf[]; -- 2 of 2. END. May 16, 1978 11:29 AM McJones Created file June 20, 1978 2:26 PM McJones Added SimpleSpace calls June 21, 1978 10:31 AM McJones Open didn't set rgBuff.open June 21, 1978 10:46 AM McJones Close didn't stop searching when buffer found June 26, 1978 5:43 PM McJones Added iBuffMru hack August 2, 1978 10:09 AM McJones Enabled File.SetSize calls August 9, 1978 1:42 AM Purcell Use new SimpleSpace September 6, 1978 9:51 AM McJones Use GetRootFile September 29, 1978 10:52 AM McJones CR20.42: Replaced MakePermanent with PutRootFile August 8, 1979 4:30 PM McJones SpecialFile => KernelFile September 4, 1979 10:02 AM Forrest Changed to use PilotFileTYpes September 6, 1979 3:07 PM Ladner Installed instrumentation in leaf cache November 26, 1979 5:50 PM Knutsen Added VMMgrStore implementation. November 27, 1979 12:41 PM Knutsen InitVMMgrStore forgot to set backFileSize sometimes. Approx May 15, 1980 Forrest Converted to Mesa 6. May 29, 1980 3:20 PM Knutsen Use VM Backing File for Hierarchy and Projection. Use packed booleans for bit operations. Named the ERRORs. Moved Key Stop V here from VMMControl. June 3, 1980 5:36 PM Knutsen Don't use VM Backing File for large spaces. July 30, 1980 2:04 PM Knutsen Change MapLog from 20 to 40 pages. August 15, 1980 5:39 PM McJones Add "= CODE" to Bug August 16, 1980 4:26 PM McJones Change countSpaceBTrees from 40 to 60 September 15, 1980 2:46 PM Fay Change countSpaceBTrees from 60 to 150, and make variable. September 16, 1980 5:57 PM Knutsen Add forgotten =CODE to ERROR. 4-Feb-82 13:27:46 Levin Change countSpaceBTrees to 250 pages. August 3, 1982 4:08 pm Levin Correct all occurrences of ~IN.