Google
 

Trailing-Edge - PDP-10 Archives - decuslib20-03 - decus/20-0078/util/realti.sim
There is 1 other file named realti.sim in the archive. Click here to see a list.
OPTIONS(/l/e); COMMENT REAL time programs IN simula;
EXTERNAL BOOLEAN PROCEDURE inputcheck;
EXTERNAL PROCEDURE sleep, abort;
EXTERNAL INTEGER PROCEDURE inputwait;
EXTERNAL REAL PROCEDURE clocktime;
simulation CLASS realtime;
NOT HIDDEN PROTECTED synchronize, desynchronize,
terminal_passivate, input_array,
hold, terminalprocess;
NOT HIDDEN process, current, time, passivate, wait,
main, linkage, link, head;
BEGIN
  REF (input_array) inputs;
  BOOLEAN synchronized;
  REAL unit, starttime, time_difference, real_time;
  REAL time_error;
  REAL a_second, hundredth_of_a_second;
  PROCEDURE adjust_times;
  BEGIN
    BEGIN real_time:= clocktime/unit+time_difference;
      time_error:= time-real_time;
      IF time_error > a_second THEN sleep((time_error)*unit)
      ELSE IF time_error < -a_second THEN
      BEGIN
        ACTIVATE NEW starter(current, FALSE)
        DELAY (-time_error+hundredth_of_a_second);
        passivate;
      END;
    END;
  END;
  process CLASS starter(processen, adjust);
  REF (process) processen; BOOLEAN adjust;
  BEGIN
    IF synchronized AND adjust THEN adjust_times;
    ACTIVATE processen;
  END;
  CLASS input_array(dimension); INTEGER dimension;
  BEGIN
    REF (infile) ARRAY infiles[1:dimension];
    REF (terminalprocess) ARRAY terminals[1:dimension];
    INTEGER maxdim;
    PROCEDURE try_to_start;
    BEGIN INTEGER i;
      FOR i:= 1 STEP 1 UNTIL maxdim DO
      IF infiles[i] =/= NONE THEN
      BEGIN
        IF inputcheck(infiles[i]) THEN
        BEGIN
          IF synchronized THEN adjust_times;
          ACTIVATE terminals[i] DELAY 0;
        END;
      END;
    END;
  END of CLASS input_array;
  PROCEDURE synchronize(timeunit); REAL timeunit;
  COMMENT this procedure starts synchronization of real and
  simulated time;
  BEGIN
    synchronized:= TRUE; unit:= timeunit;
    starttime:= clocktime/unit;
    time_difference:= time-starttime;
    a_second:= 1.0/unit; hundredth_of_a_second:= 0.01/unit;
  END;
  PROCEDURE desynchronize;
  COMMENT This procedure ends synchronization of real and
  simulated time;
  BEGIN
    synchronized:= FALSE;
  END;
  PROCEDURE terminal_passivate;
  COMMENT special version of passivate for a
  terminal_process;
  BEGIN
    inputs.try_to_start;
    IF synchronized THEN
    BEGIN
      real_time:= clocktime/unit+time_difference;
      time_error:= current.nextev.evtime-real_time;
      IF time_error > 0 THEN
      BEGIN
        inputwait(inputs.infiles,
        IF current.nextev IS activator THEN 0.0 ELSE
        time_error*unit);
        inputs.try_to_start;
      END;
    END;
    passivate;
    inputs.try_to_start;
  END;
  PROCEDURE wait(q); REF (head) q;
  COMMENT special version of wait for a terminal_process;
  BEGIN current.into(q); terminal_passivate;
  END of procedure wait;
  PROCEDURE hold(delaytime); REAL delaytime;
  COMMENT special version of hold for terminalprocesses.
  hold(0.0) gives round robin process scheduling;
  BEGIN
    ACTIVATE NEW starter(current, TRUE) DELAY delaytime;
    terminal_passivate;
  END;
  process CLASS terminalprocess(fromterminal);
  REF (infile) fromterminal;
  NOT HIDDEN PROTECTED fromterminal, waitforinput;
  NOT HIDDEN evtime, nextev, into;
  BEGIN
    INTEGER subscript; ! In input_array;
    PROCEDURE waitforinput;
    COMMENT this process waits in the input_array
    inimage is possible to make;
    IF inputcheck(fromterminal) THEN hold(0.0) ELSE
    BEGIN
      inputs.infiles[subscript]:- fromterminal;
      terminal_passivate;
    END;
    INSPECT inputs DO
    BEGIN
      FOR subscript:= 1 STEP 1 UNTIL dimension DO
      IF terminals[subscript] == NONE THEN GOTO found;
      abort("TOO MANY FILES FOR REALTIME PACKAGE ARRAY");
      found: terminals[subscript]:- THIS terminalprocess;
      IF maxdim < subscript THEN maxdim:= subscript;
    END;
    INNER;
    inputs.terminals[subscript]:- NONE;
  END of terminalprocess;
  process CLASS activator;
  BEGIN
    REF (process) lastprocess;
    INTEGER subscript;
    loop: lastprocess:- current;
    WHILE lastprocess.nextev =/= NONE
    DO lastprocess:- lastprocess.nextev;
    IF lastprocess == current THEN
    BEGIN
      subscript:= inputwait(inputs.infiles,0);
      IF subscript >= 1 THEN
      BEGIN COMMENT some open file waiting;
        IF synchronized THEN adjust_times;
        ACTIVATE inputs.terminals[subscript] DELAY 0;
        hold(0.0); GOTO loop;
      END ELSE ACTIVATE main;
    END ELSE
    BEGIN REACTIVATE current AFTER lastprocess;
      GOTO loop;
    END;
  END of activator;
  ACTIVATE NEW activator DELAY 0;
  inputs:- NEW input_array(14);
END of class realtime;