-- File: PupBootServerTool.mesa, Last Edit: HGM February 17, 1981 4:51 AM -- Please don't forget to update the herald... DIRECTORY Process USING [Yield], Space USING [nullHandle], Time USING [Current], Format USING [], -- Needed by Put.Date and such FormSW USING [ ClientItemsProcType, ProcType, AllocateItemDescriptor, newLine, sameLine, Display, FindItem, CommandItem, BooleanItem, StringItem], Menu USING [Create, Handle, Instantiate, ItemObject, MCRType], MsgSW USING [Post], Put USING [Char, CR, Date, Decimal, Line, LongNumber, Number, Text], Tool USING [Create, MakeSWsProc, MakeMsgSW, MakeFileSW, MakeFormSW], ToolWindow USING [TransitionProcType], UserInput USING [GetDefaultWindow, userAbort], Window USING [Handle, Place], Clock USING [TimeIsKnown], StatsDefs USING [StatGetCounter], BootServerDefs USING [ BootFile, timeNotKnown, PupBootServerOn, PupBootServerOff, StartProbingForBootFiles, StartLongRangeProbingForBootFiles, EnumerateBootTable, msg, slowBooteeHost, slosheeHost, slowBootFileName, slosheeFileName, running, slowBooting, probing, sloshing, statFileSent, statBootDir, statMicrocodeBooted, statFileSentSlow, statBootNew]; PupBootServerTool: MONITOR IMPORTS Space, Process, Time, FormSW, Menu, MsgSW, Put, Tool, UserInput, Clock, StatsDefs, BootServerDefs EXPORTS BootServerDefs = BEGIN OPEN BootServerDefs; form, log: PUBLIC Window.Handle ← NIL; Init: PROCEDURE = BEGIN [] ← Tool.Create[ name: "Boot Server of February 17, 1981"L, makeSWsProc: MakeSWs, clientTransition: ClientTransition, initialState: inactive]; Menu.Instantiate[menu, UserInput.GetDefaultWindow[]]; END; UpdatePicture: PUBLIC PROCEDURE = BEGIN IF form = NIL THEN RETURN; FormSW.FindItem[form, startIX].flags.invisible ← running; FormSW.FindItem[form, stopIX].flags.invisible ← ~running; FormSW.FindItem[form, probeIX].flags.invisible ← ~running; FormSW.FindItem[form, longIX].flags.invisible ← ~running; FormSW.FindItem[form, printIX].flags.invisible ← ~running; FormSW.Display[form]; END; PrintBootInfo: PROCEDURE [wh: Window.Handle] = BEGIN PrintHeader[wh, "Boot Server Statistics:"L]; PrintMaybe[wh, "Boot files sent"L, StatsDefs.StatGetCounter[statFileSent]]; PrintMaybe[ wh, "Boot directory requests"L, StatsDefs.StatGetCounter[statBootDir]]; PrintMaybe[ wh, "Microcode Boots requests"L, StatsDefs.StatGetCounter[ statMicrocodeBooted]]; PrintMaybe[ wh, "Slow boot files sent"L, StatsDefs.StatGetCounter[statFileSentSlow]]; PrintMaybe[ wh, "New boot files retrieved"L, StatsDefs.StatGetCounter[statBootNew]]; END; PrintMaybe: PROCEDURE [wh: Window.Handle, s: STRING, n: LONG INTEGER] = BEGIN IF n = 0 THEN RETURN; Put.Text[wh, s]; Put.Text[wh, ": "L]; Put.LongNumber[wh, n, [10, FALSE, TRUE, 0]]; Put.CR[wh]; END; PrintBootFileTable: PROCEDURE [wh: Window.Handle] = BEGIN PrintOne: PROCEDURE [bf: BootServerDefs.BootFile] = BEGIN pages ← pages + bf.pages; IF bf.space # Space.nullHandle THEN pagesInVM ← pagesInVM + bf.pages; IF UserInput.userAbort THEN RETURN; Put.Number[wh, bf.code, [8, FALSE, TRUE, 6]]; IF bf.space # Space.nullHandle THEN Put.Char[wh, '*] ELSE Put.Char[wh, ' ]; Put.Number[wh, bf.pages, [10, FALSE, TRUE, 5]]; Put.LongNumber[wh, bf.count, [10, FALSE, TRUE, 6]]; IF bf.count = 0 THEN Put.Text[wh, " "L] ELSE Put.LongNumber[wh, bf.ms/bf.count, [10, FALSE, TRUE, 6]]; IF bf.inTransit THEN Put.Text[wh, "T "L] ELSE Put.Text[wh, " "L]; SELECT TRUE FROM bf.unknown => Put.Text[wh, "Not on this disk "L]; (bf.create = BootServerDefs.timeNotKnown) => Put.Text[wh, "Unknown "L]; ENDCASE => Put.Date[wh, bf.create, dateTime]; Put.Text[wh, " "L]; Put.Text[wh, bf.fileName]; Put.CR[wh]; DoSomeYields[]; END; pages, pagesInVM: CARDINAL ← 0; Put.CR[wh]; PrintHeader[wh, "Boot File Table:"L]; Put.Line[wh, " Code Pgs Count AvgMs Create Time FileName"L]; EnumerateBootTable[PrintOne]; IF pagesInVM # 0 THEN BEGIN Put.Decimal[wh, pagesInVM]; Put.Text[wh, " out of "L]; Put.Decimal[wh, pages]; Put.Line[wh, " pages are mapped into VM."L]; END; END; PrintHeader: PROCEDURE [wh: Window.Handle, s: STRING] = BEGIN Put.CR[wh]; Put.Date[wh, Time.Current[], dateTime]; Put.Text[wh, " "L]; Put.Line[wh, s]; END; DoSomeYields: PROCEDURE = BEGIN THROUGH [0..100) DO Process.Yield[]; ENDLOOP; END; Start: FormSW.ProcType = BEGIN PupBootServerOn[]; END; Stop: FormSW.ProcType = BEGIN PupBootServerOff[]; END; ProbeCommand: FormSW.ProcType = BEGIN IF msg # NIL THEN SELECT TRUE FROM probing => MsgSW.Post[msg, "Already probing for new Boot files."L]; sloshing => MsgSW.Post[msg, "Currently sloshing a new Boot file."L]; ~Clock.TimeIsKnown[] => MsgSW.Post[msg, "Time not valid -- Boot probes would be ignored."L]; ENDCASE => MsgSW.Post[msg, "Probing for new Boot files."L]; StartProbingForBootFiles[]; END; LongRangeProbeCommand: FormSW.ProcType = BEGIN IF msg # NIL THEN SELECT TRUE FROM probing => MsgSW.Post[msg, "Already probing for new Boot files."L]; sloshing => MsgSW.Post[msg, "Currently sloshing a new Boot file."L]; ~Clock.TimeIsKnown[] => MsgSW.Post[msg, "Time not valid -- Boot probes would be ignored."L]; ENDCASE => MsgSW.Post[msg, "Probing for new Boot files."L]; StartLongRangeProbingForBootFiles[]; END; PrintInfo: FormSW.ProcType = BEGIN PrintBootInfo[log]; END; PrintTable: FormSW.ProcType = BEGIN PrintBootFileTable[log]; END; MakeSWs: Tool.MakeSWsProc = BEGIN msg ← Tool.MakeMsgSW[window: window, lines: 5]; form ← Tool.MakeFormSW[window: window, formProc: MakeForm]; log ← Tool.MakeFileSW[window: window, name: "BootServer.log$"L]; Menu.Instantiate[menu, log]; END; menu: Menu.Handle = Menu.Create[DESCRIPTOR[items], "Booter", TRUE]; items: ARRAY [0..1] OF Menu.ItemObject ← [["Info", DoMenu], ["Table", DoMenu]]; infoMx: CARDINAL = 0; tableMx: CARDINAL = 1; DoMenu: Menu.MCRType = BEGIN IF window # log THEN window ← NIL; -- Great window in the sky SELECT index FROM infoMx => PrintBootInfo[window]; tableMx => PrintBootFileTable[window]; ENDCASE => ERROR; END; startIX: CARDINAL = 0; stopIX: CARDINAL = 1; probeIX: CARDINAL = 2; longIX: CARDINAL = 3; printIX: CARDINAL = 6; MakeForm: FormSW.ClientItemsProcType = BEGIN booteePlace: Window.Place = [7*15, FormSW.sameLine]; bootFilePlace: Window.Place = [7*35, FormSW.sameLine]; nParams: CARDINAL = 13; items ← FormSW.AllocateItemDescriptor[nParams]; items[0] ← FormSW.CommandItem[ tag: "Start"L, proc: Start, place: FormSW.newLine, invisible: running]; items[1] ← FormSW.CommandItem[ tag: "Stop"L, proc: Stop, place: FormSW.newLine, invisible: ~running]; items[2] ← FormSW.CommandItem[ tag: "Probe"L, proc: ProbeCommand, invisible: ~running]; items[3] ← FormSW.CommandItem[ tag: "LongRangeProbe"L, proc: LongRangeProbeCommand, invisible: ~running]; items[4] ← FormSW.BooleanItem[ tag: "Probing"L, switch: @probing, readOnly: TRUE]; items[5] ← FormSW.CommandItem[ tag: "PrintInfo"L, proc: PrintInfo, place: FormSW.newLine]; items[6] ← FormSW.CommandItem[ tag: "PrintTable"L, proc: PrintTable, invisible: ~running]; items[7] ← FormSW.BooleanItem[ tag: "SlowBooting"L, switch: @slowBooting, place: FormSW.newLine, readOnly: TRUE]; items[8] ← FormSW.StringItem[ tag: "SlowBootee"L, string: @slowBooteeHost, place: booteePlace, readOnly: TRUE]; items[9] ← FormSW.StringItem[ tag: "SlowFile"L, string: @slowBootFileName, place: bootFilePlace, readOnly: TRUE]; items[10] ← FormSW.BooleanItem[ tag: "Sloshing"L, switch: @sloshing, place: FormSW.newLine, readOnly: TRUE]; items[11] ← FormSW.StringItem[ tag: "Sloshee"L, string: @slosheeHost, place: booteePlace, readOnly: TRUE]; items[12] ← FormSW.StringItem[ tag: "SloshFile"L, string: @slosheeFileName, place: bootFilePlace, readOnly: TRUE]; RETURN[items, TRUE]; END; ClientTransition: ToolWindow.TransitionProcType = BEGIN IF new = inactive THEN msg ← form ← log ← NIL; END; -- initialization Init[]; BootServerDefs.PupBootServerOn[]; END.