YggFileInternal.mesa
Copyright Ó 1988 by Xerox Corporation. All rights reserved.
Bob Hagmann November 7, 1988 1:16:16 pm PST
YggFile internal interface.
DIRECTORY
Camelot USING [segmentIdT, tidT],
Mach USING [portT],
Rope USING [ROPE],
YggCamelotSegment USING [SegPort, SegmentUseType],
YggDID USING [DID],
YggDIDMap USING [Run, RunList],
YggFile USING [FileHandle, PageCount, PageNumber];
YggFileInternal: CEDAR DEFINITIONS
= BEGIN
ROPE: TYPE ~ Rope.ROPE;
FileHandle definition
FileHandleRep: TYPE = RECORD [
did: YggDID.DIDNIL,
fileUse: ATOMNIL, -- use of the file (e. g., $contents)
uid: CARD ← 1, -- unique id that are assigned per boot (transient)
sizeInPages: YggFile.PageCount ← 0,
sizeInBytes: INT ← 0,
name: Rope.ROPENIL,  -- human-legible name.
interlock: BOOLEANFALSE,
needBroadcast: BOOLEANFALSE,
runList: YggDIDMap.RunList ← NIL,
modificationList: LIST OF Modification ← NIL -- this list is built by appending, so that parents always preceed their children (this is important!)
];
Modification: TYPE = RECORD [
tid: Camelot.tidT,
mods: LIST OF FileMod
];
ModType: TYPE = {addPages, removePages, delete, setByteSize};
FileMod: TYPE = RECORD [
type: ModType,
run: YggDIDMap.Run, -- for addPages
size: YggFile.PageCount -- for removePages and setByteSize
];
Segment Metadata
PTAllocBitmap: TYPE = LONG POINTER TO AllocBitmap;
AllocBitmap: TYPE = RECORD[SEQUENCE COMPUTED CARD OF AllocWord];
AllocBitmap: TYPE = RECORD[SEQUENCE COMPUTED CARD16 OF AllocWord];
AllocWord: TYPE = MACHINE DEPENDENT RECORD[
SELECT OVERLAID * FROM
card => [card: CARD32],
int => [int: INT32],
pair => [hi, lo: CARD16],
bytes => [hh, hl, lh, ll: BYTE],
bits => [bits: PACKED ARRAY [0..32) OF BOOL],
ENDCASE
];
SegmentMetadataList: TYPE = LIST OF SegmentMetadata;
SegmentMetadata: TYPE = MONITORED RECORD [
segmentId: Camelot.segmentIdT, -- id for segment
port: Mach.portT, -- port for segment
lowSize: CARD32,
segmentUse: YggCamelotSegment.SegmentUseType,
offsetToFirstAllocPage: YggFile.PageCount, -- how big is the preamble before allocatable storage
numberOfPages: YggFile.PageCount, -- number of pages that are allocatable in segment (excludes preamble storage)
freePages: INT, -- number of pages that are completely free (bits off in the shadow bitmap)
rover: YggFile.PageNumber,
DIDMapLogicalPage0: CARD32, -- page number that is page 0 (should be just after the allocation map; 0 means no DID Map)
NextDIDLogicalPage: CARD32, -- page number for where NextDID is stored (0 means no NextDID)
vmAddressForSegmentAllocMap: PTAllocBitmap, -- where in VM is the stable bitmap mapped
vmAddressForShadowAllocMap: PTAllocBitmap -- where in VM is the volatile bitmap mappe
];
SegMetadataList: SegmentMetadataList;
Free page bitmaps
opRun: TYPE = {stableAlloc, stableFree, stableAndVolatileFree, volatileFree};
RunOpsList: TYPE = LIST OF RunOps;
RunOps: TYPE = RECORD[
opOnRun: opRun,
run: YggDIDMap.Run
];
IsUsed: PROC [segment: SegmentMetadataList, page: YggFile.PageNumber] RETURNS [inUse: BOOL];
Test to see if a page is in-use. This test is done under the monitor, but no guarantee is made about how long the result will be true. This flavor of test is for the shadow bitmap.
SetPageUsed: PROC [segment: SegmentMetadataList, page: YggFile.PageNumber, inUse: BOOL] RETURNS [wasInUse: BOOL];
Test to see if a page is in-use, and set it to "inUse". This test is done under the monitor, but no guarantee is made about how long the result will be true. This flavor of operation is for the shadow bitmap.
Alloc: PROC [segment: SegmentMetadataList, first: YggFile.PageNumber,
size, min: YggFile.PageCount, minPage, maxPage: YggFile.PageNumber]
RETURNS [given: YggDIDMap.Run];
Find a logical run marked free in the in-memory bitmap. May be smaller than "size", but is never smaller than "min" if anything is allocated. If given.pages is 0 then no pages allocated. This flavor of allocation is for the shadow bitmap. To make the allocation stable, StableAlloc must be called with the run.
AllocAndFree: PROC [segment: SegmentMetadataList, tid: Camelot.tidT, runOpsList: RunOpsList];
Combines allocate and free from either the in-memory (shadow) bitmap or the disk resident bitmap.
StableAlloc: PROC [segment: SegmentMetadataList, run: YggDIDMap.Run, tid: Camelot.tidT];
Set the disk resident bitmap for this run. The tid is a top level transaction that is trying to commit.
Free: PROC [segment: SegmentMetadataList, run: YggDIDMap.Run];
Mark the logical run free in the in-memory (shadow) bitmap.
StableFree: PROC [segment: SegmentMetadataList, run: YggDIDMap.Run, tid: Camelot.tidT];
Mark the logical run free in the stable bitmap.
ClearLatches: PROC [segment: SegmentMetadataList, tid: Camelot.tidT];
Drop all locks in the bitmaps.
Global table of file objects
AllocForCreate: PROC RETURNS [YggFile.FileHandle];
Allocate an object, but don't place it in the table.
Insert: PROC [YggFile.FileHandle];
Insert the object into the table (after successful creation).
Lookup: PROC [runList: YggDIDMap.RunList, did: YggDID.DID, fileUse: ATOM] RETURNS [YggFile.FileHandle];
Look-up the [did, fileUse] in the table, inserting if needed.
Global table of file objects
InitializeFile: PROC [segmentList: LIST OF YggCamelotSegment.SegPort] RETURNS [firstTime: BOOL];
Tell file about the segments.
END.