!FILE LAST CHANGED ON 15/02/83 ! ******************************************************************* ! * * ! * THE JOURNAL SYSTEM: PACKAGE D * ! * THIS PACKAGE CONTAINS THE ROUTINES THAT GIVE THE * ! * SYSTEM MANAGER THE CONTROL OF SYSTEM STATISTICS * ! * * ! * DESIGNED AND WRITTEN BY JOHN HENSHALL * ! * * ! * JOHN MURISON VERSION: 015 * ! * * ! * * ! ******************************************************************* constinteger kent = 0, ercc = 1 constinteger journalsite = kent !********** SYSTEM ROUTINE SPECS recordformat rf(integer conad, filetype, datastart, dataend) systemroutinespec connect(string (31) file, integer mode, hole, project, record (rf)name r, integername flag) systemroutinespec newgen(string (31) s, t, integername flag) systemroutinespec rename(string (31) file,newfile,integername flag) systemroutinespec destroy(string (31) s, integername flag) systemroutinespec disconnect( string (31) file, integername flag) systemroutinespec outfile(string (31) s, integer size, hole, protection, integername conad, flag) systemintegerfnspec pack date and time(string (8) date, time) systemstringfnspec unpack date(integer packed) systemstringfnspec unpack time(integer packed) !**********EXTERNAL ROUTINE SPECS. externalroutinespec copy(string (255) s) externalroutinespec define(string (255) s) externalroutinespec print help(integer n) externalroutinespec journal analysis(string (255) s) externalroutinespec list(string (255) s) externalroutinespec prompt(string (255) s) externalstringfnspec date externalroutinespec send(string (255) s) !**********ROUTINE AND FUNCTION SPECS. routinespec output queues(string (255)s ) if journalsite = kent then start routinespec consumables analysis(string (255) s) finish routinespec background analysis(string (255) s) routinespec s spaces(integer n) routinespec s newpage routinespec s printstring(string (72) s) routinespec s newlines(integer n) routinespec s write(integer i, j) routinespec s print(integer i, j, real r) externalroutinespec read description(stringname reply) externalroutinespec read prompt reply(stringname reply) externalintegerfnspec s to i(string (255) s) externalstringfnspec intostr(integer value) !**********CONSTANTS. constinteger total devices = 128 !THE MAXIMUM POSSIBLE DEVICES CONNECTED TO EMAS 2900(MUST !BE AN EVEN NUMBER) constinteger nsys = 99 constinteger max users = 3001; ! This no is prime - it needs to be for hashing. !THE MAX USERS POPULATION. CAN BE ALTERED FOR ANY SITE.(MAX POSSIBLE: 16, 383) constinteger block = 4096 !BYTES IN EPAGE. constinteger max terminal lines = 18 !LINES OF OUTPUT ON ENGINEERS TERMINAL constinteger max printer lines = 60 !MAX LINES ON AN OUTPUT(LP) REPORT constinteger on = 1 constinteger off = 0 constinteger match = 1 constinteger no match = 0 constinteger no = 0 constinteger yes = 1 conststring (9) jtxt = "Journal: " !***********OWNS ownstring (255) ns1; ! used in imp9->imp80 translation of ...->(..).. owninteger printer = off owninteger terminal = off !THESE TWO DEFINE WHERE THE OUTPUT IS DIRECTED. owninteger p print = off owninteger t print = off !THESE TWO DRIVE THE OUTPUT IN THE SPECIAL 'S' OUTPUT ROUTINES. owninteger terminal lines =1 owninteger printer lines = 1 owninteger period reporting = off !THIS IS USED WHEN REPORTS BEING MADE UP ARE PERIODIC ACCUMULATION REPORTS !**********EXTERNAL ROUTINES ! ************************************************************* ! ************************************************************* ! ************************************************************* externalroutine output and background analyses(string (255) s) !THIS ROUTINE IS CALLED BY 'JOURNAL ANALYSIS' IN THE AUTOMATIC !ANALYSIS OF SPOOLR FILES WHEN A 30 DAY REPORTING PERIOD HAS BEEN !COMPLETED AND REPORTS ARE REQUIRED. integer flag period reporting=on output queues("") select output(0) if period reporting=on start printstring(jtxt." output queues report failed, leaving rerun") newline printstring(" and background analysis until next run.") newlines(2) return finish printstring(jtxt." output queues report completed.") newline period reporting = on background analysis ("") select output(0) if period reporting=on start printstring(jtxt." background analysis report failed, leaving rerun") newline printstring(" and background analysis until next run.") newlines(2) return finish printstring(jtxt." background analysis completed.") newline destroy("JJ#SPCJOB",flag) if flag#0 start printstring(jtxt." cannot destroy accumulation file, flag: ") write(flag, 2) newline printstring(" Please do the following command manually:") newline printstring(" Command:DESTROY(JJ#SPCJOB)") newline printstring(" This will clear down the accumulations.") newlines(2) finish if journalsite = kent then start period reporting=on consumables analysis("") selectoutput(0) if period reporting = on start printstring(jtxt." consumables report failed, leaving rerun") newline printstring(" and consumables analysis until next run.") newlines(2) return finish printstring(jtxt." consumables analysis completed.") newline destroy("JJ#SPCONS",flag) if flag # 0 then start printstring(jtxt." cannot destroy accumulation file, flag:") write(flag, 1) newline printstring(" please do the following command manually:") newline printstring(" Command:DESTROY(JJ#SPCONS)") newline printstring(" This will clear down the accumulations") newlines(2) finish finish end ; !OF OUTPUT AND BACKGROUND ANALYSES. ! ********************************************************* ! * THE MANAGEMENT SUMMARY CALLS. ! ********************************************************* externalroutine background summary(string (255) s) s="MANFACL:SPOOLR,BACKGROUND SUMMARY" journal analysis(s) end ! ********************************************************** ! ********************************************************* ! ********************************************************* externalroutine background analysis(string (255) s) record (rf) r recordformat f hour table(integer jobs, act cpu, req cpu, pts) record (f hour table)array hour table(0:23) record (f hour table)name hth recordformat f batch table(integer jobs, req cpu, act cpu, pts, wait, elapse) record (f batch table)array batch table(1:15) record (f batch table)name be, bt recordformat f job entry(string (6) user, string (16) device, integer size, mins qd, mins ex, byteinteger fsys) record (f job entry)arrayformat af job entry(1:100000) record (f job entry)arrayname job entry record (f job entry)name je recordformat cjob head f(integer end, start, size, filetype, checksum, datetime, format, sp0, next job slot, max job slots, start date, end date) record (cjob head f)name cjob head integer i, j, k, flag, cat, total entries, n integer hour, htot jobs, htot act cpu real rl string (6) ss string (8) start date, start time, end date, end time connect("JJ#SPCJOB", 0, 0, 0, r, flag) if flag#0 start printstring(jtxt." cannot connect completed-job stats file") newline printstring(" 'JJ#SPCJOB', flag: "); write(flag, 3) newlines(2) disconnect("JWORKFILE", flag); destroy("JWORKFILE", flag) stop finish cjob head == record(r_conad) total entries = cjob head_next job slot-1 start date = unpack date(cjob head_start date) start time = unpack time(cjob head_start date) end date = unpack date(cjob head_end date) end time = unpack time(cjob head_end date) job entry == array(addr(cjob head)+cjob head_start, af job entry) define("STREAM01,JSTATSFILE") select output(1) if total entries=0 start printstring(jtxt." no statistics on output queues collected.") newlines(2) return finish batch table(i)=0 for i=1, 1, 15 hour table(i)=0 for i=0, 1, 23 n = 0 for i=1, 1, total entries cycle je==job entry(i) continue if je_user="JOURNL" or je_device#"BATCH" j=je_size&x'0000FFFF' n = n+1 and continue if (j+10)<je_mins ex&x'FFFF' if j<=600 then cat=((j-1)//60+1) else start cat=11 if j<=900 cat=12 if 900<j<=1200 cat=13 if 1200<j<=3600 cat=14 if j>3600 finish !WE NOW HAVE THE SIZE DIVISION FOR TABLE ENTRY. hour=je_mins qd&x'000000FF' if 0<=hour<=23 start hth == hour table(hour) hth_jobs=hth_jobs+1 hth_req cpu= hth_req cpu+je_size&x'0000FFFF' hth_act cpu= hth_act cpu+je_mins ex&x'0000FFFF' finish be==batch table(cat) be_jobs=be_jobs+1 be_req cpu=be_req cpu+je_size&x'0000FFFF' be_act cpu=be_act cpu+(je_mins ex&x'0000FFFF') be_wait=be_wait+je_size>>16 be_elapse=be_elapse+(je_mins ex>>16) be_pts=be_pts+je_mins qd>>8 repeat if n>0 start newlines(4) write(n,1) printstring(" job(s) used 10 seconds more cpu time than requested.") newline printstring("They have not been included in the following report.") newlines(2) finish bt==batch table(15); ! Element 15 used to accumulate totals. for cat=1, 1, 14 cycle be==batch table(cat) bt_jobs=bt_jobs+be_jobs bt_req cpu=bt_req cpu+be_req cpu bt_act cpu=bt_act cpu+be_act cpu repeat !NOW MAKE UP THE REPORT. newpage printstring("EMAS 2900 Journal System Report on Batch Jobs") newlines(2) printstring(start date."(".start time.") to ") printstring(end date."(".end time.")") newlines(2) if period reporting=on start newlines(10) printstring(" ***********************************************") newlines(1) printstring(" * 30 day accumulation report to be retained *") newlines(1) printstring(" ***********************************************") newlines(2) finish newlines(5) printstring("Requested cpu"); spaces(17) printstring("0 61 121 181 241 301 361 421 ") printstring("481 541 601 901 1201") newline printstring("Seconds for job:"); spaces(9) printstring("To: 60 120 180 240 300 360") printstring(" 420 480 540 600 900 1200") printstring(" 3600 >3600 Total") newline; spaces(25) printsymbol('-') for i=1, 1, 105 newlines(2) printstring("Jobs"); spaces(19); printstring(":") write(batch table(i)_jobs, 6) for i=1, 1, 15 newline; printstring("As % of total jobs :") rl = 100/bt_jobs print(batch table(i)_jobs*rl, 3, 2) for i=1, 1, 15 newlines(2); printstring("CPU seconds requested :") write(batch table(i)_req cpu, 6) for i=1, 1, 15 newline; printstring("CPU seconds used :") write(batch table(i)_act cpu, 6) for i=1, 1, 15 newline; printstring("Used as % of requested :") for i=1, 1, 15 cycle if batch table(i)_req cpu>0 then c rl=(batch table(i)_act cpu/batch table(i)_req cpu)*100 else rl=0 print(rl, 3, 2) repeat newline; printstring("Used as % of total used:") for i=1, 1, 15 cycle if bt_act cpu>0 then c rl=(batch table(i)_act cpu/bt_act cpu)*100 else rl=0 print(rl, 3, 2) repeat newlines(2); printstring("Mean req CPU per job :") for i=1, 1, 15 cycle if batch table(i)_jobs>0 then c rl=batch table(i)_req cpu/batch table(i)_jobs else rl=0 print(rl, 4, 1) repeat newlines(2); printstring("Mean act. CPU per job :") for i=1, 1, 15 cycle if batch table(i)_jobs>0 then c rl=batch table(i)_act cpu/batch table(i)_jobs else rl=0 print(rl, 4, 1) repeat newlines(2); printstring("Mean wait time (mins) :") for i=1, 1, 15 cycle if batch table(i)_jobs>0 then c rl=batch table(i)_wait/batch table(i)_jobs else rl=0 print(rl, 4, 1) repeat newlines(2); printstring("Mean exec time (mins) :") for i=1, 1, 15 cycle if batch table(i)_jobs>0 then c rl=batch table(i)_elapse/batch table(i)_jobs else rl=0 print(rl, 4, 1) repeat newlines(2); spaces(25) printsymbol('-') for i=1, 1, 105 newline newpage htot jobs=0 htot act cpu=0 for i=0, 1, 23 cycle htot jobs=htot jobs+hour table(i)_jobs htot act cpu=htot act cpu+hour table(i)_act cpu repeat newlines(12) spaces(33) printstring("Actual CPU of jobs ending in hour") spaces(22); printstring("Jobs ending in hour") newline spaces(28) printstring("H As % of total actual CPU.") spaces(30); printstring("As % of total jobs.") newline printstring(" JOBS REQ CPU ACT CPU O") newline spaces(28) printstring("U 5 4 3 2 1 ") spaces(9) printstring(" 1 2 3 4 5") newline spaces(28); printstring("R ") printstring("0 ") for i=1, 1, 10 printstring("0") newline; spaces(30) printsymbol('-') for i=1, 1, 101 newline for i=0, 1, 23 cycle write(hour table(i)_jobs, 5) write(hour table(i)_req cpu, 8) write(hour table(i)_act cpu, 8) spaces(3); ss=intostr(i) ss=" ".ss if length(ss)=1 printstring(ss." ") rl=(hour table(i)_act cpu/htot act cpu)*100 j=int pt(rl) j=j+1 if rl-j>=0.5 if j>50 then ss="+" and j=50 else ss="*" spaces(50-j) printstring(ss) for k=1, 1, j printstring("|") rl=(hour table(i)_jobs/htot jobs)*100 j=int pt(rl) j=j+1 if rl-j>=0.5 if j>50 then ss="+" and j=50 else ss="*" printstring(ss) for k=1, 1, j newline repeat select output(0) close stream(1) if period reporting = on then start if journalsite = kent then list("JSTATSFILE,.LP,1") finish send("JSTATSFILE,.LP") disconnect("JWORKFILE", flag) destroy("JWORKFILE", flag) period reporting=off if period reporting=on !IE INDICATE THAT THE REPORTING WAS COMPLETED. end ; ! %external %routine background analysis. externalroutine restore analysis(string (255) s) ! Print out info held in file JJ#VOLRTAB, then clear the file. integer flag, restore entries, restore start date, restore end date, rm25, rm5, i, j, k, range, max realarray rtload, rtrest(0:31) real lcum, rcum ownintegerarray range max(1:5) = 10, 20, 40, 50, 100 ownstring (3)array range val(0:5, 1:5) = c " 0", " 2", " 4", " 6", " 8", " 10", " 0", " 4", " 8", " 12", " 16", " 20", " 0", " 8", " 16", " 24", " 32", " 40", " 0", " 10", " 20", " 30", " 40", " 50", " 0", " 20", " 40", " 60", " 80", "100" record (rf) r integerarray trest, tload(0:31) byteintegerarray page(0:100, 4:35) recordformat f restore table(string (6) tsn, user, byteinteger fsys, integer epages, mins rest wait, mins load wait, mins age) record (f restore table)arrayformat af restore table(1:6000) record (f restore table)arrayname restore table connect("JJ#VOLRTAB", 0, 0, 0, r, flag) if flag#0 start printstring(jtxt."cannot connect restore data file") newline printstring(" 'JJ#VOLRTAB', flag:") write(flag, 3) newlines(2) disconnect("JWORKFILE", flag); destroy("JWORKFILE", flag) stop finish restore table == array(r_conad+x'30', af restore table) restore start date = integer(r_conad+x'24') restore end date = integer(r_conad+x'28') restore entries = integer(r_conad+x'20') define("1,T#RESTFILE") selectoutput(1) ! JJ#VOLRTAB destroyed after analysis. printstring("EMAS 2900 Journal System Report on File Restorations Period: ".unpack date(restore start date)." ".unpack time(restore start date)) printstring(" to ".unpack date(restore end date)." ".unpack time c (restore end date)) newlines(2) printstring("Total number of files restored:"); write(restore entries, 3) newlines(6) return if restore entries=0 for j=4, 1, 35 cycle page(i, j) = ' ' for i=1, 1, 100 repeat string(addr(page(7, 35))) = "Time from restore request" string(addr(page(63, 35))) = string(addr(page(7, 35))) page(7, 35) = ' '; page(63, 35) = ' ' string(addr(page(10, 34))) = "to mag tape loaded" page(10, 34) = ' ' string(addr(page(67, 34))) = "to file restored" page(67, 34) = ' ' page(4, j) = '|' for j=29, -1, 9 page(60, j) = '|' for j=29, -1, 9 page(3, 32) = '%'; page(59, 32) = '%' for i=1, 1, 36 cycle page(4+i, 9) = '-'; page(60+i, 9) = '-' repeat string(addr(page(3, 8))) = " 0 5 10 15 20 25 30(>30)" string(addr(page(59, 8))) = string(addr(page(3, 8))) page(3, 8) = ' '; page(59, 8) = ' ' string(addr(page(15, 4))) = "Time (minutes)" string(addr(page(71, 4))) = string(addr(page(15, 4))) page(15, 4) = ' '; page(71, 4) = ' ' ! Now work out the histogram values from the restore table array. trest(i) = 0 and tload(i) = 0 for i=0, 1, 31 for j=1, 1, restore entries cycle i = restore table(j)_mins load wait i = 31 if i>30 i = 0 if i<0 tload(i) = tload(i)+1 i = restore table(j)_mins rest wait i = 31 if i>30 i = 0 if i<0 trest(i) = trest(i)+1 repeat max = 0 for j=0, 1, 31 cycle max = tload(j) if max<tload(j) max = trest(j) if max<trest(j) repeat i = 100*max//restore entries range = 0 range = range+1 until range max(range)>=i ! We now have the appropriate range for the Y-axis. for j = 29, -4, 9 cycle string(addr(page(0, j))) = range val((j-9)//4, range) string(addr(page(56, j))) = string(addr(page(0, j))) page(56, j) = ' ' repeat rm5 = 5*range max(range)*restore entries//100; rm25 = rm5>>1 for i=0, 1, 31 cycle rtload(i) = 100*tload(i)/restore entries k = (100*tload(i)+rm25)//rm5 page(i+5, j+9) = '*' for j=k, -1, 1 rtrest(i) = 100*trest(i)/restore entries k = (100*trest(i)+rm25)//rm5 page(i+61, j+9) = '*' for j=k, -1, 1 repeat ! Now print out the page array. for j=35, -1, 4 cycle i = 100 i = i-1 while i>0 and page(i, j)=' ' page(0, j) = i spaces(15); printstring(string(addr(page(0, j)))) newline repeat newpage ! Now print out the values already output in histogram form. newlines(4) printstring(" Time || % Mag tape loaded | % Mag tape loaded ||") printstring(" % File restored | % File restored || Time") newline printstring(" (minutes) || (in each minute) | (cumulative) ||") printstring(" (in each minute) | (cumulative) || (minutes)") newline spaces(5); printsymbol('-') for i=6, 1, 110 newlines(2) lcum = 0.0; rcum = 0.0 for i=0, 1, 31 cycle write(i, 9); printstring(" || ") print(rtload(i), 3, 1); printstring(" | ") lcum = lcum+rtload(i) print(lcum, 3, 1); printstring(" || ") print(rtrest(i), 3, 1); printstring(" | ") rcum = rcum+rtrest(i) print(rcum, 3, 1); printstring(" ||") write(i, 5) newline repeat spaces(5); printsymbol('-') for i=6, 1, 110 newlines(3) selectoutput(0); closestream(1) disconnect("T#RESTFILE", flag) disconnect("JJ#VOLRTAB", flag) send("T#RESTFILE") destroy("JJ#VOLRTAB", flag) if flag#0 start printstring(jtxt." cannot destroy accumulation file, flag: ") write(flag, 2) newline printstring(" please do the following command manually:") newline printstring(" DESTROY(JJ#VOLRTAB)") newline printstring(" this will clear down the accumulations.") newlines(2) finish end ; ! Of %externalroutine restore analysis. ! *********************************************************** ! *********************************************************** ! *********************************************************** externalroutine queue description(string (255) s) output queues("DEFINE") end ! ************************************************** ! ************************************************** ! ************************************************** externalroutine output queues(string (255) s) record (rf)r recordformat f dev(integer jobs, kbytes) integerarray fsys map(0:nsys); !IE LINK INTO USER TABLE WORK SPACE. recordformat f user(string (6) user, integer jobs, kbytes, link, record (f dev)array dev(1:total devices)) record (f user)arrayformat af user(1:max users) record (f user)arrayname user record (f user)name up record (f dev)name updj, updk recordformat f s unit(integer jobs, kbytes, mins qd, mins ex) recordformat f dev table(string (16) device, integer jobs, kbytes, record (f s unit)array s unit(1:6)) record (f s unit)name dtjsuk record (f dev table)array dev table(1:total devices) record (f dev table)name dti, dtj recordformat f job entry(string (6) user, string (16) device, integer size, mins qd, mins ex, byteinteger fsys) record (f job entry)arrayformat af job entry(1:100000) record (f job entry)arrayname job entry record (f job entry)name jei recordformat cjob head f(integer end, start, size, filetype, checksum, datetime, format, sp0, next job slot, max job slots, start date, end date) record (cjob head f)name cjob head recordformat f tots(integer jobs, kbytes) record (f tots)array tots(1:total devices, 0:43) recordformat f dev descriptors(string (16) dev, string (32) description) record (f dev descriptors)arrayformat af dev descriptors c (1:total devices) record (f dev descriptors)arrayname dev descriptors integername descriptor count integer descriptor addr integerarray entry(0:max users) conststring (10) array scale a(17:43)= c " 0->20K |", " 20-40K |", " 40-60K |", " 60-80K |", " 80-100K |", "100-120K |", "120-140K |", "140-160K |", "160-180K |", "180-200K |", "200-220K |", "220-240K |", "240-260K |", "260-280K |", "280-300K |", "300-320K |", "320-340K |", "340-360K |", "360-380K |", "380-400K |", "400-420K |", "420-440K |", "440-460K |", "460-480K |", "480-500K |", "500-520K |", " >520K |" conststring (5) array scale b(0:16)= c " 0K |", " 1K |", " 2K |", " 3K |", " 4K |", " 5K |", " 6K |", " 7K |", " 8K |", " 9K |", "10K |", "11K |", "12K |", "13K |", "14K |", "15K |", "16K |" integer i, j, k, l, m, flag, size, total entries, totj, totkb integer page, fsys, conad, jj, link, next user, count, pointer, unused real rl string (6) iouser string (16) device string (8) start date, start time, end date, end time string (100) pst string (64)st, ss, desc integerfn hash(string (6) user, integer prime) integer a, j, w constintegerarray p(1:6) = 47, 53, 13, 11, 29, 37 a=addr(user) w = 0 for j=1, 1, 6 cycle w=w+(byteinteger(a+j)&x'1F') * p(j) repeat result =w - (w//prime)*prime+1 end ; ! hash routine continue integer flag string (16) s1, s2 cycle prompt("CONTINUE:") read prompt reply(s1) exit if (s1->ns1.("Y").s2 and ns1="") or c (s1->ns1.("N").s2 and ns1="") repeat return if (s1->ns1.("Y").s2 and ns1="") select output(0) if printer=on start printstring("Do you wish the printer report completed?") newline cycle prompt("YES OR NO:") read prompt reply(s1) exit if (s1->ns1.("Y").s2 and ns1="") or c (s1->ns1.("N").s2 and ns1="") repeat if (s1->ns1.("Y").s2 and ns1="") start terminal = off; t print=off printstring(jtxt." terminal report ended, completing ") printstring("printer report.") newline return finish finish printstring(jtxt." run abandoned as requested.") newline if printer=on start close stream(1) destroy("JSTATSFILE", flag) finish disconnect("JWORKFILE", flag); destroy("JWORKFILE", flag) disconnect("T#SPDEVID", flag) newgen("T#SPDEVID","JJ#SPDEVID",flag) stop end ; !OF CONTINUE routine quick sort(integer array name x, integer a, b) integer l, u, d return if a >= b l = a; u = b d = x(u) cycle l=l+1 while l<u and x(l)<=d exit if l=u x(u) = x(l) u=u-1 while u>l and x(u)>=d exit if l=u x(l) = x(u) repeat x(u)=d l = l-1; u = u+1 quick sort(x, a, l) if a<l quick sort(x, u, b) if u<b end ; ! Of %routine quicksort. connect("JJ#SPCJOB", 0, 0, 0, r, flag) if flag#0 start printstring(jtxt." cannot connect output stats file") newline printstring(" 'JJ#SPCJOB', flag: "); write(flag, 3) newlines(2) disconnect("JWORKFILE", flag); destroy("JWORKFILE", flag) stop finish outfile("JWORKFILE", 1050*max users, 0, 0, conad, flag) if flag#0 start printstring(jtxt."cannot create work file!!") newline return finish user==array(conad+x'20', af user) !INITIALISE THE FSYS/USER LINK MAP. fsys map(i)=0 for i=0, 1, nsys cjob head == record(r_conad) total entries = cjob head_next job slot-1 if total entries=0 start printstring(jtxt." no statistics on output queues collected.") newlines(2) return finish start date = unpack date(cjob head_start date) start time = unpack time(cjob head_start date) end date = unpack date(cjob head_end date) end time = unpack time(cjob head_end date) job entry == array(addr(cjob head)+cjob head_start, af job entry) connect("JJ#SPDEVID", 0, 0, 0, r, flag) if flag#0 start printstring(jtxt." device descriptor file missing, flag: ") printstring(intostr(flag)); newline printstring(" creating new file.") newlines(2) outfile("T#SPDEVID", 2*4096, 0, 0, conad, flag) if flag#0 start printstring(jtxt."cannot create file, flag: ".intostr(flag)) newlines(2); return finish integer(conad)=x'2000' descriptor addr=conad dev descriptors==array(conad+x'30', af dev descriptors) for i=1, 1, total devices cycle dev descriptors(i)_dev="" dev descriptors(i)_description="??????????" repeat integer(conad+x'29')=0 finish else start disconnect("JJ#SPDEVID", flag) copy("JJ#SPDEVID,T#SPDEVID") connect("T#SPDEVID", 3, 0, 0, r, flag) if flag#0 start printstring(jtxt." cannot access device descriptor file!!") newlines(2) return finish descriptor addr=r_conad dev descriptors==array(r_conad+x'30', af dev descriptors) finish descriptor count==integer(descriptor addr+x'20') terminal=on and ->define if s="DEFINE" if period reporting=off start !IE PERIODIC REPORT ONLY TO THE PRINTER printstring("Terminal, printer or both?") newline cycle prompt("? ") read prompt reply(st) exit if (st->ns1.("T").ss and ns1="") or c (st->ns1.("P").ss and ns1="") or (st->ns1.("B").ss and ns1="") repeat if (st->ns1.("T").ss and ns1="") or (st->ns1.("B").ss and ns1="") c then terminal = on if (st->ns1.("P").ss and ns1="") or (st->ns1.("B").ss and ns1="") c then printer = on finish else printer=on define("STREAM01,JSTATSFILE,512") if printer = on p print=printer t print=terminal dev table(i) = 0 for i=1, 1, total devices for i=0, 1, 43 cycle tots(j, i)=0 for j=1, 1, total devices repeat unused = max users; ! No of user slots available. !INITIALISE THE USER TABLE WHICH IS ACCESSED VIA THE FSYS MAP. for i=1, 1, max users cycle user(i) = 0 user(i)_link=-1 repeat next user=1 for i=1, 1, total entries cycle jei == job entry(i) device=jei_device continue if device="BATCH" for j=1, 1, total devices cycle dtj == dev table(j) dtj_device=device if dtj_device="" ! This device not encountered so far - give it a slot. exit if dtj_device=device if j=total devices start printstring(jtxt." more than ".intostr(total devices)) printstring(" devices?? Disaster") newlines(2) disconnect("JWORKFILE", flag); destroy("JWORKFILE", flag) disconnect("T#SPDEVID", flag) newgen("T#SPDEVID","JJ#SPDEVID",flag) return finish repeat size=jei_size if size<0 start printstring("Warning neg file size, entry ".intostr(i).", ignored.") printstring(" User: ".jei_user.", device: ".jei_device) newline continue finish if size>2000 start ; ! Corrupt value - ignore to avoid overflow. printstring("Invalid size value: ".intostr(size)."? (ignored)") printstring(" User: ".jei_user.", device: ".jei_device) newline continue finish dtj_jobs=dtj_jobs+1 dtj_kbytes=dtj_kbytes+size if size<=16 start tots(j,size)_jobs = tots(j,size)_jobs+1 tots(j,size)_kbytes = tots(j,size)_kbytes+size finish l=(size//20+17); !LINK INTO THE HISTOGRAM TABLES. l = 43 if l>43 tots(j, l)_jobs=tots(j, l)_jobs+1 tots(j, l)_kbytes=tots(j, l)_kbytes+size k=1 if size<=16 k=2 if 16<size<=64 k=3 if 64<size<=128 k=4 if 128<size<=256 k=5 if 256<size<=512 k=6 if size>512 dtjsuk == dtj_s unit(k) dtjsuk_jobs=dtjsuk_jobs+1 dtjsuk_kbytes=dtjsuk_kbytes+size dtjsuk_mins ex=dtjsuk_mins ex+ jei_mins ex dtjsuk_mins qd=dtjsuk_mins qd + jei_mins qd iouser=jei_user; fsys=jei_fsys pointer = hash(iouser, max users) cycle exit if user(pointer)_link=-1 or user(pointer)_user=iouser pointer = pointer+1 pointer = 1 if pointer>maxusers repeat up == user(pointer) if up_link=-1 start ! User not encountered before. unused = unused-1 if unused<20 start printstring(jtxt." warning, site about to exceed ") printstring(intostr(max users)." users, see documentation") newlines(2) finish if unused=0 start printstring(jtxt." max users exceeded!!!") newlines(2) stop finish up_link = fsys map(fsys) ! Points at last user on this fsys. First user on fsys has pointer 0. fsys map(fsys) = pointer up_user = iouser finish ! Now add in values. up_jobs=up_jobs+1 up_kbytes=up_kbytes+size updj == up_dev(j) updj_jobs = updj_jobs+1 updj_kbytes = updj_kbytes+size repeat ; ! i loop. !NOW CHECK THAT ALL THE DEVICES ARE RECOGNISED IN THE DEVICE !DESCRIPTOR FILE. for i=1, 1, total devices cycle dti == dev table(i) exit if dti_device="" for j=0, 1, descriptor count cycle exit if j#0 and dti_device=dev descriptors(j)_dev if j=descriptor count start descriptor count=descriptor count+1 if descriptor count>total devices start printstring(jtxt." >".intostr(total devices)) printstring(" devices in the network??") newlines(2) descriptor count=total devices disconnect("T#SPDEVID", flag) newgen("T#SPDEVID","JJ#SPDEVID",flag) disconnect("JWORKFILE", flag); destroy("JWORKFILE", flag) return finish dev descriptors(descriptor count)_dev=dti_device exit finish repeat repeat !IF WE ARE INTERACTING VIA TERMINAL THEN SEE IF THERE ARE !ANY DEVICE DESCRIPTIONS OUTSTANDING AND IF THE USER WISHES !TO GIVE A DESCRIPTION OR CHANGE AN EXISTING ONE. define: if terminal=on and descriptor count>0 start j=0 for i=1, 1, descriptor count cycle if dev descriptors(i)_description->ns1.("?").st and c ns1="" then j=1 and exit repeat if j#0 start printstring("The following queue(s) require description.") newline j=0 for i=1, 1, descriptor count cycle if dev descriptors(i)_description->ns1.("?").st and c ns1="" start printstring(dev descriptors(i)_dev." ") j=j+1 if j=8 start j=0 newline finish finish repeat newline printstring("Do you wish to add a description to any?") newline cycle prompt("YES OR NO:") read prompt reply(st) exit if (st->ns1.("Y").ss and ns1="") or c (st->ns1.("N").ss and ns1="") repeat if (st->ns1.("Y").ss and ns1="") start cycle prompt("Queue:") read prompt reply(st) for i=1, 1, descriptor count cycle if st=dev descriptors(i)_dev start cycle prompt("Description:") read description(st) exit if 0<length(st)<=32 repeat dev descriptors(i)_description=st exit finish repeat exit if st="END" repeat finish finish newline printstring("Do you wish to change any queue description(s)?") newline cycle prompt("YES OR NO:") read prompt reply(st) exit if (st->ns1.("Y").ss and ns1="") or c (st->ns1.("N").ss and ns1="") repeat if (st->ns1.("Y").ss and ns1="") start cycle prompt("Queue") read prompt reply(st) for i=1, 1, descriptor count cycle if st=dev descriptors(i)_dev start printstring("Current descriptor is: ") printstring(dev descriptors(i)_description); newline cycle prompt("Description:") read description(st) exit if 0<length(st)<=32 repeat dev descriptors(i)_description=st exit finish repeat exit if st="END" repeat finish finish if s="DEFINE" start disconnect("T#SPDEVID", flag) newgen("T#SPDEVID","JJ#SPDEVID",flag) return finish !NOW MAKE UP THE REPORT. s newpage sprintstring("Journal Report on Output Queues, EMAS 2900") s newlines(2) sprintstring(start date."(".start time.") to ") sprintstring(end date."(".end time.")") snewlines(2) if terminal=on and printer = off start select output(0) printstring("Note that the details given on the printer would ") printstring("include histograms") newline printstring("and details of individual users' output as well ") printstring("as the summaries "); newline printstring("that follow.") newlines(2) finish if period reporting=on start s newlines(10) sprintstring(" ***********************************************") snewlines(1) sprintstring(" * 30 day accumulation report to be retained *") snewlines(1) sprintstring(" ***********************************************") snewlines(2) finish terminal lines=max terminal lines+1 if terminal=on printer lines=max printer lines+1 if printer=on for i=1, 1, total devices cycle dti == dev table(i) exit if dti_device="" t print=off; p print=off t print=on if terminal lines>max terminal lines p print=on if printer lines>max printer lines if t print+ pprint>off start !IE A PAGE SKIP IS REQUIRED BY AT LEAST ONE OF THE OUTPUT STREAMS continue if t print=on s newpage s newlines(1) s printstring("Queue Total Jobs Total Kbytes") s printstring(" Queue description") s newlines(1) s printstring("---------------------------------------") s printstring("------------------------------") s newlines(2) terminal lines=4 if t print=on printer lines=4 if p print=on finish t print=terminal; p print=printer s printstring(" ".dti_device) s spaces(16-length(dti_device)) s write(dti_jobs, 6) s write(dti_kbytes, 13) desc="??????????" if descriptor count>0 start for j=1, 1, descriptor count cycle if dev descriptors(j)_dev=dti_device start desc=dev descriptors(j)_description exit finish repeat finish s printstring(" ".desc) s newlines(1) repeat s newlines(4) s printstring("End of queue totals, 'By Queue' summary follows.") s newlines(1) for i=1, 1, total devices cycle dti == dev table(i) exit if dti_device="" continue if t print=on s newpage select output(0) and newline if t print=on sprintstring("Queue: ".dti_device) s spaces(7-length(dti_device)) desc="??????????" if descriptor count>0 start for j=1, 1, descriptor count cycle if dev descriptors(j)_dev=dti_device start desc=dev descriptors(j)_description exit finish repeat finish s printstring(desc." ") if t print=on start select output(0) newline finish s printstring("Total jobs:") s write(dti_jobs, 5) s printstring(" Kilobytes:") s write(dti_kbytes, 6) if p print=on start select output(1) spaces(2); printstring(start date."(".start time.") to ") printstring(end date."(".end time.")") finish s newlines(2) s printstring("Jobs by size (Kbytes): <=16 17-64 65-128 ") s printstring("129-256 257-512 > 512") s newlines(1) s spaces(20) s printstring("|-------|-------|-------|-------|-------|-------|") s newlines(1) s printstring("Jobs"); s spaces(16) for j=1, 1, 6 cycle if dti_s unit(j)_jobs=0 then s spaces(8) else start swrite(dti_s unit(j)_jobs, 6) s spaces(1) finish repeat s newlines(1) s printstring("As % of total ") for j=1, 1, 6 cycle if dti_s unit(j)_jobs=0 then s spaces(8) else start s print(4, 1, dti_s unit(j)_jobs/dti_jobs*100) s spaces(1) finish repeat s newlines(1); s printstring("Kilobytes ") for j=1, 1, 6 cycle if dti_s unit(j)_kbytes=0 then sspaces(8) else start s write(dti_s unit(j)_kbytes, 6) s spaces(1) finish repeat s newlines(1) sprintstring("As % of total ") for j=1, 1, 6 cycle if dti_sunit(j)_kbytes=0 then sspaces(8) else start s print(5, 1, dti_s unit(j)_kbytes/dti_kbytes*100) finish repeat s newlines(1); s printstring("Av queued time(mins)") for j=1, 1, 6 cycle if dti_sunit(j)_jobs=0 then sspaces(8) else start sprint(4, 1, dti_sunit(j)_minsqd/dti_sunit(j)_jobs) s spaces(1) finish repeat snewlines(1); s printstring("Av execution (mins)") for j=1, 1, 6 cycle if dti_sunit(j)_jobs=0 then s spaces(8) else start sprint(4, 1, Dti_sunit(j)_minsex/dti_sunit(j)_jobs) s spaces(1) finish repeat s newlines(1) if printer=on start select output(1) newlines(1) spaces(12); printstring("As % of jobs <= 16 kilobytes") spaces(32) printstring("As % of total kbytes of jobs <= 16k") newline spaces(14) printstring("10 20 30 40 50 60 70 80 90 100") spaces(12) printstring("10 20 30 40 50 60 70 80 90 100") newline spaces(9) printstring("-----------------------------------------------------") spaces(7) printstring("-----------------------------------------------------") newline totj=0; totkb=0 for j=0, 1, 16 cycle totj=totj+tots(i, j)_jobs totkb=totkb+tots(i, j)_kbytes repeat if totj#0 start for j=0, 1, 16 cycle spaces(5); printstring(scale b(j)) pst="" rl=tots(i, j)_jobs/(totj<<1)*100 k = intpt(rl) pst=pst."*" for l=1, 1, k pst=pst."*" if rl-k>0.5 printstring(pst) spaces(59-length(pst)) printstring("|"); pst="" rl=tots(i, j)_kbytes/(totkb<<1)*100 k = intpt(rl) pst=pst."*" for l=1, 1, k pst=pst."*" if rl-k>0.5 printstring(pst); newline repeat finish newline spaces(12); printstring("As % of all jobs"); spaces(44) printstring("As % of total kilobytes") newline spaces(14) printstring("10 20 30 40 50 60 70 80 90 100") spaces(12) printstring("10 20 30 40 50 60 70 80 90 100") newline spaces(9) printstring("-----------------------------------------------------") spaces(7) printstring("-----------------------------------------------------") newline totj=0; totkb=0 for j=17, 1, 43 cycle totj=totj+tots(i, j)_jobs totkb=totkb+tots(i, j)_kbytes repeat if totj#0 start for j=17, 1, 43 cycle printstring(scale a(j)) pst="" rl=tots(i, j)_jobs/(totj<<1)*100 k = intpt(rl) pst=pst."*" for l=1, 1, k pst=pst."*" if rl-k>0.5 printstring(pst) spaces(59-length(pst)) printstring("|"); pst="" rl=tots(i, j)_kbytes/(totkb<<1)*100 k = intpt(rl) pst=pst."*" for l=1, 1, k pst=pst."*" if rl-k>0.5 printstring(pst); newline repeat finish finish repeat ; ! i loop. s printstring("End of queue summary.") s newlines(1) if printer=on start select output(1) for i=0, 1, nsys cycle continue if fsys map(i)=0 printer lines=max printer lines+1 page=1 !SORT THE ENTRIES FOR THE FSYS INTO ORDER OF MOST KBYTES DOWN.. count=1 link=fsys map(i) cycle entry(count)=user(link)_kbytes entry(count)=x'3FFFF' if entry(count)>x'3FFFF' entry(count)=entry(count)<<14+link link=user(link)_link exit if link=0 count=count+1 repeat quicksort(entry,1,count) entry(k) = entry(k)&x'3FFF' for k=1, 1, count for jj=1, 1, count cycle j=entry(jj) up == user(j) if printer lines>max printer lines start newpage printstring("User output list for ") printstring("Period ".start date."(".start time.") to ") printstring(end date."(".end time."). File system: ") printstring(intostr(i)." Page: ".intostr(page)) newlines(2) printstring(" Totals------ Entries: Queue (total job") printstring("s/total kbytes)") newline printstring("User Jobs Kbytes") newline printsymbol('-') for m=1, 1, 120 newlines(2) page=page+1 printer lines=6 finish printstring(up_user); write(up_jobs, 6) write(up_kbytes, 6) l=-1 for k=1, 1, total devices cycle updk == up_dev(k) continue if updk_jobs=0 l=l+1 if l=5 start l=0; newline; spaces(20) printer lines=printer lines+1 finish pst=dev table(k)_device."(".intostr(updk_jobs) pst=pst."/".intostr(updk_kbytes).")" spaces(20-length(pst)) printstring(pst) repeat newline; printer lines=printer lines+1 repeat repeat finish select output(0) close stream(1) if printer=on list("JSTATSFILE,.LP") if period reporting=on send("JSTATSFILE,.LP") if printer=on disconnect("JWORKFILE", flag) destroy("JWORKFILE", flag) disconnect("T#SPDEVID", flag) newgen("T#SPDEVID","JJ#SPDEVID",flag) period reporting=off if period reporting=on ! indicate that the reporting was completed. end ; !OF ROUTINE OUTPUT QUEUES! if journalsite = kent then start ! ************************************************** ! ************************************************** ! ************************************************** externalroutine consumables analysis(string (255) s) integer flag, i, total entries, page, lines string (8) start date, start time, end date, end time integerarray x(1:4096) record (rf) r recordformat f ucons entry(string (6) user, integer pages, cards, c ppfeet, gpfeet, spare5) record (f ucons entry)arrayformat af ucons entry(1:4096) record (f ucons entry)arrayname uci record (f ucons entry)array ucr(1:4096) record (f ucons entry)name uce ! ! routine quicksort(integer a, b) integer l, u, d ! return if a >= b l = a; u = b; d = x(u) -> l2 l1: l = l + 1 -> l4 if l = u l2: -> l1 unless ucr(x(l))_user > ucr(d)_user x(u) = x(l) l3: u = u - 1 -> l4 if l = u -> l3 unless ucr(x(u))_user < ucr(d)_user x(l) = x(u) -> l1 l4: x(u) = d quicksort(a, l-1) quicksort(u+1, b) end ! ! routine heading newpage lines = 6 printstring("EMAS 2900 Journal report on use of consumable items") printstring(" Page:"); write(page, 1) newlines(2) printstring(start date."(".start time.") to ") printstring(end date."(".end time.")") newlines(2) printstring(" User Printed Pages") printstring(" Cards Punched Feet of Paper Tape") printstring(" Feet of Graph Paper") newlines(2) page = page + 1 end ! ! connect("JJ#SPCONS", 1, 0, 0, r, flag) if flag # 0 then start printstring(jtxt." cannot connect consumables stats file") newline printstring(" 'JJ#SPCONS', flag: "); write(flag, 1) newlines(2) return finish ! uci == array(r_conad+x'40', af ucons entry) start date = unpack date(integer(r_conad+x'24')) start time = unpack time(integer(r_conad+x'24')) end date = unpack date(integer(r_conad+x'28')) end time = unpack time(integer(r_conad+x'28')) total entries = 0 for i = 1, 1, 4096 cycle if uci(i)_user # "" then start total entries = total entries + 1 ucr(total entries) = uci(i) finish repeat if total entries = 0 then start printstring(jtxt." no statistics on use of consumables") newline printstring(" have been collected.") newlines(2) return finish ! define("1,JCONSFILE") selectoutput(1) if period reporting=on then start newlines(10) printstring(" ***********************************************") newline printstring(" * 30 day accumulation report to be retained *") newline printstring(" ***********************************************") newlines(2) finish for i = 1, 1, total entries cycle x(i) = i repeat quicksort(1, total entries) ! page = 1 heading for i = 1, 1, total entries cycle uce == ucr(x(i)) spaces(10) printstring(uce_user) spaces(10) write(uce_pages, 10) spaces(10) write(uce_cards, 10) spaces(10) write(uce_ppfeet, 10) spaces(10) write(uce_gpfeet, 10) newline lines = lines + 1 if lines > 66 then heading repeat selectoutput(0) closestream(1) if period reporting = on then list("JCONSFILE,.LP,1") send("JCONSFILE,.LP") period reporting = off end ; ! of routine CONSUMABLES ANALYSIS finish ! **************************************************************** ! *************************************************************** externalroutine session monitor(string (255) s) !THIS ROUTINE GIVES BOTH A MONTHLY REPORT ON DEMAND BY THE AUTO ANALYSIS !OF DIRECT LOGS AND ALSO CONTROLS THE INTERACTIVE INTERROGATION OF THE SESSION !MONITOR DATABASE. routinespec determine range by date routinespec session file sort(integer from, to) routinespec group reports(integer groups, from, to, string (8) c from date, from time, to date, to time) routinespec user report(string (6) user, integer from, to) recordformat f sessions list(integer end, pageturns, cpu, elapse, procs, byteinteger type, string (6) user) recordformat f descriptor(integer copies, keys, string (6) array key(1:50), string (30) array description(1:50)) record (f descriptor)name descriptor constinteger max monthly sessions = 100000 constinteger max proc slots = 256 constinteger max keys = 50 record (f sessions list)arrayformat af sessions list c (1:max monthly sessions) record (f sessions list)arrayname sessions list constinteger foreground = 1 constinteger background = 2 record (rf)r string (64) st string (8) from date, from time, to date, to time integer entries, flag, low entry, high entry, dtfrom, dtto, histograms integer groupreps, copies, keys, i, j integerarray alpha list(1:max monthly sessions) integer conad string (20) dtime, ddate, reply string (6) array group key(1:max keys) string (30) array group desc(1:max keys) switch sw(1:7) routine check date and time(stringname ddate, dtime, integername flag) integer i string (8) st, dt dt=date if length(ddate)=4 start byteinteger(addr(ddate)+5)=byteinteger(addr(dt)+7) byteinteger(addr(ddate)+6)=byteinteger(addr(dt)+8) length(ddate)=6 finish for i=1, 1, 6 cycle flag=1 and return unless x'30'<=byteinteger(addr(ddate)+i)<=x'39' repeat st = substring(ddate, 1, 2)."/".substring(ddate, 3, 4)."/".substring(ddate, 5, 6) ddate=st if length(dtime)=4 start byteinteger(addr(dtime)+5)='0' byteinteger(addr(dtime)+6)='0' length(dtime)=6 finish for i=1, 1, 6 cycle flag=1 and return unless x'30'<=byteinteger(addr(dtime)+i)<=x'39' repeat st = substring(dtime, 1, 2).".".substring(dtime, 3, 4).".".substring(dtime, 5, 6) dtime=st flag=0 return end ; !OF CHECK DATE AND TIME. histograms=no; groupreps=no; keys=0; copies=0 connect("JJ#DIRSESS", 0, 0, 0, r, flag) if flag#0 start printstring("Session database not available.") newline return finish cycle connect("JJ#DIRCON", 0, 0, 0, r, flag) exit if flag=0 printstring("Cannot connect sessions descriptor file " c .", creating new file.") newline outfile("T#DIRCON", 4096, 0, 0, conad, flag) if flag#0 start printstring("Cannot create file!!") newline return finish descriptor==record(conad+x'20') integer(conad)=x'1000' integer(conad+8)=x'1000' descriptor_copies=1 descriptor_keys=1 descriptor_key(1)="ALL" descriptor_description(1)="COMPLETE LIST" disconnect("T#DIRCON", flag) rename("T#DIRCON","JJ#DIRCON",flag) newgen("T#DIRCON","JJ#DIRCON",flag) printstring("File created with defaults: " c ."copies 1, groups 1 ('ALL', for complete list)") newline repeat descriptor==record(r_conad+x'20') connect("JJ#DIRSESS", 0, 0, 0, r, flag) if flag#0 start printstring("Cannot access the session database!") newline return finish sessions list==array(r_conad+x'50'+max proc slots*24, af sessions list) entries=integer(r_conad+x'20') from date=unpackdate(integer(r_conad+x'24')) from time=unpacktime(integer(r_conad+x'24')) to date=unpackdate(integer(r_conad+x'28')) to time=unpacktime(integer(r_conad+x'28')) ->sw(7) if s="AUTOMONTHLY" cycle prompt("Option:") read prompt reply(st) ->sw(1) if st="ADD GROUP" ->sw(2) if st="REMOVE GROUP" ->sw(3) if st->ns1.("MONTHLY COPIES ").st and ns1="" and "1"<=st<="9" ->sw(4) if st="REPORT" ->sw(5) if st="CPU PROFILE" ->sw(6) if st->st.(" BREAKDOWN") and length(st)=6 printstring("Invalid option!") newline repeat sw(1): !add a new group to the monthly report. disconnect("JJ#DIRCON", flag) copy("JJ#DIRCON,T#DIRCON") connect("T#DIRCON", 3, 0, 0, r, flag) descriptor==record(r_conad+x'20') cycle cycle prompt("Group:") read prompt reply(st) exit if length(st)=6 or st="END" printstring("Reply length 6 or 'END'") newline repeat exit if st="END" if descriptor_keys=max keys start printstring("Monthly descriptor groups list full!") newline exit finish descriptor_keys=descriptor_keys+1 descriptor_key(descriptor_keys)=st prompt("Description:") read description(st) length(st)=30 if length(st)>30 descriptor_description(descriptor_keys)=st repeat disconnect("T#DIRCON", flag) newgen("T#DIRCON","JJ#DIRCON", flag) return sw(2): !remove a group entry from the monthly report. disconnect("JJ#DIRCON", flag) copy("JJ#DIRCON,T#DIRCON") connect("T#DIRCON", 3, 0, 0, r, flag) descriptor==record(r_conad+x'20') cycle cycle prompt("Group:") read prompt reply(st) exit if st="END" or length(st)=6 or st="ALL" printstring("Reply length 6 or 'END'") newline repeat exit if st="END" if descriptor_keys#0 start for i=1, 1, descriptor_keys cycle if descriptor_key(i)=st start if i<descriptor_keys start for j=i+1, 1, descriptor_keys cycle descriptor_key(j-1)=descriptor_key(j) descriptor_description(j-1)=descriptor_description(j) repeat finish descriptor_keys=descriptor_keys-1 exit finish if i=descriptor_keys start printstring("Group: ".st." not found in monthly group list.") newline finish repeat finish else start printstring("No groups in list!!") newline exit finish repeat disconnect("T#DIRCON", flag) newgen("T#DIRCON","JJ#DIRCON",flag) return sw(3): !set copies for monthly run. disconnect("JJ#DIRCON", flag) copy("JJ#DIRCON,T#DIRCON") connect("T#DIRCON", 3, 0, 0, r, flag) descriptor==record(r_conad+x'20') descriptor_copies = s to i(st) disconnect("T#DIRCON", flag) newgen("T#DIRCON","JJ#DIRCON",flag) return sw(4): !make up a report(not the monthly run) printstring("The on line database covers " c .from date." ".from time." to ".to date." ".to time) newline determine range by date unless 1<=low entry<=high entry start printstring("No entries found for this period.") newline return finish cycle prompt("Histograms:") read prompt reply(st) histograms=yes and exit if st="YES" histograms=no and exit if st="NO" printstring("YES or NO.") newline repeat cycle prompt("Group Reports:") read prompt reply(st) groupreps=no and exit if st="NO" if st="DEFAULTS" start for i=1, 1, descriptor_keys cycle group key(i)=descriptor_key(i) group desc(i)=descriptor_description(i) repeat keys=descriptor_keys groupreps=yes exit finish if st="SPECIFIC" start cycle prompt("Group:") read prompt reply(st) exit if st="END" and keys>0 if length(st)=6 or st="ALL" start keys=keys+1 group key(keys)=st prompt("Description:") read description(st) length(st)=30 if length(st)>30 group desc(keys)=st finish else start printstring("At least one 6 char group, term with 'END'") newline finish repeat groupreps=yes exit finish printstring("'NO' or 'SPECIFIC' or 'DEFAULTS'") newline repeat if groupreps=yes or histograms=yes start cycle prompt("Copies:") read prompt reply(st) copies = s to i(st) exit if 1<=copies<=10 printstring("1->10!") newline repeat finish session file sort(low entry, high entry) ! %IF HISTOGRAMS=YES %THEN ....... if groupreps=yes start group reports(keys, low entry, high entry, unpackdate(dtfrom), unpacktime(dtfrom), unpackdate(dtto), unpacktime(dtto)) list("SESSIONREP,.LP,".intostr(copies)) if copies>0 printstring("Reports printed.") newline finish return sw(5): sw(6): !make a list of sessions for the user(group) defined. printstring("The on line database covers " c .from date." ".from time." to ".to date." ".to time) newline determine range by date unless 1<=low entry<=high entry start printstring("No entries for this period!") newline return finish user report(st, low entry, high entry) list("SESSIONLIST,.LP") return sw(7): for i=1, 1, descriptor_keys cycle group key(i)=descriptor_key(i) group desc(i)=descriptor_description(i) repeat copies=descriptor_copies session file sort(1, entries) !HISTOGRAMS HERE. group reports(descriptor_keys, 1, entries, from date, from time, to date, to time) list("SESSIONREP,.LP,".intostr(copies-1)) if copies>1 list("SESSIONREP,.LP") printstring("Reports Printed for Session Monitor"); newline copy("JJ#DIRSESS,T#DIRSESS") connect("T#DIRSESS", 3, 0, 0, r, flag) if flag#0 start printstring("Cannot connect session monitor file to clear down.") newline return finish integer(r_conad+x'20')=0 integer(r_conad+x'24')=0 integer(r_conad+x'28')=0 integer(r_conad)=x'60'+max proc slots*24 integer(r_conad+8)=(integer(r_conad)>>12+1)<<12 disconnect("T#DIRSESS", flag) newgen("T#DIRSESS","JJ#DIRSESS",flag) return routine determine range by date integer i cycle cycle prompt("*Low date, time:") read prompt reply(reply) if reply="HELP" then print help(3) else start if reply->ddate.(",").dtime start ddate -> (" ").ddate while charno(ddate,1)=' ' dtime -> (" ").dtime while charno(dtime,1)=' ' if 4<=length(ddate)<=6 and 4<=length(dtime)<=6 start if length(ddate)#5 and length(dtime)#5 start check date and time(ddate, dtime, flag) exit if flag=0 finish finish finish newline printstring(jtxt." check your reply!") newline finish repeat dtfrom=pack date and time(ddate, dtime) cycle prompt("*High date, time:") read prompt reply(reply) if reply="HELP" then print help(3) else start if reply->ddate.(",").dtime start ddate -> (" ").ddate while charno(ddate,1)=' ' dtime -> (" ").dtime while charno(dtime,1)=' ' if 4<=length(ddate)<=6 and 4<=length(dtime)<=6 start if length(ddate)#5 and length(dtime)#5 start check date and time(ddate, dtime, flag) exit if flag=0 finish finish finish newline printstring(jtxt." check your reply!") newline finish repeat dtto=pack date and time(ddate, dtime) unless dtfrom<dtto start printstring(jtxt." unordered time sequence?") newline finish else exit repeat low entry=0; high entry=0 for i=1, 1, entries cycle if sessions list(i)_end>dtfrom start low entry=i if low entry=0 if sessions list(i)_end>dtto then exit c else high entry=i finish repeat end ; ! of %routine determine range by date. routine session file sort(integer from, to) !This routine takes the main session file and sorts pointers to !part of it (from - to), into alphabetical order. !The resulting list of pointers is in alpha list(from:to) integer i, d string (6) slduser routine quick sort(integer a, b) integer l, u return if a >= b l = a-1; u = b d = alpha list(u); slduser = sessions list(d)_user cycle cycle l=l+1 -> l4 if l=u exit if sessions list(alpha list(l))_user>slduser repeat alpha list(u)=alpha list(l) cycle u=u-1 ->l4 if l=u exit if sessions list(alpha list(u))_user<slduser repeat alpha list(l)=alpha list(u) repeat l4: alpha list(u)=d quick sort(a, l-1) quick sort(u+1, b) end ; ! Of %routine quicksort. alpha list(i)=i for i=from, 1, to quick sort(from, to) end ; !OF ROUTINE SESSION FILE SORT. integerfn matchkey(string (6) key, user) !THIS FN RETURNS MATCH IF THE USER MATTCHES A KEY !IGNORING * POSITIONS. integer i if key="ALL" start if (user->ns1.("EYR").user and ns1="") then result = no match c else result =match !THIS IS TO EXCLUDE ERTE PROCS (NON ERCC SITES MAY WISH THIS REMOVED). finish for i=1, 1, 6 cycle result =no match if charno(key, i)#'*' and charno(key, i)#charno(user, i) repeat result =match end ; !OF INTEGERFN MATCHKEY routine group reports(integer groups, from, to, string (8) c from date, from time, to date, to time) !THIS ROUTINE PRODUCES REPORTS ON SESSIONS FOR EACH OF !'GROUPS' USER GROUPS. record (f sessions list)name entry record (f sessions list) empty integerarray top(1:groups) integerarrayformat linkf(1:groups, 1:to-from+1) integerarrayname link integer i, j, k, lines, n, page, flag, conad, ali integer cpu, pageturns, fsessions, bsessions, felapse, belapse, fcpu, bcpu integer fpageturns, bpageturns integer totfcpu, totfpts, totfelapse, totfsessions, totbsessions, totbcpu integer totbpts, totbelapse string (6) user outfile("JSESSIONWK", ((to-from+1)*groups*4)+64, 0, 0, conad, flag) if flag # 0 start printstring("Session monitor group report fails, no file space?") newline stop finish link == array(conad+x'20', linkf) top(i)=0 for i=1, 1, groups !THE LIST 'TOP' TELLS US HOW MANY ENTRIES THERE ARE FOR EACH !GROUP TYPE. for i=from, 1, to cycle ali = alpha list(i) user = sessions list(ali)_user for j=1, 1, groups cycle if matchkey(group key(j), user)=match then top(j)=top(j)+1 and c link(j, top(j))=ali repeat repeat !WE NOW HAVE FORMED THE ALPHABETIC LINKAGE TABLE FOR EACH GROUP. define("STREAM01,SESSIONREP,512") select output(1) newlines(10); spaces(10) printstring("EMAS 2900 Journal System session monitor") printstring(" report for the period ".from time." ") printstring(from date." to ".to time." ".to date.".") newline empty = 0; ! Null record. cpu=0;pageturns=0;fsessions=0;bsessions=0;felapse=0;belapse=0 fcpu=0;bcpu=0;fpageturns=0;bpageturns=0 user="" for i=1, 1, groups cycle if top(i)=0 start newpage printstring("No records for the group: ".group key(i)) newline continue finish page=0; lines=max printer lines totfelapse=0;totfsessions=0;totbsessions=0 totfcpu=0;totbcpu=0;totfpts=0;totbpts=0;totbelapse=0 n = top(i)+1 for j=1, 1, n cycle if j<n then entry==sessions list(link(i, j)) else entry==empty if user#entry_user start if lines>=max printer lines start page=page+1 lines=10 newpage printstring("Session monitor report " c ."for the period ".from time." " c .from date." to ".to time." ".to date.".") printstring(" Page: "); write(page, 2) newline printstring("User group: ".group key(i)." ".group desc(i)) newlines(2) spaces(11) printstring("Total---------- Foreground----------" c ."------------------------ Background-----------------" c ."-----------------") newline printstring(" User CPU Pageturns Sessions " c ."Elapse/Sess CPU/CMIN PTS/CPUS Sessions " C ."Elapse/Sess CPU/CMIN PTS/CPUS") newline printsymbol('-') for k=1, 1, 121 newline finish if user#"" start !IE THE END OF A PARTICULAR USER, REPORT ON HIM. printstring(user) write(cpu, 8); write(pageturns, 10);write(fsessions, 10) if fsessions > 0 then print(felapse/fsessions, 11, 1) c else write(fsessions, 13) if felapse>0 then print(fcpu/felapse, 8, 1) c else write(felapse, 10) if fcpu>0 then print(fpageturns/fcpu, 8, 1) c else write(fcpu, 10) write(bsessions, 11) if bsessions>0 then print(belapse/bsessions, 11, 1) c else write(bsessions, 13) if belapse>0 then print(bcpu/belapse, 8, 1) c else write(belapse, 10) if bcpu>0 then print(bpageturns/bcpu, 8, 1) c else write(bcpu, 10) newline lines=lines+1 cpu=0 pageturns=0 totfsessions=totfsessions+fsessions; fsessions=0 totbsessions=totbsessions+bsessions; bsessions=0 totfcpu=totfcpu+fcpu; fcpu=0 totbcpu=totbcpu+bcpu; bcpu=0 totfpts=totfpts+fpageturns; fpageturns=0 totbpts=totbpts+bpageturns; bpageturns=0 totbelapse=totbelapse+belapse; belapse=0 totfelapse=totfelapse+felapse; felapse=0 finish user=entry_user finish cpu=cpu+entry_cpu pageturns=pageturns+entry_pageturns if entry_type=foreground start fsessions=fsessions+1 fcpu=fcpu+entry_cpu felapse=felapse+entry_elapse fpageturns=fpageturns+entry_pageturns finish else if entry_type=background start bsessions=bsessions+1 bcpu=bcpu+entry_cpu belapse=belapse+entry_elapse bpageturns=bpageturns+entry_pageturns finish repeat ; ! j cycle newline printstring("Totals for group Sessions CPU " c ." PAGETURNS ELAPSE/SESS CPU/CMIN PTS/CPUS") newlines(2) printstring(" Foreground:") write(totfsessions, 12); write(totfcpu, 9);write(totfpts, 14) if totfsessions>0 then print(totfelapse/totfsessions, 11, 1) c else write(totfsessions, 13) if totfelapse>0 then print(totfcpu/totfelapse, 9, 1) c else write(totfelapse, 11) if totfcpu>0 then print(totfpts/totfcpu, 9, 1) c else write(totfcpu, 11) newline printstring(" Background:") write(totbsessions, 12);write(totbcpu, 9);write(totbpts, 14) if totbsessions>0 then print(totbelapse/totbsessions, 11, 1) c else write(totbsessions, 13) if totbelapse>0 then print(totbcpu/totbelapse, 9, 1) c else write(totbelapse, 11) if totbcpu>0 then print(totbpts/totbcpu, 9, 1) c else write(totbcpu, 11) newline printstring(" All sessions:") write(totbsessions+totfsessions, 12);write(totbcpu+totfcpu, 9);write(totbpts+totfpts, 14) if totbsessions+totfsessions>0 then print((totbelapse+totfelapse)/(totbsessions+totfsessions), 11, 1) c else write(totbsessions+totfsessions, 13) if totbelapse+totfelapse>0 then print((totbcpu+totfcpu)/(totbelapse+totfelapse), 9, 1) c else write(totbelapse+totfelapse, 11) if totbcpu+totfcpu>0 then print((totbpts+totfpts)/(totbcpu+totfcpu), 9, 1) c else write(totbcpu+totfcpu, 11) repeat ; ! i cycle. newpage printstring("End of session monitor report.") newlines(2) select output(0) close stream(1) disconnect("JSESSIONWK", flag) destroy("JSESSIONWK", flag) end ; !OF ROUTINE GROUP REPORTS. routine user report(string (6) user, integer from, to) !MAKE UP A LIST OF SESSIONS FOR THE DEFINED USER(GROUP). integer i, j, lines, page define("STREAM01,SESSIONLIST") select output(1) newlines(10); spaces(10) printstring("EMAS 2900 Journal System Session Monitor " C ."List for user: ".user) newline lines=max printer lines page=0 for i=from, 1, to cycle if matchkey(user, sessions list(i)_user)=match start if lines>= max printer lines start newpage page=page+1 lines=10 newline printstring(" User Session ends----- Elapse Type " c ." CPU PTS Page: ".intostr(page)) newline for j=1, 1, 62 cycle printsymbol('-') repeat newlines(2) finish printstring(sessions list(i)_user." ".unpackdate( c sessions list(i)_end)." ".unpacktime(sessions list(i)_end)) write(sessions list(i)_elapse, 6) if sessions list(i)_type=foreground then c printstring(" Foreground") else printstring(" Background") write(sessions list(i)_cpu, 8) write(sessions list(i)_pageturns, 9) newlines(2); lines=lines+2 finish repeat select output(0) close stream(1) return end ; !OF USER REPORT end ; ! Of %external %routine session monitor. !************************************************************************** ! ROUTINES AND FUNCTIONS COMMON TO THE SYSTEM. !************************************************************************** routine s spaces(integer n) select output(0) and spaces(n) if t print=on select output(1) and spaces(n) if p print=on end ; !OF S SPACES routine s newpage select output(0) and newpage if t print=on select output(1) and newpage if p print=on end ; !OF S NEWPAGE routine s printstring(string (72) s) select output(0) and printstring(s) if t print=on select output(1) and printstring(s) if p print=on end ; !OF S PRINTSTRING routine s newlines(integer n) if t print=on start select output(0) newlines(n) terminal lines=terminal lines+n finish if p print=on start select output(1) newlines(n) printer lines=printer lines+n finish end ; !OF S NEWLINES routine s write(integer i, j) select output(0) and write(i, j) if t print=on select output(1) and write(i, j) if p print=on end ; !OF S WRITE routine s print(integer i, j, real r) select output(0) and print(r, i, j) if t print=on select output(1) and print(r, i, j) if p print=on end ; !OF S PRINT endoffile