// IfsTelnetDiskStat.bcpl -- IFS system statistics commands
// Copyright Xerox Corporation 1979, 1980, 1981
// Last modified November 22, 1981 10:27 AM by Taft
get "IfsDDMgr.decl"
external
[
// outgoing procedures
DiskStatistics
// incoming procedures
Puts; Ws; PutTemplate; DoubleAdd; DoubleSubtract; Zero; Div32x16
LockDD; UnlockDD; ReadDDPage; Lock; Unlock
// incoming statics
dsp; driveTab; openLock
]
//---------------------------------------------------------------------------
let DiskStatistics() be
//---------------------------------------------------------------------------
[
Ws("*n*nDisk statistics (cumulative):")
Ws("*nUn File system Transfers Err ECC Fix Rest Unrec BTerr Free")
for drive = 0 to nDrives-1 do for fs = 0 to 1 do
[
// Don't bother locking openLock here, because the worst possible effect
// of having the disk disappear out from under us is that we print some
// garbage numbers.
let dte = lv driveTab>>DriveTab↑drive
let disk = dte>>DTE.disk↑fs
if disk ne 0 then
[
PutTemplate(dsp, (dte>>DTE.disk↑1 eq 0? "*n$O ", "*n$O/$O "),
drive, fs)
let ifs = dte>>DTE.ifs
test ifs ne 0
ifso
[
Ws(ifs>>IFS.id)
for i = 1 to 10-ifs>>IFS.id>>String.length do Puts(dsp, $*s)
for u = 0 to nDisks-1 do
if disk eq ifs>>IFS.lpdt↑u then PutTemplate(dsp, "($2O)", u)
]
ifnot
Ws("Not IFS ")
PutTemplate(dsp, "$10ED$6ED$6ED$6ED$6ED$6ED$6ED$7UD",
lv disk>>TFSDSK.nTransfers, lv disk>>TFSDSK.nErrors,
lv disk>>TFSDSK.nECCErrors, lv disk>>TFSDSK.nECCFixes,
lv disk>>TFSDSK.nRestores, lv disk>>TFSDSK.nUnRecov,
lv disk>>TFSDSK.nBTErrors, disk>>TFSDSK.freePages)
]
]
// DiskStatistics (cont'd)
Ws("*n*nDisk drive statistics (since last restart):")
Ws("*nUn Transfers Err ECC /10↑10 bits")
for drive = 0 to nDrives-1 do
[
let dte = lv driveTab>>DriveTab↑drive
// Lock out changes to disk configuration -- needed because calling
// ReadDDPage on a nonexistent disk would be disasterous.
Lock(openLock)
test dte>>DTE.ifs ne 0
ifso
[
let nTransfers = vec 6; Zero(nTransfers, 6)
let nErrors, nECCErrors = nTransfers+2, nTransfers+4
for fs = 0 to 1 do
[
let disk = dte>>DTE.disk↑fs
if disk ne 0 then
[
let ddMgr = disk>>TFSDSK.ddMgr
DoubleAdd(nTransfers, lv disk>>TFSDSK.nTransfers)
DoubleAdd(nErrors, lv disk>>TFSDSK.nErrors)
DoubleAdd(nECCErrors, lv disk>>TFSDSK.nECCErrors)
LockDD(ddMgr, disk)
let initialKD = lv (ReadDDPage(ddMgr, disk, 1))>>IFSKD.initialKD
DoubleSubtract(nTransfers, lv initialKD>>TFSKD.nTransfers)
DoubleSubtract(nErrors, lv initialKD>>TFSKD.nErrors)
DoubleSubtract(nECCErrors, lv initialKD>>TFSKD.nECCErrors)
UnlockDD(ddMgr, disk)
]
]
Unlock(openLock)
PutTemplate(dsp, "*n$O$11ED$6ED$6ED", drive, nTransfers,
nErrors, nECCErrors)
// To compute ECC errors per 10↑10 bits (T-300 spec):
// rate = (nECCErrors * 10↑10)/(nTransfers * 2↑14)
// where 2↑14 is the number of bits transferred per page.
// 10↑10 is approximately equal to 2↑33, so we have:
// rate = nECCErrors/(nTransfers * 2↑-(33-14)) =
// nECCErrors/(nTransfers/2↑19) = (nECCErrors*2↑19)/nTransfers
let rate = vec 1
rate!0, rate!1 = nECCErrors!1, 0 // God help us if more than 2↑16 errors
Div32x16(nTransfers, 8) // to compute (nECCErrors*2↑16)/(nTransfers*2↑-3)
while nTransfers!0 ne 0 do // double right shift the hard way
[ Div32x16(rate, 2); Div32x16(nTransfers, 2) ]
Div32x16(rate, nTransfers!1) // now denominator < 2↑16
PutTemplate(dsp, "$7ED", rate)
]
ifnot Unlock(openLock)
]
]