PROGRAM ServerSim;
{Programmer: Gregory A. Perkins
CS 65
Due: 20 November 1996}
{This program simulates an internet server processing outgoing messages
and reports the maximum wait time for messages to be processed}
USES cs65; {contains the random functions and IntToStr functions}
{Declaration module}
CONST Num = 5600; {number of elements in array - used mainly for testing phase}
TYPE WaitArray = ARRAY[1..Num] OF REAL; {Holds value of max wait time for each rate}
CONST NumRot = 50; {number of run times per rate}
CONST Inc = 1; {increment value of rate}
VAR WaitY : WaitArray;
VAR MessFile, MessMax : LONGINT;
VAR Tick, Packet, Rate, Rotation, Count : INTEGER;
VAR Wait, WaitSum, WaitAve : REAL;
VAR PlotX, PlotY : INTEGER;
VAR WaitDisplay, TempStr : STRING;
{Subprogram module}
FUNCTION Message(R : INTEGER) : INTEGER;
VAR Event : REAL;
BEGIN
Message := 0;
Event := Random;
IF (Event <= (R / 111111.111111)) THEN
Message := 50 * (RandomInt(39) + 1) {average of 1000 characters/message}
ELSE
Message := 0;
END;
PROCEDURE Server(VAR PSize : INTEGER; VAR MSize : LONGINT);
BEGIN
IF PSize = 1000 THEN
PSize := 0;
PSize := PSize + 50;
MSize := MSize - 50;
END;
{---------------------- STOLEN FROM BOWLING PROGRAM ------------------------------}
FUNCTION DigitToChar(D : INTEGER) : Char;
{Converts a digit to a character (e.g. 3 becomes '3').
Numbers other than a single digit become an 'X' }
BEGIN
IF (D > 9) OR (D < 0) THEN
DigitToChar := 'X'
ELSE
DigitToChar := CHR(D+48);
END;
PROCEDURE IntToStr( X, Width:INTEGER; VAR Result:STRING);
{ Convert an Integer into a String suitable for outTextXY. If X has
fewer than Width digits, it is padded on the left with blanks. If
X has more than Width digits, Result will be whatever length is
required to store the digits}
VAR Length,Digit, i, Index : INTEGER;
tempStr : STRING;
BEGIN {IntToStr}
{First decode digits into tempStr}
Length := 0;
IF X = 0 THEN
BEGIN
Length := 1;
tempStr := "0";
END
ELSE
WHILE X > 0 DO
BEGIN
Length := Length + 1;
Digit := X MOD 10;
TempStr[Length] := DigitToChar(Digit);
X := X DIV 10;
END;
{Pad to appropriate width}
WHILE Length < Width DO
BEGIN
Length := Length + 1;
TempStr[Length] := ' ';
END;
{Copy into Reslt in reverse order}
Index := 1;
FOR i := Length DOWNTO 1 DO
BEGIN
Result[Index] := tempStr[i];
Index := Index + 1;
END;
{Set length of Result}
Result[0] := CHR(Length);
END; {IntToStr}
{------------------------------------------------------------------------------}
BEGIN {main program module}
Randomize; {seed the random number generator}
Rate := 1;
FOR Count := 1 TO Num DO
WaitY[Count] := 0;
WHILE (Rate <= 5600) DO {get max wait time for all values of rate from 100 to 5600 by 100's}
BEGIN
{Variable initialization module for each new value of rate}
WaitSum := 0; WaitAve := 0;
FOR Rotation := 1 TO NumRot DO {do the loop NumRot times for each rate}
BEGIN
{Variable initialization module}
Packet := 0;
MessFile := 0;
MessMax := 0;
{Main loop : simulates 90 seconds of real time}
FOR Tick := 1 TO 10000 DO
BEGIN {main loop}
{New message module}
MessFile := MessFile + Message(Rate);
IF MessFile > MessMax THEN
MessMax := MessFile;
{Packet assembly module}
IF MessFile > 0 THEN
Server(Packet, MessFile);
END; {main loop}
{Report module}
Wait := MessMax/50 * 9/1000;
{i.e., byte-time * maximum message size, in seconds}
WaitSum := WaitSum + Wait; {add to WaitSum for later calc of ave}
END; {rotation loop}
{Calculate average maximum wait time and display}
WaitAve := WaitSum / NumRot;
WRITELN;
WRITELN('The average maximum wait time for a rate of ', Rate:1, '/cps is: ', WaitAve:3:3);
{Fill the proper element of the arrays}
WaitY[Rate] := WaitAve; {Fills the array with the appropriate max wait time}
Rate := Rate + Inc; {increment to next value of rate}
END; {while loop}
{Graphics module}
SetGraph;
ClrScr;
SetColor(0);
PlotX := 0; PlotY := 0;
{Graph Area Display module}
Line(70, 115, 570, 115);
Line(570, 115, 570, 365);
Line(570, 365, 70, 365);
Line(70, 365, 70, 115);
{Heading Display module}
OUTTEXTXY(196, 395, 'RATE OF INCOMING MESSAGES (cps)');
WaitDisplay := "MAXIMUM WAIT TIME -sec-";
FOR Count := 1 TO 23 DO
OUTTEXTXY(25, (Count * 10) + 127, WaitDisplay[Count]);
OUTTEXTXY(56, 376, '0');
{Display the 'X' coordinates}
FOR Count := 1 TO 5 DO
BEGIN
IntToStr((Count * 1000), 4, TempStr);
OUTTEXTXY(TRUNC(((Count * 1000) * 0.089) + 54), 376, TempStr);
END;
{Display the 'Y' coordinates}
FOR Count := 1 TO 10 DO
BEGIN
IntToStr((Count * 10), 3, TempStr);
OUTTEXTXY(43, TRUNC(((Count * 10) * (-2.5)) + 365), TempStr);
END;
{Graph plotting module}
FOR Count := 1 TO Num DO
BEGIN
PlotX := TRUNC((Count * 0.089) + 70);
PlotY := TRUNC((WaitY[Count] * (-2.5)) + 365);
PutPixel(PlotX, PlotY);
END;
Pause; {stop execution so user can see the resulting graph}
END. {program}