DIRECTORY BcdDefs USING [MTHandle], BootStartList USING [StateVectorCounts], CPSwapDefs USING [SwapInfo], IO USING [card, PutF, rope, STREAM], MB USING [Alloc, AllocFault, BHandle, EnumerateNoTrapModules, Handle, WartFrame], MBVM USING [ AllocData, AllocMDSData, Base, CopyRead, CopyWrite, DataSeg, LongCopyWrite, LongPointerFromSeg, LongWrite, MDS, PointerFromSeg, Read, Write], PrincOps USING [ AllocationVectorSize, AV, Byte, ControlLink, Frame, FrameCodeBase, FrameSizeIndex, FrameVec, GFT, GFTIndex, GFTItem, GlobalFrame, GlobalFrameHandle, LargeReturnSlot, MainBodyIndex, PDABase, Priority, ProcessDataArea, ProcessStateBlock, SD, sGFTLength, SpecialReturnSlot, wordsPerPage], PrincOpsUtils USING [PagesToWords, WordsToPages], RuntimeInternal USING [MakeFsi], Time USING [Packed]; MBMain: PROGRAM IMPORTS IO, MB, MBVM, PrincOpsUtils, RuntimeInternal EXPORTS MB = BEGIN OPEN PrincOps; BYTE: TYPE = 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.WordsToPages[ data.nProcesses*(SIZE[ProcessStateBlock]+1) + words + SIZE[ProcessDataArea]], data.pdaPages ]; seg _ MBVM.AllocData[base: 256, pages: data.pdaPages, dir: up]; SetReservedSegBits[seg]; pda _ MBVM.LongPointerFromSeg[seg]; FOR i IN [0..data.pdaPages*wordsPerPage) DO MBVM.LongWrite[pda+i, 0]; ENDLOOP; MBVM.LongCopyWrite[ from: @data.buildTime, to: @LOOPHOLE[@pda.available, LONG POINTER TO CPSwapDefs.SwapInfo].availableB, nwords: SIZE[Time.Packed] ]; }; InitializeMDS: PROC = { 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.WordsToPages[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] = { 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] = { 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] = { 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] = { pages: CARDINAL; seg: MBVM.DataSeg; IF single THEN RETURN[MB.Alloc[RuntimeInternal.MakeFsi[size] ! MB.AllocFault => CONTINUE], TRUE]; pages _ PrincOpsUtils.WordsToPages[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.PagesToWords[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.WordsToPages[localHeapSize], data.framePages]; pieceHeader.next _ NIL; pieceHeader.wordsAllocated _ PrincOpsUtils.PagesToWords[piecePages]; seg _ MBVM.AllocData[base: MBVM.MDS, pages: piecePages, dir: up]; seg.bootLoaded _ TRUE; seg.info _ [FALSE, resident]; 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]]]; 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 = { 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; 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; 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 Edited by Sandman on 6-Aug-81 15:41:24 Edited by Lewis on 17-Sep-81 13:31:13 Edited by Levin on June 20, 1983 2:01 pm Memory initialization fill in build time (used by Runtime.GetBuildTime) 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'. Êþ˜Jšœ ™ Jšœ&™&Jšœ%™%Jšœ(™(J˜šÏk ˜ Jšœœ ˜Jšœœ˜(Jšœ œ ˜Jšœœœ˜$JšœœI˜Qšœœ˜ Jšœkœ˜—šœ œ˜JšœœEœŒœ/˜—Jšœœ˜1Jšœœ ˜ Jšœœ ˜J˜—šœ˜Jšœœœœ!˜5Jšœœ˜ J˜—Jš˜J˜Jšœ ˜J˜Jšœœ˜J˜Jš œœœœœ˜7Jš œ œœœœ˜9J˜Jšœœ œ˜J˜Jšœœ œ˜šœœœ˜Jšœœœœœœœœ˜DJšœ œœœœœœœ˜A—˜J˜MJ˜QJ˜—Jšœ'œ˜+Jšœ œœ˜(Jš œœœœœ˜9J˜šÏnœœœœ ˜(J˜ Jšœ œ˜Jšœ œœ˜+Jšœœœ˜,šœ œ ˜Jšœœœ˜(Jšœ˜—Jšœœœ˜Jšœœœ˜Jšœ œœ˜Jšœ œœ˜Jšœœœ˜Jšœ œœ˜Jšœ œœ˜Jšœ˜J˜—šž œœœ˜Jšœ œ˜Jšœ œ˜Jšœœ˜Jšœ˜ Jšœ˜J˜J˜—Jšœ™J˜šž œœœ˜J˜Jšœ œ%˜7J˜J˜J˜J˜—šžœœ˜Jšœœ˜ šœœ ˜šœœœ˜2J˜@—Jšœ˜—šœœ˜šœœœœ˜,J˜7—šœœœœ˜(J˜/—Jšœ˜—šœœœœ˜(J˜*—šœœœœ˜&J˜&—šœœœœ˜'J˜(—šœœœœ˜'J˜(—šœœœœ˜)J˜,—šœœœœ˜)J˜,—˜J˜——šžœœ˜Jšœœ ˜Jšœœ˜(J˜Jšœœ!˜+J˜Jšœœ!˜+J˜J˜J˜—šžœœœ ˜.Jšœ œ ˜Jšœ˜Jšœ˜J˜—šžœœ˜Jšœœ ˜Jšœ ˜ Jšœœ˜ Jšœœ˜šœœ œ˜J˜6Jšœ˜—šœœ˜˜Jšœœ!œ˜MJ˜ J˜——Jšœœ5˜?J˜Jšœœ˜#šœœ!œ˜,Jšœ˜Jšœ˜—Jšœ1™1šœ˜J˜Jš œœœœœ!˜NJšœœ ˜Jšœ˜—šœ˜J˜——šž œœ˜Jšœ œ˜Jšœœ ˜Jšœœ˜ Jšœ ™ Jšœœ˜Jšœœ'˜DJš œœœœœœ˜CJ˜ Jšœ™Jšœ5œ ˜DJšœœ/˜LJšœœ˜š œœœœ ˜1Jšœ˜Jšœ˜—Jšœœ˜,Jšœ˜J˜—šžœœœ˜šœœ˜*Jšœœœ˜3Jšœœ%˜.Jšœ˜—Jšœ˜"Jšœ ˜$Jšœ˜J˜—šžœœœ˜!š žœœœ!œœ˜EJ˜,J˜Jšœ+œ˜DJšœ œ˜Jšœ,œ˜EJšœœ˜ Jšœ˜—Jšœ˜ Jšœ˜J˜—šžœœœœ˜=Jšœœ ˜&J˜Jšœ<™Jšœ œ˜Jšœ%œ˜š œ œœ œœ˜.šœ œ ˜5J˜(JšœœŸ%˜JJšœ˜ ——J˜šžœœ˜Jšœ Ÿœœ˜8Jšœ Ÿœ˜)Jšœ œ˜Jšœœ˜Jšœœ ˜šœœœ˜$J˜GJšœ˜—Jšœ œ=˜MJšœœ˜JšœD˜DJšœœœœ˜AJšœœ˜Jšœ œ ˜Jšœ œ˜%šœ˜JšœH˜H—Jšœ6œ˜VJšœ˜J˜—šžœœœœ˜OJšœ œ ˜%Jšœœ˜Jšœœ˜Jšœœ˜Jšœœ˜ Jšœœœœ˜%š ž œœ œ œœ˜=Jšœ œœ Ÿœ!˜OJšœ˜Jšœ˜J˜—šžœœ œ˜2Jš œœœœœ˜,Jšœ œ˜/Jšœ˜—šžœœ œ˜/Jš œœœœœ˜,Jšœ œ˜/Jšœ˜—Jšœ œœ˜Jšœ"œ˜)Jšœ œœ˜J˜ JšœœŸ#˜Kšœœœ˜*Jšœ9˜9Jšœ˜—Jšœœ˜šœ˜šœœœ˜2Jšœœœ˜5šœœ ˜.šž œœ˜Jšœ™Jšœ#˜'Jšœ œœœ˜7Jšœœ œ˜,J˜—šžœœ˜!JšœL™LJšœ ˜Jš œœœœœ˜@Jšœœœ˜CJš œœœœœ˜[J˜—Jšœœ˜%Jšœœœ˜J˜Jšœœœ˜JšœJ™JJ˜J˜J˜J˜Jšœ˜—Jšœ˜—Jš œœœœ œœ˜NJ˜Jš˜—Jšœ ˜šœ˜J˜——šžœœœ˜&Jšœ œœ˜"Jšœ œœ˜šœœ˜*Jšœœœœ˜7Jšœ˜—šœ ˜ Jšœ"˜"Jš œœ œœœ˜E—šœœ˜*Jšœœœ œ˜Yš˜šœ#˜#Jšœ œ$˜2Jšœœ˜/Jšœ˜——Jš˜—šœ˜J˜——Jšœ˜J˜J˜—…—,\?D