-- Copyright (C) 1982, 1984 by Xerox Corporation. All rights reserved. --Transport Mechanism Filestore - Mailbox restart -- -- MailboxRestart.mesa -- Andrew Birrell 10-Sep-82 16:37:56 -- -- Hankins 30-Jul-84 15:36:51 Klamath update (MailboxAlloc imports) DIRECTORY BitMapDefs USING [Create, Set], BodyDefs USING [oldestTime, RName, Timestamp], BTreeDefs USING [CreateAndInitializeBTree, NullProc], MailboxAlloc USING [ archiver, changeInTree, conflictMap, findInTree, getBodyObj, handle, lockMap, lookAhead, mailboxContents, mailboxes, MBXHeader, nextVirginPage, pageMap, readPostmark, tree, TreeRec], ObjectDirDefs USING [noObject, ObjectNumber, RestartObject], RestartDefs, --EXPORT only-- VMDefs USING [ OpenFile, Page, ReadPage, Release, MarkStartWait, PageIndex, PageNumber, GetFileLength]; MailboxRestart: MONITOR [initHeap: BOOLEAN] IMPORTS BitMapDefs, BTreeDefs, MailboxAlloc, ObjectDirDefs, VMDefs EXPORTS RestartDefs --MailboxRestart-- SHARES MailboxAlloc = BEGIN initMBX: BOOLEAN ← FALSE; maxMBXPages: CARDINAL ← 4000; DuplicatePage: ERROR = CODE; Init: ENTRY PROCEDURE = BEGIN pos: VMDefs.PageNumber; MailboxAlloc.handle ← VMDefs.OpenFile[ options: oldOrNew, name: "MBX.Mailboxes"L, cacheFraction: 0]; MailboxAlloc.lockMap ← BitMapDefs.Create[maxMBXPages]; MailboxAlloc.pageMap ← BitMapDefs.Create[maxMBXPages]; MailboxAlloc.conflictMap ← BitMapDefs.Create[maxMBXPages]; MailboxAlloc.tree ← BTreeDefs.CreateAndInitializeBTree[ fileH: LOOPHOLE[VMDefs.OpenFile[ options: oldOrNew, name: "MBX.BTree", cacheFraction: 10]], initializeFile: TRUE, useDefaultOrderingRoutines: TRUE, isFirstGreaterOrEqual: BTreeDefs.NullProc, areTheyEqual: BTreeDefs.NullProc]; MailboxAlloc.nextVirginPage ← VMDefs.GetFileLength[MailboxAlloc.handle].page; FOR pos IN [0..MailboxAlloc.nextVirginPage) DO BEGIN page: VMDefs.Page = VMDefs.ReadPage[ [MailboxAlloc.handle, pos], MailboxAlloc.lookAhead]; base: VMDefs.PageIndex = FIRST[VMDefs.PageIndex]; header: LONG POINTER TO MailboxAlloc.MBXHeader = LOOPHOLE[page, LONG POINTER] + base; IF initMBX OR initHeap THEN BEGIN header.first ← header.free; VMDefs.MarkStartWait[page]; END; IF header.first # header.free THEN BEGIN buffer: LONG DESCRIPTOR FOR ARRAY OF ObjectDirDefs.ObjectNumber; index: CARDINAL; rName: BodyDefs.RName = LOOPHOLE[page, LONG POINTER] + base + SIZE[MailboxAlloc.MBXHeader]; otherValue: MailboxAlloc.TreeRec = MailboxAlloc.findInTree[rName]; otherN: CARDINAL; oldest: BodyDefs.Timestamp; -- estimate of oldest in mailbox -- timeWantedInThisPage: BOOLEAN; WITH otherV: otherValue SELECT FROM empty => {oldest ← BodyDefs.oldestTime; timeWantedInThisPage ← TRUE}; found => BEGIN otherP: VMDefs.Page = VMDefs.ReadPage[ [MailboxAlloc.handle, otherV.where], 0]; otherH: LONG POINTER TO MailboxAlloc.MBXHeader = LOOPHOLE[otherP, LONG POINTER] + base; otherN ← otherH.number; IF header.number = otherN THEN ERROR DuplicatePage[]; oldest ← otherV.oldest; timeWantedInThisPage ← (otherN > header.number OR oldest = BodyDefs.oldestTime); VMDefs.Release[otherP]; END; ENDCASE => ERROR; BitMapDefs.Set[MailboxAlloc.pageMap, pos]; buffer ← DESCRIPTOR[ page + header.first, (header.free - header.first) / SIZE[ObjectDirDefs.ObjectNumber]]; FOR index IN [0..LENGTH[buffer]) DO IF buffer[index].type = TOC THEN ObjectDirDefs.RestartObject[buffer[index]]; IF buffer[index] # ObjectDirDefs.noObject THEN BEGIN body: ObjectDirDefs.ObjectNumber = MailboxAlloc.getBodyObj[ buffer[index]]; ObjectDirDefs.RestartObject[body]; IF timeWantedInThisPage AND body.type # archived THEN BEGIN oldest ← MailboxAlloc.readPostmark[body]; timeWantedInThisPage ← FALSE; END; END; MailboxAlloc.mailboxContents ← MailboxAlloc.mailboxContents + 1; ENDLOOP; WITH otherV: otherValue SELECT FROM empty => BEGIN MailboxAlloc.changeInTree[ who: rName, where: pos, lock: pos, oldest: oldest]; MailboxAlloc.mailboxes ← MailboxAlloc.mailboxes + 1; END; found => MailboxAlloc.changeInTree[ who: rName, where: IF header.number > otherN THEN pos ELSE otherV.where, lock: IF header.number = 0 THEN pos ELSE otherV.lock, oldest: oldest]; ENDCASE => ERROR; END; VMDefs.Release[page]; END ENDLOOP; END; ArchiverProcess: PROCESS; START MailboxAlloc; Init[]; ArchiverProcess ← FORK MailboxAlloc.archiver[]; END.