Added upstream from http://ftp.icm.edu.pl/pub/loglan/
[loglan.git] / at_work / exe_old / 486.inc / simula.inc
1 UNIT SIMULATION: PRIORITYQUEUE CLASS;\r
2 (* THE LANGUAGE FOR SIMULATION PURPOSES *)\r
3  \r
4   VAR CURR: SIMPROCESS,  (*ACTIVE PROCESS *)\r
5       PQ:QUEUEHEAD,  (* THE TIME AXIS *)\r
6        MAINPR: MAINPROGRAM;\r
7  \r
8  \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
15                  FINISH: BOOLEAN;\r
16  \r
17              UNIT IDLE: FUNCTION: BOOLEAN;\r
18                    BEGIN\r
19                    RESULT:= EVENT= NONE;\r
20                    END IDLE;\r
21  \r
22              UNIT TERMINATED: FUNCTION :BOOLEAN;\r
23                    BEGIN\r
24                   RESULT:= FINISH;\r
25                    END TERMINATED;\r
26  \r
27              UNIT EVTIME: FUNCTION: REAL;\r
28              (* TIME OF ACTIVATION *)\r
29                   BEGIN\r
30                   IF IDLE THEN CALL ERROR1;\r
31                                            FI;\r
32                   RESULT:= EVENT.EVENTTIME;\r
33                   END EVTIME;\r
34  \r
35     UNIT ERROR1:PROCEDURE;\r
36                 BEGIN\r
37                 ATTACH(MAIN);\r
38                 WRITELN(" AN ATTEMPT TO ACCESS AN IDLE PROCESS TIME");\r
39                 END ERROR1;\r
40  \r
41      UNIT ERROR2:PROCEDURE;\r
42                  BEGIN\r
43                  ATTACH(MAIN);\r
44                  WRITELN(" AN ATTEMPT TO ACCESS A TERMINATED PROCESS TIME");\r
45                  END ERROR2;\r
46              BEGIN\r
47  \r
48              RETURN;\r
49              INNER;\r
50              FINISH:=TRUE;\r
51               CALL PASSIVATE;\r
52              CALL ERROR2;\r
53           END SIMPROCESS;\r
54  \r
55  \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
59  \r
60       UNIT VIRTUAL LESS: FUNCTION(X: EVENTNOTICE):BOOLEAN;\r
61        (* OVERWRITE THE FORMER VERSION CONSIDERING EVENTTIME *)\r
62                   BEGIN\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
66  \r
67                END LESS;\r
68     END EVENTNOTICE;\r
69  \r
70  \r
71 UNIT MAINPROGRAM: SIMPROCESS CLASS;\r
72  (* IMPLEMENTING MASTER PROGRAM AS A PROCESS *)\r
73       BEGIN\r
74       DO ATTACH(MAIN) OD;\r
75       END MAINPROGRAM;\r
76  \r
77 UNIT TIME:FUNCTION:REAL;\r
78  (* CURRENT VALUE OF SIMULATION TIME *)\r
79      BEGIN\r
80      RESULT:=CURRENT.EVTIME\r
81      END TIME;\r
82  \r
83 UNIT CURRENT: FUNCTION: SIMPROCESS;\r
84    (* THE FIRST PROCESS ON THE TIME AXIS *)\r
85      BEGIN\r
86      RESULT:=CURR;\r
87      END CURRENT;\r
88  \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
92       BEGIN\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
97                 P.EVENT.PROC:= P;\r
98                                       ELSE\r
99        IF P.IDLE (* P HAS ALREADY BEEN SCHEDULED *) THEN\r
100                P.EVENT:= P.EVENTAUX;\r
101                P.EVENT.PRIOR:=RANDOM;\r
102                                           ELSE\r
103    (* NEW SCHEDULING *)\r
104                P.EVENT.PRIOR:=RANDOM;\r
105                CALL PQ.DELETE(P.EVENT)\r
106                                 FI; FI;\r
107       P.EVENT.EVENTTIME:= T;\r
108       CALL PQ.INSERT(P.EVENT) FI;\r
109 END SCHEDULE;\r
110  \r
111 UNIT HOLD:PROCEDURE(T:REAL);\r
112  (* MOVE THE ACTIVE PROCESS T MINUTES BACK ALONG PQ *)\r
113  (* REDEFINE PRIOR                                  *)\r
114      BEGIN\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
121      END HOLD;\r
122  \r
123 UNIT PASSIVATE: PROCEDURE;\r
124   (* REMOVE THE ACTVE PROCESS FROM PQ AND ACTIVATE THE NEXT ONE *)\r
125      BEGIN\r
126       CALL PQ.DELETE(CURRENT.EVENT);\r
127       CURRENT.EVENT:=NONE;\r
128       CALL CHOICEPROCESS\r
129      END PASSIVATE;\r
130  \r
131 UNIT RUN: PROCEDURE(P:SIMPROCESS);\r
132  (* ACTIVATE P IMMEDIATELY AND DELAY THE FORMER FIRST PROCESS BY REDEFINING*)\r
133  (* PRIOR                                                              *)\r
134      BEGIN\r
135      CURRENT.EVENT.PRIOR:=RANDOM;\r
136      IF NOT P.IDLE THEN\r
137             P.EVENT.PRIOR:=0;\r
138             P.EVENT.EVENTTIME:=TIME;\r
139             CALL PQ.CORRECT(P.EVENT,FALSE)\r
140                     ELSE\r
141       IF P.EVENTAUX=NONE THEN\r
142             P.EVENT,P.EVENTAUX:=NEW EVENTNOTICE(0);\r
143             P.EVENT.EVENTTIME:=TIME;\r
144             P.EVENT.PROC:=P;\r
145             CALL PQ.INSERT(P.EVENT)\r
146                         ELSE\r
147              P.EVENT:=P.EVENTAUX;\r
148              P.EVENT.PRIOR:=0;\r
149              P.EVENT.EVENTTIME:=TIME;\r
150              P.EVENT.PROC:=P;\r
151              CALL PQ.INSERT(P.EVENT);\r
152                           FI;FI;\r
153       CALL CHOICEPROCESS;\r
154 END RUN;\r
155  \r
156 UNIT CANCEL:PROCEDURE(P: SIMPROCESS);\r
157  (* REMOVE PROCESS P FROM PQ AND CONTINUE SIMULATION *)\r
158    BEGIN\r
159    IF P= CURRENT THEN CALL PASSIVATE ELSE\r
160     CALL PQ.DELETE(P.EVENT);\r
161     P.EVENT:=NONE;  FI;\r
162  END CANCEL;\r
163  \r
164 UNIT CHOICEPROCESS:PROCEDURE;\r
165  (* CHOOSE THE FIRST PROCESS FROM PQ TO BE ACTIVATED *)\r
166    VAR P:SIMPROCESS;\r
167    BEGIN\r
168    P:=CURR;\r
169    CURR:= PQ.MIN QUA EVENTNOTICE.PROC;\r
170     IF CURR=NONE THEN WRITE(" ERROR IN THE HEAP"); WRITELN;\r
171                       ATTACH(MAIN);\r
172                  ELSE ATTACH(CURR); FI;\r
173 END CHOICEPROCESS;\r
174  \r
175 BEGIN\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
183   INNER;\r
184   PQ:=NONE;\r
185 END SIMULATION;\r
186 \r
187  \r