--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: POINTER TO MailboxAlloc.MBXHeader = LOOPHOLE[page, POINTER] + base;
IF initMBX OR initHeap THEN
BEGIN header.first ← header.free; VMDefs.MarkStartWait[page]; END;
IF header.first # header.free THEN
BEGIN
buffer: DESCRIPTOR FOR ARRAY OF ObjectDirDefs.ObjectNumber;
index: CARDINAL;
rName: BodyDefs.RName =
LOOPHOLE[page, 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: POINTER TO MailboxAlloc.MBXHeader =
LOOPHOLE[otherP, 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.