perm filename REALTI.SIM[SIM,SYS] blob sn#460183 filedate 1979-07-20 generic text, type T, neo UTF8
00010	OPTIONS(/l/e); COMMENT REAL time programs IN simula;
00020	OPTIONS(/s:"libsim[13,134]");
00030	EXTERNAL BOOLEAN PROCEDURE inputcheck;
00040	EXTERNAL PROCEDURE sleep, abort;
00050	EXTERNAL INTEGER PROCEDURE inputwait;
00060	EXTERNAL REAL PROCEDURE clocktime;
00070	simulation CLASS realtime;
00080	NOT HIDDEN PROTECTED synchronize, desynchronize,
00090	terminal←passivate,
00100	hold, terminalprocess;
00110	NOT HIDDEN process, current, time, passivate, wait,
00120	main, linkage, link, head;
00130	BEGIN
00140	  REF (input←array) inputs;
00150	  BOOLEAN synchronized;
00160	  REAL unit, starttime, time←difference, real←time;
00170	  REAL time←error;
00180	  REAL a←second, hundredth←of←a←second;
00190	
00200	     	
00210	  PROCEDURE adjust←times;
00220	  BEGIN
00230	    BEGIN real←time:= clocktime/unit+time←difference;
00240	      time←error:= time-real←time;
00250	      IF time←error > a←second THEN sleep((time←error)*unit)
00260	      ELSE IF time←error < -a←second THEN
00270	      BEGIN
00280	        ACTIVATE NEW starter(current, FALSE)
00290	        DELAY (-time←error+hundredth←of←a←second);
00300	        passivate;
00310	      END;
00320	    END;
00330	  END;
00340	     	
00350	  process CLASS starter(processen, adjust);
00360	  REF (process) processen; BOOLEAN adjust;
00370	  BEGIN
00380	    IF synchronized AND adjust THEN adjust←times;
00390	    ACTIVATE processen;
00400	  END;
00410	     	
00420	  CLASS input←array(dimension); INTEGER dimension;
00430	  BEGIN
00440	    REF (infile) ARRAY infiles[1:dimension];
00450	    REF (terminalprocess) ARRAY terminals[1:dimension];
00460	     	
00470	    PROCEDURE try←to←start;
00480	    BEGIN INTEGER i;
00490	      FOR i:= 1 STEP 1 UNTIL dimension DO
00500	      IF infiles[i] =/= NONE THEN
00510	      BEGIN
00520	        IF inputcheck(infiles[i]) THEN
00530	        BEGIN
00540	          IF synchronized THEN adjust←times;
00550	          ACTIVATE terminals[i] DELAY 0;
00560	        END;
00570	      END;
00580	    END;
00590	  END of CLASS input←array;
00600	     	
00610	  PROCEDURE synchronize(timeunit); REAL timeunit;
00620	  COMMENT this procedure starts synchronization of real and
00630	  simulated time;
00640	  BEGIN
00650	    synchronized:= TRUE; unit:= timeunit;
00660	    starttime:= clocktime/unit;
00670	    time←difference:= time-starttime;
00680	    a←second:= 1.0/unit; hundredth←of←a←second:= 0.01/unit;
00690	  END;
00700	     	
00710	  PROCEDURE desynchronize;
00720	  COMMENT This procedure ends synchronization of real and
00730	  simulated time;
00740	  BEGIN
00750	    synchronized:= FALSE;
00760	  END;
00770	     	
00780	  PROCEDURE terminal←passivate;
00790	  COMMENT special version of passivate for a
00800	  terminal←process;
00810	  BEGIN
00820	    inputs.try←to←start;
00830	    IF synchronized THEN
00840	    BEGIN
00850	      real←time:= clocktime/unit+time←difference;
00860	      time←error:= current.nextev.evtime-real←time;
00870	      IF time←error > 0 THEN
00880	      BEGIN
00890	        inputwait(inputs.infiles,
00900	        IF current.nextev IS activator THEN 0.0 ELSE
00910	        time←error*unit);
00920	        inputs.try←to←start;
00930	      END;
00940	    END;
00950	    passivate;
00960	    inputs.try←to←start;
00970	  END;
00980	     	
00990	  PROCEDURE wait(q); REF (head) q;
01000	  COMMENT special version of wait for a terminal←process;
01010	  BEGIN current.into(q); terminal←passivate;
01020	  END of procedure wait;
01030	     	
01040	  PROCEDURE hold(delaytime); REAL delaytime;
01050	  COMMENT special version of hold for terminalprocesses.
01060	  hold(0.0) gives round robin process scheduling;
01070	  BEGIN
01080	    ACTIVATE NEW starter(current, TRUE) DELAY delaytime;
01090	    terminal←passivate;
01100	  END;
01110	     	
01120	  process CLASS terminalprocess(fromterminal);
01130	  REF (infile) fromterminal;
01140	  NOT HIDDEN PROTECTED fromterminal, waitforinput;
01150	  NOT HIDDEN evtime, nextev, into;
01160	  BEGIN
01170	    INTEGER subscript; ! In input←array;
01180	     	
01190	    PROCEDURE waitforinput;
01200	    COMMENT this process waits in the input←array
01210	    inimage is possible to make;
01220	    IF inputcheck(fromterminal) THEN hold(0.0) ELSE
01230	    BEGIN
01240	      inputs.infiles[subscript]:- fromterminal;
01250	      terminal←passivate;
01260	    END;
01270	     	
01280	    INSPECT inputs DO
01290	    BEGIN
01300	      FOR subscript:= 1 STEP 1 UNTIL dimension DO
01310	      IF terminals[subscript] == NONE THEN GOTO found;
01320	      abort("TOO MANY FILES FOR REALTIME PACKAGE ARRAY");
01330	      found: terminals[subscript]:- THIS terminalprocess;
01340	    END;
01350	     	
01360	    INNER;
01370	    inputs.terminals[subscript]:- NONE;
01380	  END of terminalprocess;
01390	     	
01400	  process CLASS activator;
01410	  BEGIN
01420	    REF (process) lastprocess;
01430	    INTEGER subscript;
01440	    loop: lastprocess:- current;
01450	    WHILE lastprocess.nextev =/= NONE
01460	    DO lastprocess:- lastprocess.nextev;
01470	    IF lastprocess == current THEN
01480	    BEGIN
01490	      subscript:= inputwait(inputs.infiles,0);
01500	      IF subscript >= 1 THEN
01510	      BEGIN COMMENT some open file waiting;
01520	        IF synchronized THEN adjust←times;
01530	        ACTIVATE inputs.terminals[subscript] DELAY 0;
01540	        hold(0.0); GOTO loop;
01550	      END ELSE ACTIVATE main;
01560	    END ELSE
01570	    BEGIN REACTIVATE current AFTER lastprocess;
01580	      GOTO loop;
01590	    END;
01600	  END of activator;
01610	     	
01620	  ACTIVATE NEW activator DELAY 0;
01630	  inputs:- NEW input←array(14);
01640	END of class realtime;
01650