-- file: LaurelSegments.mesa -- edited by Levin, January 27, 1981 11:57 AM -- edited by Brotz, November 13, 1981 12:21 PM DIRECTORY AltoDefs USING [BytesPerPage, PageCount, PageNumber], AltoFileDefs USING [FP, NullFP], Core USING [LookupInFileCache], exD: FROM "ExceptionDefs" USING [SysBug], lsD: FROM "LaurelStateDefs" USING [AllocateStateNode, PageCount, PageNumber, StateHeader, StateSegment, StateSegmentObject], SegmentDefs USING [DefaultAccess, DefaultBase, DeleteFileSegment, FileHandle, FileSegmentAddress, FileSegmentHandle, GetEndOfFile, GetFileSegmentDA, HardDown, InsertFile, LockFile, MakeSwappedIn, NewFileSegment, PageNumber, Read, ReadWriteAppend, SetEndOfFile, SetFileAccess, SetFileSegmentDA, SwapIn, SwapUp, Unlock, Write]; LaurelSegments: PROGRAM IMPORTS Core, exD, lsD, SegmentDefs EXPORTS lsD SHARES lsD = BEGIN OPEN lsD; -- Exported procedures for clients -- DefineStateSegment: PUBLIC PROC [nPages: PageCount] RETURNS [seg: StateSegment] = BEGIN OPEN SegmentDefs; IF ~beforeInstallation THEN exD.SysBug[]; seg _ AllocateStateNode[SIZE[StateSegmentObject]]; seg^ _ [pages: nPages, link: NIL, body: inCore[fsh: NewFileSegment[stateFile, stateFF, nPages, Read+Write]]]; IF segmentListHead = NIL THEN segmentListHead _ seg ELSE segmentListTail.link _ seg; segmentListTail _ seg; stateFF _ stateFF + nPages; SetEndOfFile[stateFile, stateFF-1, AltoDefs.BytesPerPage]; END; -- of DefineStateSegment -- SwapInStateSegment: PUBLIC PROCEDURE [segment: StateSegment] RETURNS [POINTER] = BEGIN OPEN SegmentDefs; MakeSwappedIn[segment.fsh, DefaultBase, HardDown]; RETURN[FileSegmentAddress[segment.fsh]] END; -- of SwapInStateSegment -- StateSegmentAddress: PUBLIC PROCEDURE [segment: StateSegment] RETURNS [POINTER] = BEGIN IF segment.fsh.lock = 0 THEN exD.SysBug[]; RETURN[SegmentDefs.FileSegmentAddress[segment.fsh]] END; -- of StateSegmentAddress -- WriteStateSegment: PUBLIC PROCEDURE [segment: StateSegment] = BEGIN segment.fsh.write _ TRUE; SegmentDefs.SwapUp[segment.fsh]; END; -- of WriteStateSegment -- ReleaseStateSegment: PUBLIC PROCEDURE [segment: StateSegment] = BEGIN SegmentDefs.Unlock[segment.fsh]; END; -- of ReleaseStateSegment -- -- Exported procedures private to the implementation -- segmentListHead, segmentListTail: StateSegment _ NIL; InstallSegments: PUBLIC PROCEDURE [header: POINTER TO StateHeader] = BEGIN -- this uses an n^2 algorithm to discover the disk hints, but we don't care -- how long installation takes. seg: StateSegment; fsh: SegmentDefs.FileSegmentHandle; IF (header.segmentList _ segmentListHead) = NIL THEN RETURN; header.firstSegmentPage _ segmentListHead.fsh.base; FOR seg _ segmentListHead, seg.link UNTIL seg = NIL DO OPEN SegmentDefs; fsh _ seg.fsh; SwapIn[fsh]; seg.hint _ GetFileSegmentDA[fsh]; Unlock[fsh]; DeleteFileSegment[fsh]; ENDLOOP; END; -- of InstallSegments -- InitializeSegments: PUBLIC PROCEDURE [header: POINTER TO StateHeader] = BEGIN OPEN SegmentDefs; seg: StateSegment; fsh: FileSegmentHandle; base: PageNumber _ header.firstSegmentPage; IF beforeInstallation THEN beforeInstallation _ FALSE ELSE exD.SysBug[]; FOR seg _ header.segmentList, seg.link UNTIL seg = NIL DO fsh _ NewFileSegment[stateFile, base, seg.pages, Read]; SetFileSegmentDA[fsh, seg.hint]; seg.fsh _ fsh; base _ base + seg.pages; ENDLOOP; END; -- of InitializeSegments -- -- Main program (executed by start trap) -- stateFF: PageNumber; stateFile: PUBLIC SegmentDefs.FileHandle; beforeInstallation: BOOLEAN _ TRUE; Initialize: PROCEDURE = BEGIN byte: CARDINAL; stateFP: AltoFileDefs.FP _ Core.LookupInFileCache["Laurel.state"L]; IF stateFP = AltoFileDefs.NullFP THEN exD.SysBug[]; stateFile _ SegmentDefs.InsertFile[@stateFP, SegmentDefs.DefaultAccess]; SegmentDefs.LockFile[stateFile]; SegmentDefs.SetFileAccess[stateFile, SegmentDefs.ReadWriteAppend]; [stateFF, byte] _ SegmentDefs.GetEndOfFile[stateFile]; IF byte ~= AltoDefs.BytesPerPage THEN exD.SysBug[] ELSE stateFF _ stateFF + 1; END; -- of Initialize -- Initialize[]; END.z20461l3008(529)\f1