1 UNIT SIMULATION: PRIORITYQUEUE CLASS;
\r
2 (* THE LANGUAGE FOR SIMULATION PURPOSES *)
\r
4 VAR CURR: SIMPROCESS, (*ACTIVE PROCESS *)
\r
5 PQ:QUEUEHEAD, (* THE TIME AXIS *)
\r
9 UNIT SIMPROCESS : COROUTINE;
\r
10 (* USER PROCESS PREFIX *)
\r
11 VAR EVENT, (* ACTIVATION MOMENT NOTICE *)
\r
12 EVENTAUX: EVENTNOTICE,
\r
13 (* THIS IS FOR AVOIDING MANY NEW CALLS AS AN RESULT OF *)
\r
14 (* SUBSEQUENT PASSIVATIONS AND ACTIVATIONS *)
\r
17 UNIT IDLE: FUNCTION: BOOLEAN;
\r
19 RESULT:= EVENT= NONE;
\r
22 UNIT TERMINATED: FUNCTION :BOOLEAN;
\r
27 UNIT EVTIME: FUNCTION: REAL;
\r
28 (* TIME OF ACTIVATION *)
\r
30 IF IDLE THEN CALL ERROR1;
\r
32 RESULT:= EVENT.EVENTTIME;
\r
35 UNIT ERROR1:PROCEDURE;
\r
38 WRITELN(" AN ATTEMPT TO ACCESS AN IDLE PROCESS TIME");
\r
41 UNIT ERROR2:PROCEDURE;
\r
44 WRITELN(" AN ATTEMPT TO ACCESS A TERMINATED PROCESS TIME");
\r
56 UNIT EVENTNOTICE: ELEM CLASS;
\r
57 (* A PROCESS ACTIVATION NOTICE TO BE PLACED ONTO THE TIME AXIS PQ *)
\r
58 VAR EVENTTIME: REAL, PROC: SIMPROCESS;
\r
60 UNIT VIRTUAL LESS: FUNCTION(X: EVENTNOTICE):BOOLEAN;
\r
61 (* OVERWRITE THE FORMER VERSION CONSIDERING EVENTTIME *)
\r
63 IF X=NONE THEN RESULT:= FALSE ELSE
\r
64 RESULT:= EVENTTIME< X.EVENTTIME OR
\r
65 (EVENTTIME=X.EVENTTIME AND PRIOR< X.PRIOR); FI;
\r
71 UNIT MAINPROGRAM: SIMPROCESS CLASS;
\r
72 (* IMPLEMENTING MASTER PROGRAM AS A PROCESS *)
\r
77 UNIT TIME:FUNCTION:REAL;
\r
78 (* CURRENT VALUE OF SIMULATION TIME *)
\r
80 RESULT:=CURRENT.EVTIME
\r
83 UNIT CURRENT: FUNCTION: SIMPROCESS;
\r
84 (* THE FIRST PROCESS ON THE TIME AXIS *)
\r
89 UNIT SCHEDULE: PROCEDURE(P:SIMPROCESS,T:REAL);
\r
90 (* ACTIVATION OF PROCESS P AT TIME T AND DEFINITION OF "PRIOR"- PRIORITY *)
\r
91 (* WITHIN TIME MOMENT T *)
\r
93 IF T<TIME THEN T:= TIME FI;
\r
94 IF P=CURRENT THEN CALL HOLD(T-TIME) ELSE
\r
95 IF P.IDLE AND P.EVENTAUX=NONE THEN (* HAS NOT BEEN SCHEDULED YET*)
\r
96 P.EVENT,P.EVENTAUX:= NEW EVENTNOTICE(RANDOM);
\r
99 IF P.IDLE (* P HAS ALREADY BEEN SCHEDULED *) THEN
\r
100 P.EVENT:= P.EVENTAUX;
\r
101 P.EVENT.PRIOR:=RANDOM;
\r
103 (* NEW SCHEDULING *)
\r
104 P.EVENT.PRIOR:=RANDOM;
\r
105 CALL PQ.DELETE(P.EVENT)
\r
107 P.EVENT.EVENTTIME:= T;
\r
108 CALL PQ.INSERT(P.EVENT) FI;
\r
111 UNIT HOLD:PROCEDURE(T:REAL);
\r
112 (* MOVE THE ACTIVE PROCESS T MINUTES BACK ALONG PQ *)
\r
113 (* REDEFINE PRIOR *)
\r
115 CALL PQ.DELETE(CURRENT.EVENT);
\r
116 CURRENT.EVENT.PRIOR:=RANDOM;
\r
117 IF T<0 THEN T:=0; FI;
\r
118 CURRENT.EVENT.EVENTTIME:=TIME+T;
\r
119 CALL PQ.INSERT(CURRENT.EVENT);
\r
120 CALL CHOICEPROCESS;
\r
123 UNIT PASSIVATE: PROCEDURE;
\r
124 (* REMOVE THE ACTVE PROCESS FROM PQ AND ACTIVATE THE NEXT ONE *)
\r
126 CALL PQ.DELETE(CURRENT.EVENT);
\r
127 CURRENT.EVENT:=NONE;
\r
131 UNIT RUN: PROCEDURE(P:SIMPROCESS);
\r
132 (* ACTIVATE P IMMEDIATELY AND DELAY THE FORMER FIRST PROCESS BY REDEFINING*)
\r
135 CURRENT.EVENT.PRIOR:=RANDOM;
\r
138 P.EVENT.EVENTTIME:=TIME;
\r
139 CALL PQ.CORRECT(P.EVENT,FALSE)
\r
141 IF P.EVENTAUX=NONE THEN
\r
142 P.EVENT,P.EVENTAUX:=NEW EVENTNOTICE(0);
\r
143 P.EVENT.EVENTTIME:=TIME;
\r
145 CALL PQ.INSERT(P.EVENT)
\r
147 P.EVENT:=P.EVENTAUX;
\r
149 P.EVENT.EVENTTIME:=TIME;
\r
151 CALL PQ.INSERT(P.EVENT);
\r
153 CALL CHOICEPROCESS;
\r
156 UNIT CANCEL:PROCEDURE(P: SIMPROCESS);
\r
157 (* REMOVE PROCESS P FROM PQ AND CONTINUE SIMULATION *)
\r
159 IF P= CURRENT THEN CALL PASSIVATE ELSE
\r
160 CALL PQ.DELETE(P.EVENT);
\r
164 UNIT CHOICEPROCESS:PROCEDURE;
\r
165 (* CHOOSE THE FIRST PROCESS FROM PQ TO BE ACTIVATED *)
\r
169 CURR:= PQ.MIN QUA EVENTNOTICE.PROC;
\r
170 IF CURR=NONE THEN WRITE(" ERROR IN THE HEAP"); WRITELN;
\r
172 ELSE ATTACH(CURR); FI;
\r
176 PQ:=NEW QUEUEHEAD; (* SIMULATION TIME AXIS*)
\r
177 CURR,MAINPR:=NEW MAINPROGRAM;
\r
178 MAINPR.EVENT,MAINPR.EVENTAUX:=NEW EVENTNOTICE(0);
\r
179 MAINPR.EVENT.EVENTTIME:=0;
\r
180 MAINPR.EVENT.PROC:=MAINPR;
\r
181 CALL PQ.INSERT(MAINPR.EVENT);
\r
182 (* THE FIRST PROCESS TO BE ACTIVATED IS MAIN PROGRAM *)
\r