-- SSImpl.Mesa Edited by Sandman on October 2, 1980 9:56 AM -- Copyright Xerox Corporation 1979, 1980 DIRECTORY Inline USING [LongCOPY], ProcessDefs USING [DisableInterrupts, EnableInterrupts], SegmentDefs USING [EasyUp, MaxRefs, OpenFile, SwapError], Segments USING [PageNumber, SHandle], Storage USING [FreeWords, Words], StreamDefs USING [ReadBlock, WriteBlock], Streams USING [Address, Ended, Handle], SwapperOps USING [AllocVM, FreePage, UpdateVM, ValidateObject]; SSImpl: PROGRAM IMPORTS SwapperOps, Inline, ProcessDefs, SegmentDefs, Storage, StreamDefs, Streams EXPORTS Segments, Streams = PUBLIC BEGIN Kill: PUBLIC PROCEDURE [seg: Segments.SHandle, base: Segments.PageNumber] = BEGIN OPEN ProcessDefs, SwapperOps; vmpage: Segments.PageNumber; pages: CARDINAL; ValidateObject[seg]; IF seg.swappedin THEN RETURN; IF seg.file.swapcount = SegmentDefs.MaxRefs THEN SIGNAL SegmentDefs.SwapError[seg]; IF ~seg.file.open THEN SegmentDefs.OpenFile[seg.file]; vmpage ← AllocVM[base, pages ← seg.pages, SegmentDefs.EasyUp, seg]; DisableInterrupts[]; IF seg.swappedin THEN {EnableInterrupts[]; UpdateVM[vmpage, pages, FreePage]; RETURN}; seg.VMpage ← vmpage; seg.file.swapcount ← seg.file.swapcount + 1; seg.swappedin ← TRUE; UpdateVM[vmpage, pages, seg]; EnableInterrupts[]; RETURN END; MakeReadOnly: PROCEDURE [seg: Segments.SHandle] = {}; GetBlock: PROCEDURE [h: Streams.Handle, a: Streams.Address, words: CARDINAL] RETURNS [read: CARDINAL] = BEGIN bufferSize: CARDINAL = MIN[words, 1024]; buffer: POINTER; count: CARDINAL; IF words = 0 THEN RETURN; read ← 0; buffer ← Storage.Words[bufferSize]; DO count ← StreamDefs.ReadBlock[h, buffer, MIN[words, bufferSize] ! UNWIND => Storage.FreeWords[buffer]]; IF count = 0 THEN EXIT; Inline.LongCOPY[from: buffer, to: a, nwords: count]; read ← read + count; IF (words ← words - count) = 0 THEN EXIT; a ← a + count; IF Streams.Ended[h] THEN EXIT; ENDLOOP; Storage.FreeWords[buffer]; RETURN END; PutBlock: PROCEDURE [h: Streams.Handle, a: Streams.Address, words: CARDINAL] RETURNS [written: CARDINAL] = BEGIN bufferSize: CARDINAL = MIN[words, 1024]; buffer: POINTER; count: CARDINAL; IF words = 0 THEN RETURN; written ← 0; buffer ← Storage.Words[bufferSize]; DO Inline.LongCOPY[from: a, to: buffer, nwords: count ← MIN[words, bufferSize]]; count ← StreamDefs.WriteBlock[h, buffer, count ! UNWIND => Storage.FreeWords[buffer]]; IF count = 0 THEN EXIT; written ← written + count; IF (words ← words - count) = 0 THEN EXIT; a ← a + count; ENDLOOP; Storage.FreeWords[buffer]; RETURN END; END.