[comp.lang.ada] Question on Tasking and Text_IO

karl@grebyn.COM (Karl A. Nyberg) (01/07/88)

[Ed. - this is being forwarded becuase the original sender is having
difficulty with the ARPANET.  p.s. to P. S. - let me know that you see
this.]

------------------------------------------------------------------------
Help!

I have been attempting to use Tasking in my work in real-time signal 
processing on VAX/VMS, ALSYS and Meridian Ada compilers.  One task (the 
main program) is dedicated to handling user interaction, and other tasks 
run around doing the real-time stuff.  I came across a problem on the 
Alsys system where once entry of a data field was started, the other 
tasks in the system freeze, and the PC seems to be totally dedicated to 
handling the user input.  I tried this on the DEC VAX/VMS and Meridian 
compilers, and ended up with three different responses, one for each 
compiler. 

What gives?  Am I missing something big, or does Ada not care whether a 
single task performing Text_IO calls can block the reset of a system?  
The code fragment which follows illustrates the three responses that 
were obtained (P.S. in the actual program I use a mailbox and not a 
shared variable!):

The three classes of response were:

DEC VAX/VMS: 		with $ DEFINE ADA$INPUT TT: the A_Task updates 
                        the shared variable at 10 Hz, as expected.

ALSYS on SPERRY-IT	Correct updating of the shared variable until 
                        the first character of the command is entered, 
                        then A_Task freezes.  Time-slicing does not 
                        help.

MERIDIAN on COMPAQ-386	The shared variable is never updated.  Pragma 
                        Priority does not help.

Does this also mean that I have to provide a machine-dependent mechanism 
for user interaction in the presence of tasking?  I would appreciate any 
comments on this dilemma.

P.S.Tuffs

CS-NET:	Tuffs@alcoa.com
Mail:	P.S.Tuffs
	Alcoa Technical Center,
	Alcoa Center
	Pa 15069.

-------------------------------------------------------------------------------
-- An example of how the Text_IO.Get for enumerations can block a task
with Text_Io;
procedure Task_Blk is
  
  Shared_Variable: Integer := 0;
  task A_Task is
    entry Stop;
  end A_Task;

  type Commands is (Help, Stop);
  The_Command: Commands;
  package Command_Io is new Text_Io.Enumeration_IO(Commands);

  task body A_Task is
  begin 
    loop
      select
        accept Stop;
        exit;
      or
        delay 0.1;
        Shared_Variable := Shared_Variable + 1;
      end select;
    end loop;
  end A_Task;

begin
  loop
    Text_IO.Put("Enter the command: ");
    Command_IO.Get(The_Command);
    exit when The_Command = Stop;
    Text_Io.Put_Line("The variable is: " & Integer'Image(Shared_Variable));   
  end loop;    
  A_Task.Stop;
end Task_Blk;
-------------------------------------------------------------------------------

stt@ada-uts (01/08/88)

The LRM does not state whether during I/O other tasks may/must proceed.
If you consider I/O operations as simply very slow machine instructions,
then it is "reasonable" that no other task proceeds during I/O.
On the other hand, if you consider I/O a communication with some
independent processor running in parallel with the CPU (e.g. the
human at the keyboard, or a disk drive), then it would seem
"reasonable" that the CPU would be available for running other
tasks while the I/O operation is waiting for a response from the
"other" processor.

Obviously, most users would prefer
the "communication with independent processor" model over
the "very slow machine instruction" model, but alas, the LRM
doesn't specify which is required.  There are some folks
who feel that on philosophical grounds the "very slow machine
instruction" model is actually more logical, but they
of course would never want to use it to try to build a
highly interactive application.

In any case, one way to protect yourself is to have
an input task which checks for the presence of input
before reading it (this is possible in some O/Ss).
If no input is present, it does an Ada DELAY and checks again.
Once input is present, it reads it, causing minimal interruption
to other tasks.

Another alternative available on Unix(R) systems
(presuming you drop into C), is to set an alarm and then read input.
When the alarm expires, the "read" will return with an error,
the task may then do an Ada delay (to allow other tasks to proceed
for awhile) before retrying the alarmed read.

S. Tucker Taft
c/o Intermetrics, Inc.
Cambridge, MA  02138