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; FileHandleRep: TYPE = RECORD [ did: YggDID.DID _ NIL, fileUse: ATOM _ NIL, -- 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.ROPE _ NIL, -- human-legible name. interlock: BOOLEAN _ FALSE, needBroadcast: BOOLEAN _ FALSE, 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 ]; PTAllocBitmap: TYPE = LONG POINTER TO AllocBitmap; 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; 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]; SetPageUsed: PROC [segment: SegmentMetadataList, page: YggFile.PageNumber, inUse: BOOL] RETURNS [wasInUse: BOOL]; Alloc: PROC [segment: SegmentMetadataList, first: YggFile.PageNumber, size, min: YggFile.PageCount, minPage, maxPage: YggFile.PageNumber] RETURNS [given: YggDIDMap.Run]; AllocAndFree: PROC [segment: SegmentMetadataList, tid: Camelot.tidT, runOpsList: RunOpsList]; StableAlloc: PROC [segment: SegmentMetadataList, run: YggDIDMap.Run, tid: Camelot.tidT]; Free: PROC [segment: SegmentMetadataList, run: YggDIDMap.Run]; StableFree: PROC [segment: SegmentMetadataList, run: YggDIDMap.Run, tid: Camelot.tidT]; ClearLatches: PROC [segment: SegmentMetadataList, tid: Camelot.tidT]; AllocForCreate: PROC RETURNS [YggFile.FileHandle]; Insert: PROC [YggFile.FileHandle]; Lookup: PROC [runList: YggDIDMap.RunList, did: YggDID.DID, fileUse: ATOM] RETURNS [YggFile.FileHandle]; InitializeFile: PROC [segmentList: LIST OF YggCamelotSegment.SegPort] RETURNS [firstTime: BOOL]; END. HYggFileInternal.mesa Copyright ำ 1988 by Xerox Corporation. All rights reserved. Bob Hagmann November 7, 1988 1:16:16 pm PST YggFile internal interface. FileHandle definition Segment Metadata AllocBitmap: TYPE = RECORD[SEQUENCE COMPUTED CARD OF AllocWord]; Free page bitmaps 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. 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. 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. Combines allocate and free from either the in-memory (shadow) bitmap or the disk resident bitmap. Set the disk resident bitmap for this run. The tid is a top level transaction that is trying to commit. Mark the logical run free in the in-memory (shadow) bitmap. Mark the logical run free in the stable bitmap. Drop all locks in the bitmaps. Global table of file objects Allocate an object, but don't place it in the table. Insert the object into the table (after successful creation). Look-up the [did, fileUse] in the table, inserting if needed. Global table of file objects Tell file about the segments. สK˜codešœ™Kšœ<™Kšœ;™;K™—šก œœG˜WKšœ/™/K™—šก œœ3˜EKšœ™—K˜—šœ™šกœœœ˜2K™4—K˜šกœœ˜"K™=—K˜š กœœ*œ œœ˜gKšœ=™=K˜——šœ™šกœœœœ6˜`K™—˜K˜——K˜Kšœ˜Kšฯr™K™—…—–)