DIRECTORY Basics USING [BYTE], BcdDefs USING [MTHandle], BootStartList USING [StateVectorCounts], IO USING [card, PutF, rope, STREAM], MB USING [Alloc, AllocFault, BHandle, EnumerateNoTrapModules, Handle, WartFrame], MBVM USING [AllocData, AllocMDSData, Base, CopyRead, CopyWrite, DataSeg, LongPointerFromSeg, LongWrite, MDS, PointerFromSeg, Read, Write], PrincOps USING [AllocationVectorSize, AV, ControlLink, Frame, FrameCodeBase, FrameSizeIndex, FrameVec, GFT, GFTIndex, GFTItem, GlobalFrame, GlobalFrameHandle, LargeReturnSlot, MainBodyIndex, PDABase, Priority, ProcessDataArea, ProcessStateBlock, SD, sGFTLength, SpecialReturnSlot, wordsPerPage], PrincOpsUtils USING [MakeFsi, PagesForWords, WordsForPages]; MBMain: CEDAR PROGRAM IMPORTS IO, MB, MBVM, PrincOpsUtils EXPORTS MB = BEGIN OPEN PrincOps; BYTE: TYPE = Basics.BYTE; AVPage: CARDINAL = LOOPHOLE[AV, CARDINAL]/wordsPerPage; GFTPage: CARDINAL = LOOPHOLE[GFT, CARDINAL]/wordsPerPage; data: MB.Handle _ NIL; values: REF Values _ NIL; Values: TYPE = RECORD [ frameWeights: PACKED ARRAY FrameSizeIndex OF BYTE _ ALL[LAST[BYTE]], fsiChain: PACKED ARRAY FrameSizeIndex OF BYTE _ ALL[LAST[BYTE]]]; DefaultValues: Values = [ frameWeights: [9,13,9,8,7,6,4,2,2,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0], fsiChain: [1,2,3,4,5,6,7,8,9,10,11,0,13,14,15,16,17,18,0,0,0,0,0,0,0,0,0,0,0,0]]; heapFrames, extraFrames: FrameCounts _ NIL; FrameCounts: TYPE = REF FrameCountTable; FrameCountTable: TYPE = ARRAY FrameSizeIndex OF CARDINAL; InitMain: PUBLIC PROC [h: MB.Handle] = { data _ h; values _ NEW[Values _ []]; heapFrames _ NEW[FrameCountTable _ ALL[0]]; extraFrames _ NEW[FrameCountTable _ ALL[0]]; FOR i: Priority IN Priority DO h.stateVectorCounts[i] _ LAST[CARDINAL]; ENDLOOP; h.nProcesses _ LAST[CARDINAL]; h.framePages _ LAST[CARDINAL]; h.pdaPages _ LAST[CARDINAL]; h.svSize _ LAST[CARDINAL]; h.gftLength _ LAST[CARDINAL]; h.mdsBase _ LAST[CARDINAL]; h.codeBase _ LAST[CARDINAL]; }; FinishMain: PUBLIC PROC = { values _ NIL; heapFrames _ NIL; extraFrames _ NIL; data _ NIL; }; InitMemory: PUBLIC PROC = { AssignDefaults[]; IF ~data.germ THEN {ReserveSelectedPages[]; InitPDA[]}; InitializeMDS[]; AllocateLocalFrames[]; }; AssignDefaults: PROC = { i: CARDINAL; FOR i IN Priority DO IF data.stateVectorCounts[i] = LAST[CARDINAL] THEN data.stateVectorCounts[i] _ simpleDefaults.stateVectorCounts[i]; ENDLOOP; FOR i IN FrameSizeIndex DO IF values.frameWeights[i] = LAST[BYTE] THEN values.frameWeights[i] _ DefaultValues.frameWeights[i]; IF values.fsiChain[i] = LAST[BYTE] THEN values.fsiChain[i] _ DefaultValues.fsiChain[i]; ENDLOOP; IF data.gftLength = LAST[CARDINAL] THEN data.gftLength _ simpleDefaults.gftLength; IF data.mdsBase = LAST[CARDINAL] THEN data.mdsBase _ simpleDefaults.mdsBase; IF data.codeBase = LAST[CARDINAL] THEN data.codeBase _ simpleDefaults.codeBase; IF data.pdaPages = LAST[CARDINAL] THEN data.pdaPages _ simpleDefaults.pdaPages; IF data.nProcesses = LAST[CARDINAL] THEN data.nProcesses _ simpleDefaults.nProcesses; IF data.framePages = LAST[CARDINAL] THEN data.framePages _ simpleDefaults.framePages; }; ReserveSelectedPages: PROC = { seg: MBVM.DataSeg; seg _ MBVM.AllocData[base: 1, pages: 1]; SetReservedSegBits[seg]; seg _ MBVM.AllocData[base: 376B, pages: 1]; SetReservedSegBits[seg]; seg _ MBVM.AllocData[base: 377B, pages: 1]; SetReservedSegBits[seg]; }; SetReservedSegBits: PROC [s: MBVM.DataSeg] = { s.info _ [FALSE, resident]; s.bootLoaded _ TRUE; }; InitPDA: PROC = { seg: MBVM.DataSeg; pda: PDABase; i: CARDINAL; words: CARDINAL _ 0; FOR i IN Priority DO words _ words + data.stateVectorCounts[i]*data.svSize; ENDLOOP; data.pdaPages _ MAX[ PrincOpsUtils.PagesForWords[ data.nProcesses*(SIZE[ProcessStateBlock]+1) + words + SIZE[ProcessDataArea]], data.pdaPages ]; seg _ MBVM.AllocData[base: 256, pages: data.pdaPages, dir: up]; SetReservedSegBits[seg]; TRUSTED { pda _ MBVM.LongPointerFromSeg[seg]; FOR i IN [0..data.pdaPages*wordsPerPage) DO MBVM.LongWrite[pda+i, 0]; ENDLOOP; }; }; InitializeMDS: PROC = TRUSTED { gftPages: CARDINAL; seg: MBVM.DataSeg; p: POINTER; p _ AV; SetReservedSegBits[seg _ MBVM.AllocMDSData[base: AVPage, pages: 1]]; FOR i: CARDINAL IN [0..wordsPerPage) DO MBVM.Write[p+i, 0] ENDLOOP; InitAV[p]; gftPages _ PrincOpsUtils.PagesForWords[data.gftLength*SIZE[GFTItem]]; SetReservedSegBits[seg _ MBVM.AllocMDSData[base: GFTPage, pages: gftPages]]; p _ GFT; FOR i: CARDINAL IN [0..gftPages*SIZE[GFTItem]) DO MBVM.Write[p+i, 0]; ENDLOOP; MBVM.Write[@SD[sGFTLength], data.gftLength]; }; InitAV: PROC [av: POINTER] = TRUSTED { FOR i: FrameSizeIndex IN FrameSizeIndex DO IF values.fsiChain[i] <= i THEN MBVM.Write[av+i, 1] ELSE MBVM.Write[av+i, 4*values.fsiChain[i]+2]; ENDLOOP; MBVM.Write[av+LargeReturnSlot, 1]; MBVM.Write[av+SpecialReturnSlot, 1]; }; TurnOffStartTrap: PUBLIC PROC = { DoIt: PROC [bh: MB.BHandle, mth: BcdDefs.MTHandle] RETURNS [BOOL] = TRUSTED { f: GlobalFrameHandle = bh.mt[mth.gfi].frame; fcb: FrameCodeBase; MBVM.CopyRead[from: @f.code, to: @fcb, nwords: SIZE[FrameCodeBase]]; fcb.out _ FALSE; MBVM.CopyWrite[from: @fcb, to: @f.code, nwords: SIZE[FrameCodeBase]]; RETURN[FALSE] }; MB.EnumerateNoTrapModules[DoIt]; }; StartControlLink: PUBLIC PROC RETURNS [proc: ControlLink] = TRUSTED { g: GlobalFrameHandle = MB.WartFrame[]; gf: GlobalFrame; MBVM.CopyRead[from: g, to: @gf, nwords: SIZE[GlobalFrame]]; proc _ [procedure[gfi: gf.gfi, ep: MainBodyIndex, tag: TRUE]]; gf.started _ TRUE; MBVM.CopyWrite[from: @gf, to: g, nwords: SIZE[GlobalFrame]]; }; SimpleValues: TYPE = RECORD [ mdsBase, codeBase: MBVM.Base, nProcesses: CARDINAL, framePages: CARDINAL, pdaPages: CARDINAL, gftLength: CARDINAL, svSize: CARDINAL, stateVectorCounts: BootStartList.StateVectorCounts ]; simpleDefaults: SimpleValues = [ mdsBase: 512, codeBase: 768, nProcesses: 50, framePages: 10, pdaPages: 1, gftLength: 512, svSize: 20B, stateVectorCounts: [1,1,3,1,1,3,1,1] ]; GetFrameWeight: PUBLIC PROC [index: FrameSizeIndex] RETURNS [weight: CARDINAL] = { RETURN[values.frameWeights[index]]}; SetFrameWeight: PUBLIC PROC [index: FrameSizeIndex, weight: CARDINAL] = { values.frameWeights[index] _ weight}; GetFsiChain: PUBLIC PROC [index: FrameSizeIndex] RETURNS [fsiNext: FrameSizeIndex] = { RETURN[values.fsiChain[index]]}; SetFsiChain: PUBLIC PROC [index: FrameSizeIndex, fsiNext: FrameSizeIndex] = { values.fsiChain[index] _ fsiNext}; AllocateFrames: PUBLIC PROC [size: CARDINAL, single, resident: BOOL] RETURNS [frames: POINTER, inFrameHeap: BOOL] = TRUSTED { pages: CARDINAL; seg: MBVM.DataSeg; IF single THEN RETURN[MB.Alloc[PrincOpsUtils.MakeFsi[size] ! MB.AllocFault => CONTINUE], TRUE]; pages _ PrincOpsUtils.PagesForWords[size]; seg _ MBVM.AllocData[base: MBVM.MDS, pages: pages, dir: up]; frames _ MBVM.PointerFromSeg[seg]; seg.info.readOnly _ FALSE; IF resident THEN { seg.bootLoaded _ TRUE; seg.info.state _ resident; }; RETURN[frames, FALSE] }; FrameHeapPiece: TYPE = POINTER TO FrameHeapPieceHeader; FrameHeapPieceHeader: TYPE = MACHINE DEPENDENT RECORD [ next(0): FrameHeapPiece, wordsAllocated(1): CARDINAL, -- actually [0..VM.WordsForPages[shortPointerSpan]] wordsInUse(2): CARDINAL, -- assert: wordsInUse MOD 4 = 3 fsiFrame(3): ARRAY [0..0) OF --WORD-- FsiFrame]; -- must be at 3 MOD 4 boundary. FsiFrame: TYPE = MACHINE DEPENDENT RECORD [ fsi(0): AnyFrameSizeIndex, -- must be at 3 MOD 4 boundary. frame(1): local Frame]; AnyFrameSizeIndex: TYPE = CARDINAL [0..AllocationVectorSize); MarkerType: TYPE = MACHINE DEPENDENT {frame(0), deadSpace(1)}; FrameMarker: TYPE = MACHINE DEPENDENT RECORD [ marker(0): SELECT markerType(0:0..0): MarkerType FROM frame => [fsi(0:1..15): FrameSizeIndex], deadSpace => [count(0:1..15): NAT], -- count does NOT include FrameMarker ENDCASE]; AllocateLocalFrames: PROC = { pieceHeader: --VMInternal.--FrameHeapPieceHeader _ NULL; pieceInVM: --VMInternal.--FrameHeapPiece; piecePages: CARDINAL; localHeapSize: CARDINAL _ 0; seg: MBVM.DataSeg; FOR i: CARDINAL IN FrameSizeIndex DO localHeapSize _ localHeapSize + values.frameWeights[i]*(FrameVec[i]+1); ENDLOOP; piecePages _ MAX[PrincOpsUtils.PagesForWords[localHeapSize], data.framePages]; pieceHeader.next _ NIL; pieceHeader.wordsAllocated _ PrincOpsUtils.WordsForPages[piecePages]; seg _ MBVM.AllocData[base: MBVM.MDS, pages: piecePages, dir: up]; seg.bootLoaded _ TRUE; seg.info _ [FALSE, resident]; TRUSTED { pieceInVM _ MBVM.PointerFromSeg[seg]; pieceHeader.wordsInUse _ DivideAllocationArea[pieceInVM, pieceHeader.wordsAllocated, heapFrames]; MBVM.CopyWrite[from: @pieceHeader, to: pieceInVM, nwords: SIZE[FrameHeapPieceHeader]]; }; }; DivideAllocationArea: PROC [base: POINTER, size: CARDINAL, counts: FrameCounts] RETURNS [wordsUsed: CARDINAL _ 0] = { p: POINTER _ base; origin: POINTER; sum: CARDINAL _ 0; ct: CARDINAL; fw: ARRAY FrameSizeIndex OF CARDINAL; AdjustSize: PROC [words: CARDINAL, markDead: BOOL _ TRUE] = { IF markDead THEN MBVM.Write[p, --VMSideDoor.--FrameMarker[deadSpace[words-1]]]; TRUSTED {p _ p + words}; size _ size - words; }; EnsureQuadWordAlignment: PROC [markDead: BOOL] = { pm4: CARDINAL = LOOPHOLE[p, CARDINAL] MOD 4; IF pm4 ~= 0 THEN AdjustSize[4 - pm4, markDead]; }; Ensure3Mod4Alignment: PROC [markDead: BOOL] = { pm4: CARDINAL = LOOPHOLE[p, CARDINAL] MOD 4; IF pm4 ~= 3 THEN AdjustSize[3 - pm4, markDead]; }; IF size < 4 THEN RETURN; EnsureQuadWordAlignment[markDead: FALSE]; IF size < 4 THEN RETURN; origin _ p; Ensure3Mod4Alignment[markDead: FALSE]; -- allow space for FramePieceHeader FOR i: FrameSizeIndex IN [0..fw.LENGTH) DO sum _ sum + FrameVec[i]*(fw[i] _ values.frameWeights[i]); ENDLOOP; ct _ MAX[size/sum, 1]; WHILE size > FrameVec[0] DO FOR fsi: FrameSizeIndex IN [0..FrameVec.LENGTH) DO frSize: CARDINAL = FrameVec[fsi] + SIZE[FrameMarker]; THROUGH [1..fw[fsi]*ct] UNTIL size < frSize DO AddFrameToAV: PROC = TRUSTED { MBVM.Write[p, FrameMarker[frame[fsi]]]; MBVM.Write[p + SIZE[FrameMarker], MBVM.Read[@AV[fsi]]]; MBVM.Write[@AV[fsi], p + SIZE[FrameMarker]]; }; EnsureLegalForDandelion: PROC = { OPEN PrincOps; offsetInPage: CARDINAL = LOOPHOLE[p, CARDINAL] MOD wordsPerPage; IF offsetInPage = wordsPerPage-SIZE[FrameMarker] THEN AdjustSize[4] ELSE IF offsetInPage = wordsPerPage-SIZE[FrameMarker]-SIZE[local Frame] THEN AdjustSize[8]; }; Ensure3Mod4Alignment[markDead: TRUE]; IF size < frSize THEN EXIT; EnsureLegalForDandelion[]; IF size < frSize THEN EXIT; AddFrameToAV[]; counts[fsi] _ counts[fsi] + 1; TRUSTED {p _ p + frSize}; size _ size - frSize; ENDLOOP; ENDLOOP; FOR i: FrameSizeIndex IN [0..fw.LENGTH-1) DO fw[i] _ MAX[fw[i]/3, 1]; ENDLOOP; ct _ 1; ENDLOOP; TRUSTED {RETURN [p - origin]} }; ReportFrameAllocation: PUBLIC PROC = { loadmap: IO.STREAM = data.loadmap; serendipity: BOOL _ FALSE; FOR i: FrameSizeIndex IN FrameSizeIndex DO IF extraFrames[i] ~= 0 THEN {serendipity _ TRUE; EXIT}; ENDLOOP; loadmap.PutF[ "\NLOCAL FRAMES ALLOCATED%g:\N\N", IO.rope[IF serendipity THEN " (total=(heap+serendipity))" ELSE NIL]]; FOR i: FrameSizeIndex IN FrameSizeIndex DO IF extraFrames[i] = 0 THEN loadmap.PutF["%4d: %d\N", IO.card[i], IO.card[heapFrames[i]]] ELSE loadmap.PutF["%4d: %d (=%d+%d)\N", IO.card[i], IO.card[heapFrames[i]+extraFrames[i]], IO.card[heapFrames[i]], IO.card[extraFrames[i]] ]; ENDLOOP; }; END.  MBMain.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Sandman on 6-Aug-81 15:41:24 Lewis on 17-Sep-81 13:31:13 Levin on January 12, 1984 4:26 pm Russ Atkinson (RRA) March 8, 1985 5:24:23 pm PST Memory initialization av and sd gft Note that the following manipulates only the overhead words. Frame Allocation Someday, we may wish to do the following: [] _ DivideAllocationArea[frames+size, pages*wordsPerPage - size, extraFrames]; The following declarations are shared with VMInternal and VMSideDoor. When VM stabilizes, they should be referenced from there. VMInternal: VMSideDoor: OPEN VMSideDoor; Make sure that the fsi word, overhead, and local 0 are all in the same page. Assert: 'p' MOD 4 = 3 and 'frSize' words are available, beginning at 'p'. Κθ˜codešœ ™ Kšœ Οmœ1™Kšœ žœ˜Kšžœ%žœ˜š œ žœžœž œžœ˜.šœ žœ ž˜5K˜(Kšœžœ %˜JKšžœ˜ ——K˜šŸœžœ˜Kšœ  œžœ˜8Kšœ  œ˜)Kšœ žœ˜Kšœžœ˜Kšœžœ ˜šžœžœžœž˜$K˜GKšžœ˜—Kšœ žœ>˜NKšœžœ˜KšœE˜EKšœžœžœžœ˜AKšœžœ˜Kšœ žœ ˜šžœ˜ Kšœ žœ˜%šœ˜KšœH˜H—Kšžœ6žœ˜VK˜—Kšœ˜K˜—šŸœžœžœžœ˜OKšžœ žœ ˜%Kšœžœ˜Kšœžœ˜Kšœžœ˜Kšœžœ˜ Kšœžœžœžœ˜%š Ÿ œžœ žœ žœžœ˜=Kšžœ žœžœ  œ!˜OKšžœ˜Kšœ˜K˜—šŸœžœ žœ˜2Kš œžœžœžœžœ˜,Kšžœ žœ˜/Kšœ˜—šŸœžœ žœ˜/Kš œžœžœžœžœ˜,Kšžœ žœ˜/Kšœ˜—Kšžœ žœžœ˜Kšœ"žœ˜)Kšžœ žœžœ˜K˜ Kšœžœ #˜Kšžœžœžœž˜*Kšœ9˜9Kšžœ˜—Kšœžœ˜šžœž˜šžœžœžœž˜2Kšœžœžœ˜5šžœžœ ž˜.šŸ œžœžœ˜Kšœ™Kšžœ#˜'Kšžœ žœžœžœ˜7Kšžœžœ žœ˜,K˜—šŸœžœ˜!KšœL™LKšžœ ˜Kš œžœžœžœžœ˜@Kšžœžœžœ˜CKš žœžœžœžœžœ˜[K˜—Kšœžœ˜%Kšžœžœžœ˜K˜Kšžœžœžœ˜KšœJ™JK˜K˜Kšžœ˜K˜Kšžœ˜—Kšžœ˜—Kš žœžœžœžœ žœžœ˜NK˜Kšž˜—Kšžœžœ˜šœ˜K˜——šŸœžœžœ˜&Kšœ žœžœ˜"Kšœ žœžœ˜šžœžœž˜*Kšžœžœžœžœ˜7Kšžœ˜—šœ ˜ Kšœ"˜"Kš žœžœ žœžœžœ˜E—šžœžœž˜*Kšžœžœžœ žœ˜Yšž˜šœ#˜#Kšžœ žœ$˜2Kšžœžœ˜/Kšœ˜——Kšž˜—šœ˜K˜——Kšžœ˜K˜K˜—…—+β>Φ