<> <> <> DIRECTORY Commander, CommandTool, File, Graphics, GraphicsOps, PrincOpsUtils USING[ LongCopy ], Process USING[ Detach, Pause, SecondsToTicks ], Rope USING[ Concat, Equal, ROPE ], ViewerClasses, ViewerOps, VolumeFormat USING[ VAMObject ], VM, VMSideDoor USING[ vmPages ]; ShowVAM: CEDAR PROGRAM IMPORTS Commander, CommandTool, File, Graphics, GraphicsOps, PrincOpsUtils, Process, Rope, ViewerOps, VM, VMSideDoor = BEGIN MyData: TYPE = REF MyDataRec; MyDataRec: TYPE = RECORD[ volume: File.Volume, bitmap: GraphicsOps.BitmapRef _ NIL ]; myClass: ViewerClasses.ViewerClass = NEW[ViewerClasses.ViewerClassRec _ [ flavor: $ShowVAM, paint: MyPaint, init: MyInit, icon: tool ] ]; VMName: Rope.ROPE = "VM"; Style: TYPE = { VM, VAM }; MyInit: ViewerClasses.InitProc --[self: Viewer]-- = BEGIN data: MyData _ NARROW[self.data]; style: Style = IF Rope.Equal[self.name, VMName, FALSE] THEN VM ELSE VAM; width: CARDINAL = 512; <> size: INT = IF style = VM THEN VMSideDoor.vmPages ELSE MIN[ File.GetVolumePages[data.volume].size, LONG[815]*15*28]; data.bitmap _ GraphicsOps.NewBitmap[width, (size+width-1)/width]; ViewerOps.SetOpenHeight[self, data.bitmap.height+1]; TRUSTED{ Process.Detach[IF style = VM THEN FORK VMFiller[self] ELSE FORK VAMFiller[self]] }; END; MyPaint: ViewerClasses.PaintProc --[self: Viewer, context: Graphics.Context, whatChanged: REF ANY, clear: BOOL]-- = BEGIN data: MyData = NARROW[self.data]; Graphics.SetCP[context, self.cw/2 - data.bitmap.width/2, data.bitmap.height+1]; GraphicsOps.DrawBitmap[ self: context, bitmap: data.bitmap, w: data.bitmap.width, h: data.bitmap.height]; END; VMFiller: PROC[self: ViewerClasses.Viewer] = TRUSTED BEGIN data: MyData = NARROW[self.data]; size: INT = VMSideDoor.vmPages; UNTIL self.destroyed DO IF NOT self.iconic THEN BEGIN word: LONG POINTER TO PACKED ARRAY [0..16) OF BOOL _ LOOPHOLE[data.bitmap.base]; page: INT _ 0; WHILE page < size DO FOR i: CARDINAL IN [0..16) DO word[i] _ VM.State[page].dataState # none; page _ page+1; ENDLOOP; word _ LOOPHOLE[word+1]; ENDLOOP; ViewerOps.PaintViewer[self, client]; END; Process.Pause[Process.SecondsToTicks[5]]; ENDLOOP; END; VAMFiller: PROC[self: ViewerClasses.Viewer] = TRUSTED BEGIN data: MyData = NARROW[self.data]; vamFile: File.Handle = File.Open[data.volume, File.GetRoot[data.volume, VAM].fp]; filePages: INT = File.Info[vamFile].size; fileWords: INT = File.wordsPerPage * filePages; interval: VM.Interval = VM.Allocate[VM.PagesForWords[fileWords]]; buffer: LONG POINTER TO VolumeFormat.VAMObject = VM.AddressForPageNumber[interval.page]; UNTIL self.destroyed DO IF NOT self.iconic THEN BEGIN File.Read[file: vamFile, from: [0], to: buffer, nPages: filePages]; PrincOpsUtils.LongCopy[from: @buffer[0], to: LOOPHOLE[data.bitmap.base], nwords: data.bitmap.raster * data.bitmap.height]; ViewerOps.PaintViewer[self, client]; END; Process.Pause[Process.SecondsToTicks[5]]; ENDLOOP; VM.Free[interval]; END; ShowVAMProc: Commander.CommandProc = { <<[exec: ExecHandle, clientData: REF ANY _ NIL] RETURNS[ok: BOOLEAN _ TRUE]>> argv: CommandTool.ArgumentVector; volume: File.Volume; volumeName: Rope.ROPE; argv _ CommandTool.Parse[cmd: cmd ! CommandTool.Failed => { msg _ errorMsg; CONTINUE; }]; IF argv = NIL THEN GOTO Failed; IF argv.argc = 1 THEN { volume _ File.SystemVolume[]; volumeName _ File.GetVolumeName[volume]; } ELSE { IF argv.argc # 2 THEN GOTO Usage; volume _ File.FindVolumeFromName[argv[1]]; volumeName _ argv[1]; }; IF volume = NIL THEN GOTO NoVolume; [] _ ViewerOps.CreateViewer[ flavor: myClass.flavor, info: [column: left, iconic: FALSE, data: NEW[MyDataRec _ [volume: volume]], name: Rope.Concat["VAM for ", volumeName ]] ]; EXITS Failed => RETURN[$Failure, msg]; Usage => RETURN[$Failure, " Usage: ShowVAM volumename\n"]; NoVolume => RETURN[$Failure, " No such volume\n"]; }; ShowVMProc: Commander.CommandProc = { <<[exec: ExecHandle, clientData: REF ANY _ NIL] RETURNS[ok: BOOLEAN _ TRUE]>> [] _ ViewerOps.CreateViewer[ flavor: myClass.flavor, info: [column: left, iconic: FALSE, data: NEW[MyDataRec _ [volume: File.SystemVolume[]]], name: VMName ] ]; }; ViewerOps.RegisterViewerClass[flavor: myClass.flavor, class: myClass]; Commander.Register[key: "ShowVAM", proc: ShowVAMProc, doc: "Show a viewer with a bitmap of the VAM (volume allocation map) of the given logical volume ('Cedar' if omitted)"]; Commander.Register[key: "ShowVM", proc: ShowVMProc, doc: "Show a viewer with a bitmap of the VM (virtual memory)"]; END. <> <> <> <<>> <> <> <> <<>> <<>>