Trailing-Edge
-
PDP-10 Archives
-
decuslib10-06
-
43,50412/tops.sim
There are 2 other files named tops.sim in the archive. Click here to see a list.
SIMULATION
BEGIN
INTEGER MAXJOB;
REAL SWAPLATENCY,SWAPRATE,PROT0,PROT1,FREECORE, TOTUSERCORE;
REAL NRBUFFERS, COMPQUANT, IOQUANT, INITIALQUANT;
INTEGER BLKSPERCYL, BLKSPERTRACK, NRCYL, DISKSIZE, TRACKSPERCYL;
REAL BLKSPERSEC, SEEKSTART, SEEKCYL;
INTEGER NRCHAN, DRIVESPERKON, KONPERCHAN, NRDRIVES;
REAL OVERHD0,OVERHD1;
INTEGER VERSION;
REF(INFILE) PAR;
TEXT PARBUF;
TEXT P, PARNAME;
REF (OUTFILE) O, RSLTS;
TEXT OBUF, ONAME, RSLTSBUF, RSLTSNAME;
PROCEDURE PARERR;
BEGIN
OUTTEXT ("ERR READING SIMULATION PARAMETERS");
OUTIMAGE;
OUTTEXT (P);
OUTIMAGE;
GOTO ENDRUN;
END;
VERSION:=1;
OUTTEXT ("PARAMETER FILE? ");
BREAKOUTIMAGE;
INIMAGE;
PARNAME:-INTEXT(20);
PAR:-NEW INFILE(PARNAME);
PARBUF:-BLANKS(80);
PAR.OPEN(PARBUF);
OUTTEXT ("REPORT FILE? ");
BREAKOUTIMAGE;
INIMAGE;
ONAME:-INTEXT(20);
O:-NEW OUTFILE(ONAME);
OBUF:-BLANKS(80);
O.OPEN(OBUF);
OUTTEXT ("DETAILED RESULTS FILE? ");
BREAKOUTIMAGE;
INIMAGE;
RSLTSNAME:-INTEXT(20);
RSLTS:-NEW OUTFILE(RSLTSNAME);
RSLTSBUF:-BLANKS(100);
RSLTS.OPEN(RSLTSBUF);
INSPECT PAR DO
BEGIN
INIMAGE;
P:-INTEXT(15);
IF P = "SWAPLATENCY " THEN SWAPLATENCY:= INREAL
ELSE PARERR;
INIMAGE;
P:-INTEXT(15);
IF P = "SWAPRATE " THEN SWAPRATE:= INREAL
ELSE PARERR;
INIMAGE;
P:-INTEXT(15);
IF P = "PROT0 " THEN PROT0:= INREAL
ELSE PARERR;
INIMAGE;
P:-INTEXT(15);
IF P = "PROT1 " THEN PROT1:= INREAL
ELSE PARERR;
INIMAGE;
P:-INTEXT(15);
IF P = "FREECORE " THEN FREECORE:= INREAL
ELSE PARERR;
INIMAGE;
P:-INTEXT(15);
IF P = "MAXJOB " THEN MAXJOB:= ININT
ELSE PARERR;
INIMAGE;
P:-INTEXT(15);
IF P = "NRBUFFERS " THEN NRBUFFERS:= INREAL
ELSE PARERR;
INIMAGE;
P:-INTEXT(15);
IF P = "COMPQUANT " THEN COMPQUANT:= INREAL
ELSE PARERR;
INIMAGE;
P:-INTEXT(15);
IF P = "IOQUANT " THEN IOQUANT:= INREAL
ELSE PARERR;
INIMAGE;
P:-INTEXT(15);
IF P = "INITIALQUANT " THEN INITIALQUANT:= INREAL
ELSE PARERR;
INIMAGE;
P:-INTEXT(15);
IF P = "NRCYL " THEN NRCYL:= ININT
ELSE PARERR;
INIMAGE;
P:-INTEXT(15);
IF P = "TRACKSPERCYL " THEN TRACKSPERCYL:= ININT
ELSE PARERR;
INIMAGE;
P:-INTEXT(15);
IF P = "BLKSPERTRACK " THEN BLKSPERTRACK:= ININT
ELSE PARERR;
INIMAGE;
P:-INTEXT(15);
IF P = "BLKSPERSEC " THEN BLKSPERSEC:= INREAL
ELSE PARERR;
INIMAGE;
P:-INTEXT(15);
IF P = "NRCHAN " THEN NRCHAN:= ININT
ELSE PARERR;
INIMAGE;
P:-INTEXT(15);
IF P = "KONPERCHAN " THEN KONPERCHAN:= ININT
ELSE PARERR;
INIMAGE;
P:-INTEXT(15);
IF P = "DRIVESPERKON " THEN DRIVESPERKON:= ININT
ELSE PARERR;
INIMAGE;
P:-INTEXT(15);
IF P = "OVERHD0 "THEN OVERHD0:= INREAL
ELSE PARERR;
INIMAGE;
P:-INTEXT(15);
IF P = "OVERHD1 " THEN OVERHD1:= INREAL
ELSE PARERR;
CLOSE;
END;
DISKSIZE:=NRCYL * TRACKSPERCYL * BLKSPERTRACK;
BLKSPERCYL:=TRACKSPERCYL * BLKSPERTRACK;
NRDRIVES:=NRCHAN*KONPERCHAN*DRIVESPERKON;
TOTUSERCORE:=FREECORE;
BEGIN
REAL PROCEDURE MIN(A,B); REAL A,B;
MIN:=IF A<B THEN A ELSE B;
REAL PROCEDURE MAX(A,B); REAL A,B;
MAX:=IF A > B THEN A ELSE B;
PROCEDURE EVENT(NR,PAR); INTEGER NR,PAR;
IF WANTEVTMESG(NR)
THEN BEGIN
OUTTIME (TIME);
OUTTEXT (EVENTMESG(NR));
OUTINT (PAR,6);
OUTIMAGE;
END;
PROCEDURE OUTTIME (T); REAL T;
BEGIN
REAL HOURS, MINS, SECS;
HOURS:=ENTIER(T/3600);
MINS:=ENTIER((T-HOURS*3600)/60);
SECS:=T-HOURS*3600 - MINS*60;
OUTINT (HOURS,2);
OUTTEXT(":");
OUTINT (MINS,2);
OUTTEXT(":");
OUTFIX (SECS,4,7);
OUTTEXT (" ");
END;
PROCEDURE SCHEDMESG(J,T); REF(JOB)J; REAL T;
IF WANTEVTMESG(17) THEN
BEGIN
OUTTIME (TIME);
OUTTEXT ("JOB ");
OUTINT(J.I, 3);
OUTTEXT(" RUNS FOR ");
OUTFIX(T,3,5);
OUTIMAGE;
END;
PROCEDURE HISEGMESG (J,H); INTEGER J,H;
IF WANTEVTMESG (25) THEN
BEGIN
OUTTIME (TIME);
OUTTEXT ("JOB ");
OUTINT (J,3);
OUTTEXT (" GETS HISEG ");
OUTINT (H,6);
OUTIMAGE;
END;
PROCEDURE INITEVENTARRAY;
BEGIN
REF(INFILE) EVT;
TEXT EVTBUF;
INTEGER I,EVENTPAR;
EVT:-NEW INFILE("EVENTS");
EVTBUF:-BLANKS(80);
EVT.OPEN (EVTBUF);
EVT.INIMAGE;
I:= 1;
INSPECT EVT DO
WHILE NOT ENDFILE DO
BEGIN
EVENTPAR:=ININT;
WANTEVTMESG(I):= (IF EVENTPAR > 0 THEN TRUE ELSE FALSE);
EVENTMESG(I):-INTEXT(26);
I:=I+1;
INIMAGE;
END;
EVT.CLOSE;
END ***INITEVENTARRAY***;
PROCEDURE INITHISEGS;
BEGIN
REF (HISEG) H;
HISEGCHAIN:-NEW HEAD;
NULLHISEG:-NEW HISEG(1000);
INSPECT NULLHISEG DO
BEGIN
SIZE:=0;
SGNAME:-COPY("NONE ");
INCORE:=TRUE;
END;
H:-NEW HISEG(1001);
H.SGNAME:-COPY("TECO ");
H.SWAPPEDSIZE:=H.SIZE:=7;
H.INCORE:=FALSE;
H.INTO (HISEGCHAIN);
H:-NEW HISEG (1002);
H.SGNAME:-COPY ("PIP ");
H.SWAPPEDSIZE:=H.SIZE:=9;
H.INCORE:=FALSE;
H.INTO (HISEGCHAIN);
H:-NEW HISEG (1003);
H.SGNAME:-COPY("SOS ");
H.SWAPPEDSIZE:=H.SIZE:=15;
H.INCORE:=FALSE;
H.INTO (HISEGCHAIN);
H:-NEW HISEG (1004);
H.SGNAME:-COPY("EDITS ");
H.SWAPPEDSIZE:=H.SIZE:=15;
H.INCORE:=FALSE;
H.INTO (HISEGCHAIN);
H:-NEW HISEG (1005);
H.SGNAME:-COPY("DIRECT");
H.SWAPPEDSIZE:=H.SIZE:=19;
H.INCORE:=FALSE;
H.INTO (HISEGCHAIN);
H:-NEW HISEG (1006);
H.SGNAME:-COPY("BASIC ");
H.SWAPPEDSIZE:=H.SIZE:=25;
H.INCORE:=FALSE;
H.INTO (HISEGCHAIN);
END;
LINK CLASS IOREQ;
BEGIN
PROCEDURE INIT;
BEGIN
DRIVENR:=RANDINT(1,NRDRIVES, RANDOMVAR);
DRIVE:-DRIVELIST(DRIVENR);
BLK:=RANDINT(1, DISKSIZE, RANDOMVAR);
CYL:=BLK/BLKSPERCYL;
SECTOR:=BLK - ENTIER(BLK/BLKSPERTRACK)*BLKSPERTRACK;
END ***INIT***;
INTEGER DRIVENR, BLK, NRBLKS, CYL, SECTOR;
REF (DISKDRIVE) DRIVE;
REF (IOPROCESS) OWNER;
END ***CLASS IOREQ ***;
PROCESS CLASS DISKDRIVE;
BEGIN
REAL PROCEDURE LATENCY;
BEGIN
REAL T,SECTOR, DIST;
T:=TIME*BLKSPERSEC;
SECTOR:= T - ENTIER(T/BLKSPERTRACK)*BLKSPERTRACK;
DIST:=(IF SECTOR < R.SECTOR THEN R.SECTOR - SECTOR
ELSE R.SECTOR - SECTOR + BLKSPERTRACK);
LATENCY:=DIST/BLKSPERSEC;
END ***PROCEDURE LATENCY***;
INTEGER NR;
REF (CONTROLLER) MYKON;
REF(CHANNEL) MYCHAN;
BOOLEAN DOINGSEEK, WAITINGXFER, SEARCHING, DOINGXFER;
INTEGER SEEKS, XFERS, BLOCKS;
INTEGER CURCYL, TARGETCYL, DIST, BESTDIST;
REF(HEAD) POSWAITQUEUE;
REF(IOREQ) R, BESTREQ;
POSWAITQUEUE:-NEW HEAD;
WHILE NOT F.ENDFILE OR REQSPENDING > 0 DO
BEGIN
IF POSWAITQUEUE.EMPTY OR MYKON.BUSY THEN PASSIVATE
ELSE
BEGIN
R:-POSWAITQUEUE.FIRST;
BESTREQ:-NONE;
BESTDIST:=NRCYL+1;
WHILE NOT R == NONE DO
BEGIN
DIST:=ABS(R.CYL - CURCYL);
IF DIST < BESTDIST
THEN BEGIN
BESTDIST:=DIST;
BESTREQ:- R;
END;
R:-R.SUC;
END;
R:-BESTREQ;
R.OUT;
TARGETCYL:=R.CYL;
IF BESTDIST > 0
THEN BEGIN
DOINGSEEK:=TRUE;
EVENT (12,NR);
HOLD (SEEKSTART + SEEKCYL*BESTDIST);
DOINGSEEK:=FALSE;
CURCYL:=TARGETCYL;
EVENT (13,NR);
SEEKS:=SEEKS + 1;
END;
WAITINGXFER:=TRUE;
R.INTO (MYCHAN.XFERWAITQUEUE);
ACTIVATE (MYCHAN) AFTER THIS PROCESS;
PASSIVATE;
XFERS:=XFERS+1;
END;
END ***WHILE NOT F.ENDFILE ***;
HOLD (100000);
END ***PROCESS DISKDRIVE***;
CLASS CONTROLLER (NRDRIVES); INTEGER NRDRIVES;
BEGIN
BOOLEAN BUSY;
REF(CHANNEL) MYCHAN;
REF(DISKDRIVE) ARRAY DRIVELIST(1:NRDRIVES);
END;
PROCESS CLASS CHANNEL (NRKON); INTEGER NRKON;
BEGIN
BOOLEAN SEARCHING, DOINGXFER;
REF(IOREQ) R, BESTREQ;
REF (HEAD) XFERWAITQUEUE;
REF(CONTROLLER) ARRAY KONLIST (1:NRKON);
INTEGER I;
REAL LATENCY, BESTSOFAR;
XFERWAITQUEUE:-NEW HEAD;
WHILE NOT F.ENDFILE OR REQSPENDING > 0 DO
BEGIN
IF XFERWAITQUEUE.EMPTY THEN PASSIVATE
ELSE
BEGIN
R:-XFERWAITQUEUE.FIRST;
BESTREQ:-NONE;
BESTSOFAR:=1000000;
WHILE NOT R == NONE DO
BEGIN
LATENCY:=R.DRIVE.LATENCY;
IF LATENCY < BESTSOFAR
THEN BEGIN
BESTSOFAR:=LATENCY;
BESTREQ:-R;
END;
R:-R.SUC;
END;
R:-BESTREQ;
R.OUT;
LATENCY:=BESTSOFAR;
R.DRIVE.MYKON.BUSY:=TRUE;
R.DRIVE.WAITINGXFER:=FALSE;
R.DRIVE.SEARCHING:=SEARCHING:=TRUE;
R.NRBLKS:=NRBUFFERS - R.OWNER.J.FULLBUFS;
IF R.NRBLKS > R.OWNER.J.BLKSNEEDED - R.OWNER.J.FULLBUFS
THEN R.NRBLKS:= R.OWNER.J.BLKSNEEDED - R.OWNER.J.FULLBUFS;
EVENT(14,R.DRIVE.NR);
HOLD (LATENCY);
R.DRIVE.SEARCHING:=SEARCHING:=FALSE;
R.DRIVE.DOINGXFER:=DOINGXFER:=TRUE;
EVENT (8,R.DRIVE.NR);
HOLD (R.NRBLKS/BLKSPERSEC);
R.DRIVE.DOINGXFER:=DOINGXFER:=FALSE;
R.DRIVE.MYKON.BUSY:=FALSE;
R.DRIVE.BLOCKS:=R.DRIVE.BLOCKS + R.NRBLKS;
EVENT (9,R.DRIVE.NR);
ACTIVATE(R.OWNER);
INSPECT R.DRIVE.MYKON DO
FOR I:= 1 STEP 1 UNTIL NRDRIVES DO
ACTIVATE DRIVELIST(I) ;
END;
END ***WHILE STATEMENT***;
HOLD (100000);
END ***CLASS CHANNEL ***;
PROCEDURE INITDISKDATA;
BEGIN
INTEGER I, J, K, DRIVENR, NRKON, NRDRIVES;
REF(CHANNEL)C;
REF(CONTROLLER)KON;
REF(DISKDRIVE)D;
DRIVENR:= 1;
FOR I:= 1 STEP 1 UNTIL NRCHAN DO
BEGIN
C:-NEW CHANNEL(KONPERCHAN);
CHANLIST(I):-C;
ACTIVATE C;
NRKON:=C.NRKON;
FOR J := 1 STEP 1 UNTIL NRKON DO
BEGIN
KON:-NEW CONTROLLER(DRIVESPERKON);
C.KONLIST(J):-KON;
KON.MYCHAN:-C;
NRDRIVES:=KON.NRDRIVES;
FOR K:= 1 STEP 1 UNTIL NRDRIVES DO
BEGIN
D:- NEW DISKDRIVE;
KON.DRIVELIST(K):- D;
D.MYKON:-KON;
D.MYCHAN:-C;
D.NR:=DRIVENR;
DRIVELIST(DRIVENR):-D;
DRIVENR:=DRIVENR+1;
ACTIVATE D;
END;
END;
END;
OUTTEXT ("DISK DATA INITED");
OUTIMAGE;
END ***INIT DISKDATA ***;
LINK CLASS REQUEST;
BEGIN
REAL CPUTIME, DISKBLKS, KCT, THINKTIME;
REAL STARTTIME,SERVICETIME, JOBNR, CORE, TIMEIN;
TEXT PROGRAM;
END;
HEAD CLASS QUEUE;
BEGIN
PROCEDURE UPDATE;
BEGIN
SUM:= SUM + CARDINAL*(TIME - LASTCHANGE);
LASTCHANGE:=TIME;
END;
TEXT QNAME;
REAL LASTCHANGE, SUM;
END;
REF (REQUEST) PROCEDURE NEXTREQ;
BEGIN
REF (REQUEST) REQ;
REQ:-NEW REQUEST;
REQSPENDING:=REQSPENDING + 1;
INSPECT F DO
BEGIN
INSPECT REQ DO
BEGIN
STARTTIME:=ININT/60;
THINKTIME:=ININT/60;
SERVICETIME:=ININT/60;
INCHAR;
PROGRAM:-INTEXT(6);
CORE:=ININT;
CPUTIME:=ININT/60;
JOBNR:=ININT;
DISKBLKS:=ININT;
IF CORE > TOTUSERCORE THEN
BEGIN
OUTTEXT ("ERR -- REQ WITH SIZE > TOTAL USER CORE");
OUTIMAGE;
OUTTEXT ("CONTINUING WITH SIZE - TOTAL USER CORE ");
OUTIMAGE;
CORE:=TOTUSERCORE;
END;
IF STARTTIME < LASTSTARTTIME
THEN BEGIN
OUTTEXT ("ERR -- INPUT RECORDS OUT OF ORDER");
OUTIMAGE;
GOTO ENDRUN;
END
ELSE LASTSTARTTIME:=STARTTIME;
END;
INIMAGE;
END;
NEXTREQ:-REQ;
END;
PROCEDURE ASSIGN(SEG); REF (SEGMENT) SEG;
BEGIN
REAL INCREASE;
INCREASE:=SEG.SIZE - SEG.COREASSIGNED;
IF INCREASE > FREECORE THEN
OUTTEXT ("ERR IN ASSIGN -- SEG TOO LARGE")
ELSE FREECORE:=FREECORE - INCREASE;
IF SEG.BEINGSWAPPED THEN
BEGIN
OUTTEXT("ERR --SEG ASSIGNED CORE WHILE BEING SWAPPED");
OUTIMAGE;
END;
EVENT (20, SEG.I);
SEG.COREASSIGNED:=SEG.SIZE;
END;
PROCEDURE DEASSIGN (SEG); REF(SEGMENT) SEG;
BEGIN
IF SEG.BEINGSWAPPED THEN
BEGIN
OUTTEXT ("ERR -- SEG DEASSIGNED WHILE BEING SWAPPED");
OUTIMAGE;
END;
IF SEG.INCORE
THEN SEG.INCORE:=FALSE
ELSE BEGIN
OUTTEXT ("ERR--DEASSING FOR SEG NOT IN CORE");
OUTIMAGE;
END;
FREECORE:=FREECORE + SEG.COREASSIGNED;
SEG.COREASSIGNED:=0;
EVENT (21,SEG.I);
END;
PROCESS CLASS SCANNER;
BEGIN
REF (JOB) J;
BOOLEAN RESTART;
PROCEDURE SCANFOR(Q); REF(QUEUE)Q;
IF NOT RESTART THEN
BEGIN
J:-Q.FIRST;
WHILE J =/= NONE AND NOT RESTART DO
BEGIN
PASSIVATE;
J:-J.SUC;
END;
END ***SCANFOR***;
PROCEDURE SCANBACK (Q); REF(QUEUE) Q;
IF NOT RESTART THEN
BEGIN
J:-Q.LAST;
WHILE J =/= NONE AND NOT RESTART DO
BEGIN
PASSIVATE;
J:-J.PRED;
END;
END ***SCANBACK***;
END ***CLASS SCANNER ***;
PROCESS CLASS SEGMENT(I); INTEGER I;
BEGIN
TEXT SGNAME;
REAL SIZE, COREASSIGNED,SWAPPEDSIZE;
BOOLEAN INCORE, BEINGSWAPPED, EXPANDING;
END;
SEGMENT CLASS HISEG;
BEGIN
INTEGER INCORECNT;
BOOLEAN PROCEDURE INSWAPPABLE;
INSWAPPABLE:= NOT INCORE;
BOOLEAN PROCEDURE OUTSWAPPABLE;
BEGIN
OUTSWAPPABLE:=( IF INCORECNT > 0
THEN FALSE
ELSE IF COREASSIGNED = 0
THEN FALSE
ELSE TRUE);
IF SWAPPER.INJOB =/= NONE
THEN BEGIN
IF SWAPPER.INJOB.H == THIS HISEG
THEN OUTSWAPPABLE:=FALSE;
END;
END ***OUTSWAPPABLE***;
END ***HISEG***;
SEGMENT CLASS JOB;
BEGIN
BOOLEAN PROCEDURE SWAPWAIT;
SWAPWAIT:=NOT INCORE OR BEINGSWAPPED OR EXPANDING
OR NOT H.INCORE OR H.BEINGSWAPPED;
BOOLEAN PROCEDURE RUNNABLE;
RUNNABLE:= INCORE AND NOT BEINGSWAPPED AND NOT EXPANDING
AND NOT IOWAIT
AND H.INCORE AND NOT H.BEINGSWAPPED;
BOOLEAN PROCEDURE INSWAPPABLE;
INSWAPPABLE:=NOT INCORE OR EXPANDING OR NOT H.INCORE;
BOOLEAN PROCEDURE OUTSWAPPABLE;
OUTSWAPPABLE:= ( IF NOT INCORE THEN FALSE
ELSE IF BEINGSWAPPED THEN FALSE
ELSE IF PROTECTTIME > TIME THEN FALSE
ELSE TRUE);
PROCEDURE MYHISEG;
BEGIN
REF (HISEG) H1;
H:-NULLHISEG;
H1:-HISEGCHAIN.FIRST;
WHILE H1 =/= NONE DO
BEGIN
IF H1.SGNAME = R.PROGRAM THEN
BEGIN
H:-H1;
H1:-NONE;
END
ELSE H1:-H1.SUC;
END ***WHILE H1=/=NONE;
END ***MYHISEG***;
PROCEDURE MYNEXTREQ;
BEGIN
NEXTREQTIME:=0;
INSPECT R DO NEXTREQTIME:=STARTTIME + THINKTIME + SERVICETIME;
WHILE REQSTACK(I).EMPTY AND NOT F.ENDFILE AND
(IF R =/= NONE THEN R.STARTTIME < NEXTREQTIME + 10 ELSE TRUE )DO
BEGIN
R:-NEXTREQ;
IF JOBLIST(R.JOBNR).STARTED
THEN R.INTO(REQSTACK (R.JOBNR))
ELSE BEGIN
OUTTEXT ("ERR -- REQ FOR JOB THAT WAS NOT STARTED");
OUTIMAGE;
OUTTEXT ("DURING JOB INITIALIZATION");
OUTIMAGE;
OUTTEXT ("RECORDS OUT OF ORDER ?");
OUTIMAGE;
OUTTEXT ("CONTINUING -- THAT REQ IGNORED");
REQSPENDING:=REQSPENDING - 1;
END;
END;
R:-REQSTACK(I).FIRST;
IF R == NONE THEN EVENT(28,I)
ELSE
BEGIN
R.OUT;
HOLD (R.THINKTIME);
EVENT (18,I);
R.TIMEIN:=TIME;
WHILE BEINGSWAPPED DO HOLD (.1);
IF MYQUEUE =/= STOPQ THEN
BEGIN
OUTTEXT ("ERR -- REQ FOR JOB NOT IN STOP Q");
OUTIMAGE;
END;
IF R.PROGRAM = SGNAME
THEN BEGIN
SIZE:=R.CORE - H.SIZE;
IF SIZE < 1 THEN SIZE:=1;
IF INCORE
THEN BEGIN
IF COREASSIGNED < SIZE
THEN BEGIN
IF FREECORE < SIZE - COREASSIGNED
THEN EXPANDING:=TRUE
ELSE ASSIGN (THIS SEGMENT);
END;
IF COREASSIGNED > SIZE THEN ASSIGN (THIS SEGMENT);
END
ELSE IF SIZE < SWAPPEDSIZE THEN SWAPPEDSIZE:=SIZE;
END
ELSE BEGIN
IF INCORE
THEN BEGIN
H.INCORECNT:=H.INCORECNT-1;
SIZE:=1;
ASSIGN(THIS SEGMENT);
MYHISEG;
H.INCORECNT:=H.INCORECNT+1;
SIZE:=R.CORE - H.SIZE;
IF SIZE < 1 THEN SIZE:=1;
IF FREECORE < SIZE - COREASSIGNED
THEN EXPANDING:= TRUE
ELSE ASSIGN (THIS SEGMENT);
END
ELSE BEGIN
MYHISEG;
SIZE:=R.CORE - H.SIZE;
IF SIZE < 1 THEN SIZE:= 1;
SWAPPEDSIZE:=1;
END;
SGNAME:-COPY(R.PROGRAM);
HISEGMESG(I,H.I);
IO.REQ.INIT;
END;
END;
END ***MYNEXTREQ***;
PROCEDURE REQUEUE (POS, Q, QUANT); INTEGER POS; REF (QUEUE) Q;
REAL QUANT;
BEGIN
MYQUEUE.UPDATE;
Q.UPDATE;
MYQUEUE:-Q;
IF POS=FRONT THEN FOLLOW (Q)
ELSE INTO (Q);
CPUQUANTUMLEFT:=QUANT;
IF WANTEVTMESG(22)
THEN BEGIN
OUTTIME (TIME);
OUTTEXT ("JOB ");
OUTINT (I,3);
OUTTEXT (" MOVED TO ");
IF POS = FRONT THEN OUTTEXT ("FRONT OF ")
ELSE OUTTEXT ("REAR OF ");
OUTTEXT (Q.QNAME);
OUTIMAGE;
END;
END;
PROCEDURE QUANTUMREQUEUE;
BEGIN
IF MYQUEUE==PQ1 OR MYQUEUE==PQ3 THEN
REQUEUE (REAR, PQ2,COMPQUANT)
ELSE REQUEUE (REAR, PQ3, COMPQUANT);
END ***QUANTUMREQUEUE***;
PROCEDURE UPDATEACTCNT;
BEGIN
INTEGER I;
REAL T;
I:=NRACTIVENOW;
T:=TIME - ACTCHNGTIME;
ACTJOBWT(I):=ACTJOBWT(I) + T;
TOTACTIVE:=TOTACTIVE + T;
SUMACTIVE:=SUMACTIVE + I*T;
ACTCHNGTIME:=TIME;
END ***UPDATEACTCNT***;
! **************** MAIN SECTION OF CLASS JOB *****************;
REF(HISEG) H;
REF(REQUEST)R;
REF(QUEUE)MYQUEUE;
REF (IOPROCESS) IO;
REAL NEXTREQTIME;
REAL FULLBUFS, BLKSNEEDED, CPUTIMENEEDED, CPUB4IO, CPUPERBLK;
BOOLEAN IOACTIVE,IODONE, IOWAIT, STARTED, NEEDSREQUEUE;
REAL CPUQUANTUMLEFT, PROTECTTIME;
IO:-NEW IOPROCESS (THIS JOB);
ACTIVATE IO;
STARTED:=TRUE;
INCORE:=FALSE;
REQUEUE (REAR, STOPQ, 0);
MYNEXTREQ;
WHILE R =/= NONE DO
BEGIN
FULLBUFS:=0;
IF R.DISKBLKS = 0 THEN
BEGIN
BLKSNEEDED:=0;
CPUTIMENEEDED:=CPUPERBLK:=R.CPUTIME;
CPUB4IO:=R.CPUTIME+1000000;
END
ELSE BEGIN
BLKSNEEDED:=R.DISKBLKS;
IF R.CPUTIME = 0 THEN R.CPUTIME:=.01;
!MUST HAVE CPU PER BLK > 0 OR
DISPATCHER WILL BE CONFUSED;
CPUPERBLK:=R.CPUTIME/R.DISKBLKS;
CPUB4IO:=CPUPERBLK/2;
CPUTIMENEEDED:=R.CPUTIME;
END;
REQUEUE (FRONT, PQ1, INITIALQUANT);
UPDATEACTCNT;
NRACTIVENOW:=NRACTIVENOW + 1;
PASSIVATE;
EVENT(19,I);
REQSPENDING:=REQSPENDING - 1;
UPDATEACTCNT;
NRACTIVENOW:=NRACTIVENOW - 1;
MYNEXTREQ;
END ***WHILE R =/= NONE***;
HOLD (100000);
END ***CLASS JOB***;
PROCESS CLASS IOPROCESS (J); REF(JOB) J;
BEGIN
REF(IOREQ) REQ;
REQ:-NEW IOREQ;
REQ.OWNER:-THIS IOPROCESS;
REQ.INIT;
PASSIVATE;
WHILE J.R =/= NONE DO
BEGIN
EVENT (10,J.I);
WHILE J.FULLBUFS < NRBUFFERS AND J.BLKSNEEDED > J.FULLBUFS DO
BEGIN
J.IOACTIVE:=TRUE;
EVENT (24,J.I);
REQ.INTO(REQ.DRIVE.POSWAITQUEUE);
ACTIVATE REQ.DRIVE AFTER THIS PROCESS;
PASSIVATE;
J.FULLBUFS:= J.FULLBUFS + REQ.NRBLKS;
IF J.IOWAIT
THEN BEGIN
J.IODONE:=TRUE;
J.NEEDSREQUEUE:=TRUE;
END;
END *** WHILE J.FULLBUFS < NRBUFFERS ***;
J.IOACTIVE:=FALSE;
EVENT (11,J.I);
PASSIVATE;
END ***WHILE J.R =/= NONE ***;
HOLD (100000);
END CLASS IOPROCESS;
!*******************************************************************
SWAPPER
**********************************************************************;
SCANNER CLASS OSCANOBJ;
WHILE RESTART DO
BEGIN
RESTART:=FALSE;
SCANBACK (STOPQ);
SCANBACK(PQ3);
SCANBACK(PQ2);
SCANBACK(PQ1);
WHILE NOT RESTART DO PASSIVATE;
END ***OSCANOBJ***;
SCANNER CLASS ISCANOBJ;
WHILE RESTART DO
BEGIN
RESTART:=FALSE;
SCANFOR(PQ1);
SCANFOR(PQ2);
SCANFOR(PQ3);
WHILE NOT RESTART DO PASSIVATE;
END ***ISCANOBJ***;
PROCESS CLASS SWAPPEROBJ;
BEGIN
PROCEDURE SWAPOUT;
BEGIN
REF (JOB) J;
OSCAN.RESTART:=TRUE;
ACTIVATE OSCAN;
J:-OSCAN.J;
OUTJOB:-NONE;
AVAIL:=0;
BESTSOFAR:=0;
AMTSHORT:=CORENEEDED - FREECORE;
WHILE AVAIL < AMTSHORT AND J =/= NONE AND J =/= INJOB DO
BEGIN
IF J.OUTSWAPPABLE THEN
BEGIN
AVAILHERE:=J.SIZE + J.H.SIZE/J.H.INCORECNT;
AVAIL:=AVAIL + AVAILHERE;
IF AVAILHERE > BESTSOFAR THEN
BEGIN
BESTSOFAR:=AVAILHERE;
OUTJOB:-J;
END;
END;
ACTIVATE OSCAN;
J:-OSCAN.J;
END;
IF AVAIL < AMTSHORT THEN
BEGIN
STUCK:=TRUE;
TIMESSTUCK:=TIMESSTUCK + 1;
OUTJOB:-NONE;
END
ELSE BEGIN
J:-OUTJOB;
EVENT(4,J.I);
J.BEINGSWAPPED:=TRUE;
J.H.INCORECNT:=J.H.INCORECNT-1;
IF J.H.OUTSWAPPABLE THEN
BEGIN
J.H.BEINGSWAPPED:=TRUE;
J.H.SWAPPEDSIZE:=J.H.COREASSIGNED;
EVENT(5,J.H.I);
HOLD (SWAPLATENCY + (J.H.COREASSIGNED/SWAPRATE));
PSWPDOUT:=PSWPDOUT + J.H.COREASSIGNED;
J.H.BEINGSWAPPED:=FALSE;
DEASSIGN(J.H);
END;
WHILE J.IOACTIVE DO PASSIVATE;
J.SWAPPEDSIZE:=J.COREASSIGNED;
EVENT(6,J.I);
HOLD (SWAPLATENCY + (J.COREASSIGNED/SWAPRATE));
XFERSOUT:=XFERSOUT + 1;
PSWPDOUT:=PSWPDOUT + J.COREASSIGNED;
J.EXPANDING:=FALSE;
J.BEINGSWAPPED:=FALSE;
DEASSIGN(J);
END;
END ***SWAPOUT***;
PROCEDURE SWAPIN;
BEGIN
REF(JOB)J;
ISCAN.RESTART:=TRUE;
ACTIVATE ISCAN;
J:-ISCAN.J;
STUCK:=FALSE;
WHILE (IF J =/= NONE THEN NOT J.INSWAPPABLE ELSE FALSE) DO
BEGIN
ACTIVATE ISCAN;
J:-ISCAN.J;
END;
IF J == NONE THEN PASSIVATE
ELSE BEGIN
INJOB:-J;
EVENT(1,J.I);
CORENEEDED:=J.SIZE - J.COREASSIGNED + ( IF NOT J.H.INCORE
THEN J.H.SIZE ELSE 0);
WHILE CORENEEDED > FREECORE AND NOT STUCK DO
SWAPOUT;
IF NOT STUCK THEN
BEGIN
IF NOT J.H.INCORE THEN
BEGIN
ASSIGN(J.H);
J.H.BEINGSWAPPED:=TRUE;
EVENT(2,J.H.I);
HOLD(SWAPLATENCY + J.H.SWAPPEDSIZE/SWAPRATE);
PSWPDIN:=PSWPDIN + J.H.SWAPPEDSIZE;
J.H.BEINGSWAPPED:=FALSE;
J.H.INCORE:=TRUE;
CORENEEDED:=CORENEEDED - INJOB.H.SIZE;
WHILE CORENEEDED > FREECORE AND NOT STUCK DO
SWAPOUT;
END;
END ***IF NOT STUCK***;
IF NOT STUCK THEN
BEGIN
IF NOT J. INCORE THEN
BEGIN
ASSIGN (J);
J.BEINGSWAPPED:=TRUE;
EVENT(3,J.I);
HOLD (SWAPLATENCY + (J.SWAPPEDSIZE/SWAPRATE));
PSWPDIN:=PSWPDIN + J.SWAPPEDSIZE;
XFERSIN:=XFERSIN + 1;
J.BEINGSWAPPED:=FALSE;
J.H.INCORECNT:=J.H.INCORECNT+1;
J.INCORE:=TRUE;
J.PROTECTTIME:=TIME + PROT0 + PROT1*((2*J.SIZE) - 1);
END;
J.EXPANDING:=FALSE;
END
ELSE EVENT(7,J.I);
END;
PASSIVATE;
END ***SWAPIN ***;
BOOLEAN STUCK;
REAL CORENEEDED;
REF(OSCANOBJ) OSCAN;
REF(ISCANOBJ) ISCAN;
REAL AVAIL, AMTSHORT, AVAILHERE,BESTSOFAR;
REF(JOB) INJOB,OUTJOB;
INTEGER TIMESSTUCK, XFERSIN, XFERSOUT;
REAL PSWPDIN, PSWPDOUT;
ISCAN:-NEW ISCANOBJ;
OSCAN:-NEW OSCANOBJ;
WHILE NOT F.ENDFILE OR REQSPENDING > 0 DO
SWAPIN;
HOLD (100000);
END ***SWAPPEROBJ***;
!**********************************************************************
DISPATCHER
**********************************************************************;
SCANNER CLASS SCHEDSCANOBJ;
WHILE RESTART DO
BEGIN
RESTART:=FALSE;
SCANFOR(PQ1);
SCANFOR(PQ2);
SCANFOR(PQ3);
WHILE NOT RESTART DO PASSIVATE;
END **SCHEDSCANOBJ***;
PROCESS CLASS DISPOBJ; !SYSTEM DISPATCHER;
BEGIN
REF (JOB) PROCEDURE NEXTJOB;
BEGIN
BLOCKEDPQJOB:=FALSE;
SCHEDCALLS:=SCHEDCALLS + 1;
SSCANNER.RESTART:=TRUE;
ACTIVATE SSCANNER;
WHILE
(IF SSCANNER.J =/= NONE THEN NOT SSCANNER.J.RUNNABLE
ELSE FALSE) DO
BEGIN
IF J.SWAPWAIT THEN BLOCKEDPQJOB:=TRUE;
ACTIVATE SSCANNER;
END;
IF SSCANNER.J == NONE THEN NEXTJOB:- NULLJOB
ELSE NEXTJOB:-SSCANNER.J;
END ***NEXTJOB ***;
PROCEDURE UPDATEQUEUES;
BEGIN
INTEGER I;
FOR I:= 1 STEP 1 UNTIL MAXJOB DO
BEGIN
J:-JOBLIST(I);
IF J.NEEDSREQUEUE THEN
BEGIN
IF J.IODONE THEN
BEGIN
J.REQUEUE (FRONT, PQ1, IOQUANT);
J.IODONE:=J.IOWAIT:=FALSE;
END
ELSE IF J.IOWAIT
THEN J.REQUEUE (REAR, IOWAITQ, 0);
J.NEEDSREQUEUE:=FALSE;
END;
END;
END ***UPDATEQUEUES ***;
PROCEDURE UPDATETIMES (T,J); REAL T; REF(JOB) J;
!ARGUMENT T IS HOW LONG JOB JUST RAN;
INSPECT J DO
BEGIN
CPUTIMENEEDED:= CPUTIMENEEDED - T;
CPUB4IO:=CPUB4IO - T;
CPUQUANTUMLEFT:=CPUQUANTUMLEFT - T;
TIMETILLTICK:=TIMETILLTICK - T;
END;
PROCEDURE RECORDINT(J); REF(JOB) J;
BEGIN
REAL STRECH, T, T2;
INTEGER I, I2;
INSPECT J.R DO
BEGIN
NRINT:=NRINT + 1;
RESPONSETIME:=TIME - TIMEIN;
IF WANTEVTMESG(29)
THEN BEGIN
OUTTEXT ("RESPONSE TIMES: ");
OUTFIX (SERVICETIME,2,8);
OUTFIX (RESPONSETIME,2,8);
OUTIMAGE;
END;
INSPECT RSLTS DO
BEGIN
OUTFIX (STARTTIME,2,8);
OUTFIX (THINKTIME,2,8);
OUTFIX (SERVICETIME,2,8);
OUTFIX (RESPONSETIME,2,8);
OUTFIX (RESPONSETIME - SERVICETIME,2,8);
OUTTEXT (" ");
OUTTEXT (PROGRAM);
OUTINT (CORE,4);
OUTFIX (CPUTIME,2,8);
OUTINT (JOBNR,4);
OUTINT (DISKBLKS,6);
OUTIMAGE;
END;
RESPTOT:=RESPTOT + RESPONSETIME;
RESPSQTOT:=RESPSQTOT + (RESPONSETIME**2);
ASERVTOT:=ASERVTOT + SERVICETIME;
ASERVSQTOT:=ASERVSQTOT + (SERVICETIME**2);
PRODTOT:=PRODTOT + RESPONSETIME * SERVICETIME;
RESPDIFF:=RESPONSETIME - SERVICETIME;
DIFFTOT:=DIFFTOT + RESPDIFF;
DIFFABSTOT:=DIFFABSTOT + ABS(RESPDIFF);
TOTCPU:=TOTCPU + CPUTIME;
TOTWAIT:=TOTWAIT + RESPONSETIME;
TOTDSK:=TOTDSK + DISKBLKS;
IF RESPONSETIME < 60 THEN
BEGIN
I:= 1;
T:= .5;
END
ELSE BEGIN
I:= 8;
T:= 60;
END;
IF RESPONSETIME < 1920 THEN
BEGIN
WHILE T < RESPONSETIME DO
BEGIN
I:=I+1;
T:=T*2;
END;
END
ELSE I:= 14;
RESPTIMECNT(I):=RESPTIMECNT(I) + 1;
RESPTIMEWT(I):=RESPTIMEWT(I) + CPUTIME;
IF CPUTIME < .4
THEN BEGIN
TOTSHRTCNT:= TOTSHRTCNT + 1;
TOTSHRTWT:=TOTSHRTWT + CPUTIME;
SHRTRESPCNT(I) :=SHRTRESPCNT(I) + 1;
SHRTRESPWT(I) := SHRTRESPWT(I) + CPUTIME;
END
ELSE BEGIN
TOTLONGCNT:=TOTLONGCNT + 1;
TOTLONGWT:=TOTLONGWT + CPUTIME;
LONGRESPCNT(I):=LONGRESPCNT(I) + 1;
LONGRESPWT(I):=LONGRESPWT(I) + CPUTIME;
STRECH:=RESPONSETIME/CPUTIME;
IF STRECH > 80 THEN I2:=7
ELSE BEGIN
T2:=2.5;
I2:=1;
WHILE T2 < STRECH DO
BEGIN
T2:=T2*2;
I2:=I2+1;
END;
END;
RESPCATCNT(I2):=RESPCATCNT(I2) + 1;
RESPCATWT(I2):=RESPCATWT(I2) + CPUTIME;
END;
END ***INSPECT R ***;
END ***RECORDINT ***;
!**********************************************************************
MAIN SECTION OF DISPATCHER
**********************************************************************;
REF(SCHEDSCANOBJ) SSCANNER;
REAL TIMETILLTICK,T,T2;
REF (JOB) J, OLDJOB;
BOOLEAN BLOCKEDPQJOB;
REAL USERTIME, IDLETIME, LOSTTIME, OVERHDTIME;
INTEGER SECTICS, MINSECS;
INTEGER NRACTIVEJOBS,ACTTOT, ACTCNT;
INTEGER CONTEXTSWITCHES, SCHEDCALLS, UUOS, NRINT;
REAL RESPONSETIME;
REAL RESPTOT, RESPDIFF, DIFFTOT, DIFFABSTOT;
REAL RESPSQTOT,ASERVTOT, ASERVSQTOT, PRODTOT;
REAL TOTCPU, TOTWAIT, TOTDSK;
INTEGER ARRAY RESPTIMECNT(1:14);
REAL ARRAY RESPTIMEWT(1:14);
INTEGER ARRAY SHRTRESPCNT (1:14);
INTEGER TOTSHRTCNT;
REAL ARRAY SHRTRESPWT (1:14);
REAL TOTSHRTWT;
INTEGER ARRAY LONGRESPCNT(1:14);
INTEGER TOTLONGCNT;
REAL ARRAY LONGRESPWT (1:14);
REAL TOTLONGWT;
INTEGER ARRAY RESPCATCNT (1:7);
REAL ARRAY RESPCATWT (1:7);
SSCANNER:-NEW SCHEDSCANOBJ;
SECTICS:=-1;
MINSECS:=0;
WHILE NOT F.ENDFILE OR REQSPENDING > 0 DO
BEGIN
EVENT(23,0);
TIMETILLTICK:=(1/60);
SECTICS:=SECTICS + 1;
IF SECTICS = 60
THEN BEGIN
EVENT (26,0);
SECTICS:= 0;
MINSECS:=MINSECS + 1;
IF MINSECS = 60
THEN BEGIN
EVENT (27,0);
MINSECS:= 0;
END;
END;
UPDATEQUEUES;
ACTIVATE SWAPPER;
NRACTIVEJOBS:=PQ1.CARDINAL + PQ2.CARDINAL + PQ3.CARDINAL
+ IOWAITQ.CARDINAL;
ACTTOT:= ACTTOT + NRACTIVEJOBS;
ACTCNT:=ACTCNT + 1;
T:= (1/60)*(OVERHD0 + NRACTIVEJOBS*OVERHD1);
HOLD (T);
OVERHDTIME:=OVERHDTIME + T;
TIMETILLTICK:=TIMETILLTICK - T;
WHILE TIMETILLTICK > 0 DO
BEGIN
IF J =/= NULLJOB THEN OLDJOB:- J;
J:-NEXTJOB;
!RUN THE SELECTED JOB;
IF J =/= OLDJOB AND J =/= NULLJOB
THEN CONTEXTSWITCHES:=CONTEXTSWITCHES + 1;
INSPECT J DO
BEGIN
T:=MIN(TIMETILLTICK,CPUTIMENEEDED);
!T IS MAX TIME JOB CAN RUN BEFORE CLOCK
TICK OR COMPLETION OF REQUEST, ASSUMING
IT DOES NOT HAVE TO WAIT FOR IO;
WHILE T > 0 AND NOT IOWAIT DO
BEGIN
T2:= MIN(T,CPUB4IO);
IF T2 > 0 THEN
BEGIN
SCHEDMESG(J,T2);
!T2 IS TIME UNTIL EITHER RUNTIME EXPIRES
OR JOB NEEDS MORE IO;
HOLD(T2);
IF J =/= NULLJOB THEN USERTIME:= USERTIME + T2
ELSE IF BLOCKEDPQJOB THEN LOSTTIME:=LOSTTIME + T2
ELSE IDLETIME:= IDLETIME + T2;
END;
!NOW WE HAVE EITHER (1) CLOCK TICK, (2) IO REQUEST,
OR (3) INTERACTION COMPLETE;
T:=T - T2;
UPDATETIMES(T2,J);
IF CPUB4IO <= 0
THEN BEGIN
IF FULLBUFS > 0
THEN BEGIN
UUOS:=UUOS+1;
FULLBUFS:=FULLBUFS - 1;
BLKSNEEDED:=BLKSNEEDED - 1;
IF BLKSNEEDED > 0
THEN BEGIN
CPUB4IO:= CPUPERBLK;
IF FULLBUFS <= 1 AND NOT IOACTIVE
THEN ACTIVATE IO;
END
ELSE CPUB4IO:=10000000;
EVENT (15,J.I);
END
ELSE BEGIN
IOWAIT:=TRUE;
NEEDSREQUEUE:=TRUE;
IF NOT IOACTIVE THEN ACTIVATE IO;
EVENT (16, J.I);
END;
END;
END ***WHILE T > 0 AND NOT IOWAIT ***;
IF NOT IOWAIT THEN
BEGIN
IF CPUQUANTUMLEFT <= 0 THEN QUANTUMREQUEUE;
IF CPUTIMENEEDED <= 0 THEN
BEGIN
IF BLKSNEEDED > 0
THEN BEGIN
OUTTEXT ("ERR IN DISPATCHER ");
OUTIMAGE;
OUTTEXT ("STILL NEED IO AT END OF INT");
OUTIMAGE;
END;
J.PROTECTTIME:=0;
J.REQUEUE (REAR, STOPQ, 0);
RECORDINT(J); !UPDATE INTERACTION DATA;
ACTIVATE(J);
END;
END ***IF NOT IOWAIT ***;
END; ! ***INSPECT J DO (I.E. RUN SELECTED JOB) ***;
END ***WHILE TIMTILLTICK > 0 ***;
END ***WHILE NOT F.ENDFILE***;
ENDTIME:=TIME;
HOLD (.01);
FOR I:= 1 STEP 1 UNTIL 6 DO
QUEUELIST(I).UPDATE;
HOLD (100000);
END ***CLASS DISPOBJ ***;
PROCEDURE REPORT;
BEGIN
PROCEDURE RPTHDR;
INSPECT O DO
BEGIN
OUTIMAGE;
OUTIMAGE;
OUTIMAGE;
OUTTEXT(" T O P S - 1 0 S I M U L A T I O N R E P O R T ");
OUTIMAGE;
OUTIMAGE;
OUTIMAGE;
OUTTEXT("TOPS.SIM VERSION ");
OUTINT(VERSION,3);
OUTIMAGE;
OUTTEXT("TRACE FILE: ");
OUTTEXT(FNAME);
OUTIMAGE;
OUTTEXT("PARAMETER FILE: ");
OUTTEXT(PARNAME);
OUTIMAGE;
OUTTEXT("REPORT FILE: ");
OUTTEXT(ONAME);
OUTIMAGE;
OUTTEXT("DETAILED RESULTS FILE: ");
OUTTEXT(RSLTSNAME);
OUTIMAGE;
OUTIMAGE;
OUTIMAGE;
OUTTEXT("TOTAL TIME SIMULATED: ");
OUTFIX(ENDTIME,0,6);
OUTTEXT(" SECONDS");
OUTIMAGE;
OUTIMAGE;
END;
PROCEDURE RPTRSP;
INSPECT O DO
INSPECT DISPATCHER DO
BEGIN
INTEGER N,I;
REAL CORREL, SUM, S;
N:=NRINT;
OUTIMAGE;
OUTIMAGE;
OUTTEXT ("NR INTERACTIONS: ");
OUTINT (N,6);
OUTIMAGE;
OUTIMAGE;
OUTTEXT ("AVE DIFF: ");
OUTFIX (DIFFTOT/N, 3, 8);
OUTIMAGE;
OUTTEXT ("AVE ABS DIFF: ");
OUTFIX (DIFFABSTOT/N, 3, 8);
OUTIMAGE;
OUTTEXT("CORREL COEF: ");
CORREL:=(PRODTOT - (RESPTOT*ASERVTOT)/N) /
SQRT((RESPSQTOT - (RESPTOT**2)/N) * (ASERVSQTOT - (ASERVTOT**2)/N));
OUTFIX (CORREL, 2, 6);
OUTIMAGE;
OUTIMAGE;
OUTTEXT("NR JOBS ");
OUTINT (MAXJOBNR,3);
OUTIMAGE ;
OUTTEXT("TOTAL CPU TIME ");
OUTFIX (TOTCPU,3,8);
OUTTEXT(" = ");
OUTFIX (100*TOTCPU/ENDTIME,1,5);
OUTTEXT(" % USER ");
OUTIMAGE ;
OUTTEXT("TOTAL DSK BLKS ");
OUTINT (TOTDSK, 6);
OUTTEXT(" = ");
OUTFIX (TOTDSK/ENDTIME, 0,4);
OUTTEXT(" BLKS/SEC ");
OUTIMAGE ;
OUTTEXT("TOTAL USER WAIT TIME ");
OUTFIX (TOTWAIT,0,6);
OUTTEXT( " SEC = ");
OUTFIX (TOTWAIT/MAXJOBNR,0,6);
OUTTEXT(" SEC PER USER ");
OUTIMAGE ;
OUTIMAGE ;
OUTTEXT("NR ACTIVE JOBS");
OUTIMAGE;
OUTTEXT(" NR % CUMULATIVE ");
OUTIMAGE ;
SUM:= 0;
FOR I:= 0 STEP 1 UNTIL 19 DO
IF SUM < TOTACTIVE THEN
BEGIN
OUTINT (I,8);
OUTFIX (100*ACTJOBWT(I)/TOTACTIVE,1,8);
SUM:=SUM + ACTJOBWT(I);
OUTFIX (100*SUM/TOTACTIVE,1,8);
OUTIMAGE ;
END;
OUTIMAGE ;
OUTTEXT("AVE NR ACTIVE JOBS =");
OUTFIX (SUMACTIVE/TOTACTIVE,1,5);
OUTIMAGE ;
OUTIMAGE ;
BEGIN
PROCEDURE RESPREP (CNT, WT, CNTTOT, WTTOT);
INTEGER ARRAY CNT;
REAL ARRAY WT;
INTEGER CNTTOT;
REAL WTTOT;
BEGIN
INTEGER I, CUMCNT;
REAL T, CUMWT;
IF CNTTOT > 0 THEN
BEGIN
OUTTEXT (" NR % CUM %CPU CUM");
OUTIMAGE;
CUMCNT:=CUMWT:= 0;
FOR I:= 1 STEP 1 UNTIL 14 DO
IF CUMCNT < CNTTOT THEN
BEGIN
IF I < 8 THEN
BEGIN
OUTFIX (.5*(2**(I-1)),1,6);
OUTTEXT (" SEC ");
END
ELSE BEGIN
OUTFIX (2**(I-8),1,6);
OUTTEXT (" MIN ");
END;
OUTINT (CNT(I),8);
OUTFIX (100*CNT(I)/CNTTOT,1,8);
CUMCNT:= CUMCNT + CNT(I);
OUTFIX (100*CUMCNT/CNTTOT,1,8);
IF WTTOT > 0 THEN
BEGIN
OUTFIX (100*WT(I)/WTTOT,1,8);
CUMWT:=CUMWT + WT(I);
OUTFIX (100*CUMWT/WTTOT,1,8);
END;
OUTIMAGE ;
END;
OUTTEXT (" ");
OUTINT(CNTTOT,8);
OUTIMAGE;
OUTIMAGE ;
OUTIMAGE ;
END;
END ***PROCEDURE RESPREP***;
OUTTEXT ("RESPONSE TIMES -- ALL INTERACTIONS ");
OUTIMAGE ;
OUTIMAGE ;
RESPREP (RESPTIMECNT, RESPTIMEWT, NRINT, TOTCPU);
OUTTEXT ("RESPONSE TIMES -- INTERACTIONS < .4 SEC CPUTIME ");
OUTIMAGE ;
OUTIMAGE ;
RESPREP (SHRTRESPCNT, SHRTRESPWT, TOTSHRTCNT, TOTSHRTWT);
OUTIMAGE ;
OUTIMAGE ;
OUTTEXT ("RESPONSE TIMES -- INTERACTIONS > .4 SEC CPUTIME ");
OUTIMAGE ;
OUTIMAGE ;
RESPREP (LONGRESPCNT, LONGRESPWT, TOTLONGCNT, TOTLONGWT);
OUTIMAGE ;
OUTIMAGE ;
END;
OUTTEXT ("STRETCH FACTORS -- INTERACTIONS > .4 SEC CPU TIME");
OUTIMAGE ;
OUTTEXT ("FACTOR NR % CUM WT% CUM ");
OUTIMAGE;
S:=T:=0;
FOR I:= 1 STEP 1 UNTIL 7 DO
IF S < TOTLONGCNT THEN
BEGIN
OUTFIX (2.5*(2**I),1,6);
OUTINT(RESPCATCNT(I),6);
OUTFIX (100*RESPCATCNT(I)/TOTLONGCNT,1,8);
S:=S + RESPCATCNT(I);
OUTFIX (100*S/TOTLONGCNT,1,8);
OUTFIX (100*RESPCATWT(I)/TOTLONGWT,1,8);
T:=T + RESPCATWT(I);
OUTFIX (100*T/TOTLONGWT,1,8);
OUTIMAGE;
END;
OUTIMAGE ;
OUTIMAGE ;
END ***RPTRST***;
PROCEDURE RPTCPU;
INSPECT O DO
INSPECT DISPATCHER DO
BEGIN
OUTIMAGE;
OUTIMAGE;
OUTTEXT ("CPU UTILIZATION");
OUTIMAGE;
OUTIMAGE;
OUTTEXT ("% IDLE: ");
OUTFIX (100*IDLETIME/ENDTIME, 1, 6);
OUTIMAGE;
OUTTEXT ("% LOST: ");
OUTFIX (100*LOSTTIME/ENDTIME, 1,6);
OUTIMAGE;
OUTTEXT ("% OVHD: ");
OUTFIX (100*OVERHDTIME/ENDTIME,1,6);
OUTIMAGE;
OUTTEXT ("% USER: ");
OUTFIX (100*USERTIME/ENDTIME, 1,6);
OUTIMAGE;
OUTIMAGE;
OUTTEXT ("SCHEDULER CALLS: ");
OUTINT (SCHEDCALLS, 6);
OUTIMAGE;
OUTTEXT("CONTEXT SWITCHES: ");
OUTINT (CONTEXTSWITCHES, 6);
OUTIMAGE;
OUTTEXT ("UUOS: ");
OUTINT (UUOS,6);
OUTIMAGE;
OUTIMAGE;
END ***RPTCPU***;
PROCEDURE RPTSWP;
INSPECT O DO
BEGIN
OUTTEXT ("SWAPPING DATA");
OUTIMAGE;
OUTIMAGE;
OUTTEXT ("INPUT TRANSFERS: ");
OUTINT (SWAPPER.XFERSIN,6);
OUTIMAGE;
OUTTEXT ("PAGES SWAPPED IN: ");
OUTFIX (SWAPPER.PSWPDIN,0,6);
OUTIMAGE;
OUTTEXT ("OUTPUT TRANSFERS: ");
OUTINT (SWAPPER.XFERSOUT,6);
OUTIMAGE;
OUTTEXT ("PAGES SWAPPED OUT: ");
OUTFIX (SWAPPER.PSWPDOUT,0,6);
OUTIMAGE;
OUTTEXT ("TIMES STUCK: ");
OUTINT (SWAPPER.TIMESSTUCK,6);
OUTIMAGE;
OUTIMAGE;
END ***PROCEDURE RPTSWP***;
PROCEDURE RPTQUEUELEN;
INSPECT O DO
BEGIN
OUTTEXT("AVE QUEUE LENGTHS ");
OUTIMAGE;
OUTIMAGE;
FOR I:= 1 STEP 1 UNTIL 6 DO
BEGIN
INSPECT QUEUELIST(I) DO
BEGIN
OUTTEXT (QNAME);
IF LASTCHANGE > 0 THEN
OUTFIX (SUM/LASTCHANGE,3,8)
ELSE OUTFIX (0,3,8);
OUTIMAGE;
END;
END;
OUTIMAGE;
END ***RPTQUEUELEN ***;
PROCEDURE RPTDISK;
INSPECT O DO
BEGIN
REF(CHANNEL) C;
REF(CONTROLLER) KON;
REF(DISKDRIVE)D;
INTEGER I, J, K, NRKON, NRDRIVES;
INTEGER SEEKTOT, XFERTOT, BLOCKTOT;
OUTTEXT ("DISK STATISTICS ");
OUTIMAGE;
OUTIMAGE;
FOR I:= 1 STEP 1 UNTIL NRCHAN DO
BEGIN
C:-CHANLIST(I);
NRKON:=C.NRKON;
FOR J:= 1 STEP 1 UNTIL NRKON DO
BEGIN
KON:-C.KONLIST(J);
NRDRIVES:=KON.NRDRIVES;
FOR K:= 1 STEP 1 UNTIL NRDRIVES DO
BEGIN
D:-KON.DRIVELIST(K);
SEEKTOT:=SEEKTOT + D.SEEKS;
XFERTOT:=XFERTOT + D.XFERS;
BLOCKTOT:= BLOCKTOT + D.BLOCKS;
END;
END;
END;
OUTTEXT ("SEEKS: ");
OUTINT (SEEKTOT,5);
OUTIMAGE;
OUTTEXT ("TRANSFERS: ");
OUTINT (XFERTOT,5);
OUTIMAGE;
OUTTEXT ("BLOCKS: ");
OUTINT (BLOCKTOT,5);
OUTIMAGE;
END ***RPTDISK ***;
!MAIN SECTION OF PROCEDURE REPORT;
OUTTEXT ("TOTAL TIME SIMULATED = ");
OUTTIME (ENDTIME);
INSPECT O DO
BEGIN
RPTHDR;
RPTRSP;
RPTCPU;
RPTSWP;
RPTDISK;
END;
END ***PROCEDURE REPORT***;
!**********************************************************************
**********************************************************************
*********************************************************************
STARTING MAIN PROGRAM
**********************************************************************
**********************************************************************
********************************************************************;
INTEGER RANDOMVAR,I,J, DRIVENR;
TEXT BUFFER, EBUF, FNAME;
REF (DISPOBJ) DISPATCHER;
REF (SWAPPEROBJ) SWAPPER;
REF (QUEUE) PQ1,PQ2,PQ3,STOPQ,IOWAITQ,NULLQ;
REF (INFILE) F;
REF (OUTFILE) ERRFILE;
REF (REQUEST) R;
REF (HEAD) HISEGCHAIN;
REF (CHANNEL) ARRAY CHANLIST (1:8);
REF (DISKDRIVE) ARRAY DRIVELIST (1:64);
REF(HEAD) ARRAY REQSTACK (1:MAXJOB);
REF(JOB) ARRAY JOBLIST (1:MAXJOB);
REF (QUEUE) ARRAY QUEUELIST (1:6);
REF(HISEG) NULLHISEG;
REF(JOB) NULLJOB;
REF(CHANNEL) C;
REF(DISKDRIVE) D;
BOOLEAN ARRAY WANTEVTMESG (1:100);
TEXT ARRAY EVENTMESG (1:100);
INTEGER REQSPENDING;
INTEGER FRONT, REAR;
REAL ENDTIME, LASTSTARTTIME;
INTEGER MAXJOBNR;
REAL ARRAY ACTJOBWT (0:20);
REAL ACTCHNGTIME, TOTACTIVE, SUMACTIVE;
INTEGER NRACTIVENOW;
INITEVENTARRAY;
OUTTEXT ("TRACE FILE? ");
BREAKOUTIMAGE;
INIMAGE;
FNAME:-INTEXT(20);
F:-NEW INFILE (FNAME);
BUFFER:-BLANKS(80);
F.OPEN(BUFFER);
F.INIMAGE;
INITDISKDATA;
FRONT:=1;
REAR:=2;
NULLQ:-NEW QUEUE;
NULLQ.QNAME:-COPY("NULL QUEUE ");
IOWAITQ:-NEW QUEUE;
IOWAITQ.QNAME:-COPY("IOWAIT QUEUE ");
STOPQ:-NEW QUEUE;
STOPQ.QNAME:-COPY("STOP QUEUE ");
PQ1:-NEW QUEUE;
PQ1.QNAME:-COPY("PQ1 ");
PQ2:-NEW QUEUE;
PQ2.QNAME:-COPY("PQ2 ");
PQ3:-NEW QUEUE;
PQ3.QNAME:-COPY("PQ3 ");
QUEUELIST(1):-PQ1;
QUEUELIST(2):-PQ2;
QUEUELIST(3):-PQ3;
QUEUELIST(4):-IOWAITQ;
QUEUELIST(5):-STOPQ;
QUEUELIST(6):-NULLQ;
INITHISEGS;
NULLJOB:-NEW JOB(0);
INSPECT NULLJOB DO
CPUQUANTUMLEFT:=CPUTIMENEEDED:=CPUB4IO:=CPUPERBLK:=100000000;
FOR I:= 1 STEP 1 UNTIL MAXJOB DO
BEGIN
REQSTACK(I):-NEW HEAD;
JOBLIST(I):-NEW JOB(I);
INSPECT JOBLIST(I) DO
BEGIN
MYQUEUE:-NULLQ;
REQUEUE (REAR, NULLQ, 0);
SIZE:=SWAPPEDSIZE:=1;
INCORE:=EXPANDING:=FALSE;
COREASSIGNED:=0;
H:-NULLHISEG;
STARTED:=FALSE;
END;
END;
OUTTEXT("INITIALIZING JOBS"); OUTIMAGE;
REQSPENDING:=0;
WHILE (IF R =/= NONE THEN R.STARTTIME= 0 ELSE TRUE) DO
BEGIN
R:-NEXTREQ;
R.INTO(REQSTACK(R.JOBNR));
ACTIVATE JOBLIST(R.JOBNR) DELAY (1/60);
IF R.JOBNR > MAXJOBNR THEN MAXJOBNR:=R.JOBNR;
END;
SWAPPER:-NEW SWAPPEROBJ;
OUTTEXT("STARTING SWAPPER"); OUTIMAGE;
ACTIVATE SWAPPER;
OUTTEXT ("STARTING DISPATCHER"); OUTIMAGE;
DISPATCHER:-NEW DISPOBJ;
ACTIVATE DISPATCHER;
OUTTEXT("INITIALIZATION COMPLETE");
OUTIMAGE;
HOLD(36000);
REPORT;
END;
ENDRUN:
END;