-- CachedRegionInternal.mesa (last edited by Knutsen on December 1, 1980 12:52 PM)
-- This interface defines some operations on the region cache. They should be used only by modules in the Swapper.
-- Some CachedRegionInternal procedures are involved in recovering from the frame heap becoming exhausted. Because of this, invoking these procedures must not cause any frame allocations. This means that these procedures (and any that they call) must be INLINEs or coroutines. Since there is no such thing as an ENTRY coroutine, it must be simulated by an ENTRY INLINE procedure (which acquires the monitor lock) which itself calls the coroutine. To have an ENTRY INLINE PROCEDURE, the monitor lock must be available in the DEFINITIONS module. To allow a coroutine to be called as a public procedure, the procedure descriptor must be bundled into a record to force it to be a procedure variable.
DIRECTORY
CachedRegion USING [Desc, ReturnWait],
VM USING [Interval, PageNumber];
CachedRegionInternal: DEFINITIONS LOCKS regionCacheLock =
BEGIN
AwaitNotCheckedOut: PROCEDURE [pageMember: VM.PageNumber];
AllocateMStoreRuthlessly: ENTRY PROCEDURE [interval: VM.Interval] = INLINE
-- Allocates and maps real memory to all of the specified interval.
-- Guaranteed not to do an ALLOC from the frame heap.
BEGIN allocateMStoreRuthlesslyInternal[interval] END;
CheckIn: PROCEDURE [desc: CachedRegion.Desc];
-- Terminates caller’s exclusive access to region.
-- If desc.state=missing, the descriptor is deleted from the cache.
CheckOut: PROCEDURE [pageMember: VM.PageNumber, ifCheckedOut: CachedRegion.ReturnWait]
RETURNS [desc: CachedRegion.Desc];
-- Gives exclusive access to the region containing pageMember.
-- If desc.state=missing, the descriptor for that region was not in the cache. In that case, desc.interval.page+desc.interval.count is the lowest page at which the next region whose descriptor is in the cache might start. (If you try to CheckOut that descriptor, it might also return state=missing).
FindUnreferenced: PROCEDURE [newCycle: BOOLEAN, pageStart: VM.PageNumber]
RETURNS [allReferenced: BOOLEAN, pageVictim: VM.PageNumber];
-- Searches for a not-recently-referenced swap unit. If newCycle=TRUE, starts circular search at point of own choosing. If newCycle=FALSE, starts circular search at pageStart.
-- If allReferenced=TRUE, none could be found. The caller should try again later. If allReferenced=FALSE, the swap unit containing pageVictim is a good candidate to try to swap out.
LongMoveUp: PROCEDURE [pSource: LONG POINTER, size: CARDINAL, pSink: LONG POINTER] = INLINE
-- Move the contents of size words starting at pSource to the size words starting at pSink. pSink must be >= pSource to avoid clobbering source field
-- Similar to version in UtilitiesImpl, but INLINE.
{FOR i: CARDINAL DECREASING IN [0..size) DO (pSink+i)↑ ← (pSource+i)↑ ENDLOOP};
-- inSwappableCold: READONLY CachedRegion.InSwappable; ++ for age Operation: if a region’s temperature is inSwappableCold and it has not been referenced, it will be swapped out.
regionCacheLock: PRIVATE MONITORLOCK;
AllocateMStoreRuthlesslyInternal: PRIVATE TYPE = RECORD [
proc: PROCEDURE [interval: VM.Interval]];
allocateMStoreRuthlesslyInternal: PRIVATE READONLY AllocateMStoreRuthlesslyInternal;
END.
LOG
September 26, 1979 11:32 AMKnutsenCreated file.
March 18, 1980 2:49 PMKnutsenAdded AllocateMStoreRuthlessly, LongMove.
December 1, 1980 12:52 PMKnutsenAdded FindUnreferenced, deleted checkIn.