-- Swapper>SwapperControl.mesa (last edited by Levin on September 15, 1982 8:50 pm) DIRECTORY CachedRegion USING [age, Apply, Outcome, pagefault, pageTop], CachedRegionInternal USING [FindUnreferenced], Environment USING [PageCount, PageNumber], MStore USING [AwaitBelowThreshold, SetThreshold], PageFault USING [AwaitPageFault], Process USING [DisableAborts, GetPriority, Priority, SetPriority, SetTimeout], ProcessPriorities USING [priorityPageFaultHigh], Runtime USING [CallDebugger], StoragePrograms USING [], SwapperException USING [Report], SwapperPrograms USING [ CachedRegionImplB, CachedSpaceImpl, PageFaultImpl, InitializeSwapBuffer, SwapperExceptionImpl, SwapTaskImpl]; SwapperControl: MONITOR --just so we can use a CONDITION as a mechanism for yielding control-- IMPORTS CachedRegion, CachedRegionInternal, MStore, PageFault, Process, Runtime, SwapperException, SwapperPrograms EXPORTS StoragePrograms = BEGIN InitializeSwapper: PUBLIC PROCEDURE [pMapLogDesc: LONG POINTER TO UNSPECIFIED] = BEGIN throwAway: PROCESS; priorityPrev: Process.Priority; -- CachedRegionImplA is started by PilotControl (see StoragePrograms). -- MStoreImpl is started by PilotControl (see StoragePrograms). -- SimpleSpaceImpl is started by PilotControl (see StoragePrograms). -- ResidentMemoryImpl is started by PilotControl (see StoragePrograms). -- ResidentHeapImpl is started by PilotControl (see StoragePrograms). START SwapperPrograms.CachedSpaceImpl[]; START SwapperPrograms.CachedRegionImplB[pMapLogDesc]; SwapperPrograms.InitializeSwapBuffer[]; -- (CachedSpaceImpl must be started first.) START SwapperPrograms.PageFaultImpl[]; START SwapperPrograms.SwapTaskImpl[]; START SwapperPrograms.SwapperExceptionImpl[]; Process.DisableAborts[@aShortTime]; Process.SetTimeout[condition: @aShortTime, ticks: 1]; priorityPrev ← Process.GetPriority[]; Process.SetPriority[ProcessPriorities.priorityPageFaultHigh]; throwAway ← FORK PageFaultProcess[]; -- (no profit in detaching.) Process.SetPriority[priorityPrev]; -- (ReplacementProcess is forked by PilotControl.) END; PageFaultProcess: PROCEDURE = BEGIN page: Environment.PageNumber; outcome: CachedRegion.Outcome; DO page ← PageFault.AwaitPageFault[]; -- wait for a page fault. -- Start region coming in. Faulting process will be restarted by PageTransferProcess -- when it is in. outcome ← CachedRegion.Apply[page, CachedRegion.pagefault].outcome; WITH outcome SELECT FROM ok => NULL; regionDMissing, spaceDMissing, error => -- I can't do it, pass the buck to the VM Helper. SwapperException.Report[page, CachedRegion.pagefault, outcome]; ENDCASE => ERROR; ENDLOOP; END; aShortTime: CONDITION; -- used to yield control to VM Helper, and to yield control if everyone is being referenced. ReplacementProcess: PUBLIC ENTRY PROCEDURE [threshold: Environment.PageCount] = BEGIN deadlockPasses: CARDINAL = 1000; -- meant to be about 60 sec of trying. swapUnitsAgedInCycle: CARDINAL; -- just for instrumentation. page, pageNext: Environment.PageNumber; newCycle, allReferenced: BOOLEAN; outcome: CachedRegion.Outcome; passes: CARDINAL ← 0; MStore.SetThreshold[threshold]; DO --make a pass through memory.. FOR page ← FIRST[Environment.PageNumber], pageNext WHILE page<CachedRegion.pageTop DO IF (newCycle ← MStore.AwaitBelowThreshold[].newCycle) THEN -- wait until memory gets short {passes ← 0; swapUnitsAgedInCycle ← 0}; [allReferenced, page] ← CachedRegionInternal.FindUnreferenced[newCycle, page]; IF allReferenced THEN WAIT aShortTime; [outcome, pageNext] ← CachedRegion.Apply[page, CachedRegion.age]; -- swaps out region if not referenced; else marks it not referenced. swapUnitsAgedInCycle ← SUCC[swapUnitsAgedInCycle]; SELECT outcome.kind FROM ok => NULL; spaceDMissing => { SwapperException.Report[page, CachedRegion.age, outcome]; IF passes >= 2 THEN WAIT aShortTime; }; -- if we're having trouble, allow VM Helper a chance to make progress. ENDCASE => ERROR; ENDLOOP; IF (passes ← SUCC[passes]) >= deadlockPasses THEN Runtime.CallDebugger["No regions to swap out!"]; ENDLOOP; --end of one pass through memory. END; END. LOG (For earlier log entries, see Pilot 3.0 archive version.) January 31, 1980 1:03 PM Knutsen/McJones Add Region Cache parameters/switch to InitializeSwapper starting interface. February 21, 1980 6:53 PM Knutsen Implement Region Cache parameters. Don't START MStoreImpl (now started by PilotControl). March 20, 1980 12:50 PM Knutsen Made ReplacementProcess detect deadlocks. April 15, 1980 12:05 PM Knutsen Various components started early by PilotControl. December 1, 1980 12:55 PM Knutsen Only use Process.mumble during initialization. Yield to VMHelper if having trouble. Use FindUnreferenced. January 19, 1981 4:14 PM Knutsen Set process priorities. September 15, 1982 8:50 pm Levin PageFault.Await => PageFault.AwaitPageFault.