ie53@NTSUVAX.BITNET (HAERIM LEE) (08/24/87)
with text_io; use text_io;
procedure imore is -- Intelligent 'more'
key : character;
task mon_user is -- monitor user
entry do_comm(key : character);
end mon_user;
task body mon_user is
d_time : duration := 60.0; -- pause this amount before printing next page
frozen : boolean := FALSE; -- true if user temporarily freeze printing
procedure print_next is
begin -- print_next
put_line("Next screen"); -- simulation of printing next screen
end print_next;
procedure do_it(key : character) is
begin -- do_it
case key is
when ' ' => print_next; -- print next screen
when 'f' | 'F' => frozen := TRUE; -- freeze to read more carefully
when 't' | 'T' => frozen := FALSE; -- thaw (release) the freeze
when 'c' | 'C' => d_time := 30.0; -- change delay time
when others => null; -- ignore
end case;
end do_it;
begin -- mon_user
print_next; -- print first page
-- The following loop will keep printing next page every
-- 'd_time' second, if user does not enter any command
-- during 'd_time' seconds, or if user already has frozen
-- automatic printing. If he hits <space bar>, the next
-- page is printed IMMEDIATELY, and the current printing
-- mode is preserved.
loop
select
accept do_comm(key : character) do
do_it(key);
end;
or when not frozen =>
delay d_time; -- (roughly) suspension point 1
print_next;
end select;
end loop;
end mon_user;
begin -- imore
-- The following loop keeps waiting for user to enter
-- a command. If he does, it will call the entry 'do_comm'
-- and passes that command to it. If no command is given
-- within 'd_time' seconds, the next page will be automatically
-- printed.
loop
get(key); -- suspension point 2
mon_user.do_comm(key);
end loop;
end imore;
-- problems statement:
--
-- This program is similar to 'more' on Unix except its more
-- clever default behavior; that is, it keeps printing each
-- page and delaying some amount of time so that user can
-- read it. User doesn't have to hit <space bar> at all unless
-- he/she wants to wait for the next page. It automatically
-- prints the next page after some amount of time (of cousrse,
-- user can change this value on the fly). This is quite useful
-- if the file contains many pages which do not require careful
-- reading. When it begins printing pages which need some
-- attention (say, need reading twice), user can freeze this
-- automatic print-pause sequence temporarily, and then use the
-- <space bar> as in the normal 'more'. Once this portion is
-- over, he/she can resume the automatic mode printing. With
-- this automatic printing feature and existing ones in 'more'
-- one can think about whole bunch of new functions. It would
-- be something like a marriage of 'more' and 'cat' on Unix.
--
-- I started writing some lines of code shown above. I expected
-- this small program would keep printing "next line" every 60
-- second if I don't hit any key after invoking this program.
-- The result, however, was quite different; only the first
-- "next screen" is printed, and it was sitting idle until I hit
-- the <space bar>. I noticed that this is because the 'get'
-- statement in the main body does not return its control to
-- the task 'mon_user' when it is suspended (Is it?) by this input
-- operation, while the task 'mon_user' was already in a suspended
-- state and possibly in a ready state if the specified delay time
-- had passed. In this case, the control should be given 'mon_user'
-- so that the procedure call 'print_next' after the delay state-
-- ment can be executed. Actually, I found that the task 'mon_user'
-- did NOT become suspended when the 'get' was invoked, but remained
-- as a 'running' state. This can be shown using the VAX/VMS Symbolic
-- Debugger.
--
-- Shouldn't the state of the task 'mon_user' become
-- 'suspended' when the 'get' is called, if there are any 'ready'
-- tasks? If not, how do we easily implement such time-bombs for
-- input operations? What is the relationship between task states
-- and i/o operations? In Ada, are i/o operations done synchronously
-- or asynchronously? Seems to be 'synchronous' in the Vax Ada V1.3.
--
-- Any comments would be appreciated.
--
-- Haerim Lee (IE53@NTSUVAX)arny@wayback.UUCP (Arny B. Engelson) (08/26/87)
I would expect the program to do exactly what you expected it to do.
One possibility is that the delay statement is not implemented very nicely
(although still legally). LRM 9.6:1 states "The execution of a delay statement
... suspends further execution of the task ... for AT LEAST the duration
specified ... " [emphasis mine]
Perhaps they just decided to delay forever?
You mentioned VAX Ada; have you tried pragma Time_Slice?
How about making the "Get (Key)" part of a timed entry call, as follows:
---------------------------------------------------
task body mon is
L_Key : Character;
begin
loop
Get (L_Key);
accept Got_It (Out_Key : out Character) do
Out_Key := Key;
end;
end loop;
end;
task body imore is
begin
loop
select
mon.Got_It (Key);
or
delay Dur_Time;
Print_Next_Screen;
end select;
end loop;
end;
---------------------------------------------------
I know the above code is incomplete and has some bugs in it, but I'm
just trying to stimulate ideas. Besides I only thought of it as I was
typing this article, and don't have time to go over it now.
- Arny Engelson {ihnp4|bonnie|clyde}!wayback!arnyjb@rti.UUCP (Jeff Bartlett) (08/27/87)
In article <8708241839.AA01159@ucbvax.Berkeley.EDU>, ie53@NTSUVAX.BITNET (HAERIM LEE) writes: > procedure imore is -- Intelligent 'more' > > This program is similar to 'more' on Unix except its more > clever default behavior; that is, it keeps printing each ..... > "next screen" is printed, and it was sitting idle until I hit > the <space bar>. I noticed that this is because the 'get' > statement in the main body does not return its control to > the task 'mon_user' when it is suspended (Is it?) by this input > operation, while the task 'mon_user' was already in a suspended > state and possibly in a ready state if the specified delay time > had passed. In this case, the control should be given 'mon_user' > so that the procedure call 'print_next' after the delay state- > ment can be executed. Actually, I found that the task 'mon_user' > did NOT become suspended when the 'get' was invoked, but remained > as a 'running' state. This can be shown using the VAX/VMS Symbolic > Debugger. > Shouldn't the state of the task 'mon_user' become > 'suspended' when the 'get' is called, if there are any 'ready' > tasks? If not, how do we easily implement such time-bombs for > input operations? What is the relationship between task states > and i/o operations? In Ada, are i/o operations done synchronously > or asynchronously? Seems to be 'synchronous' in the Vax Ada V1.3. > > -- Haerim Lee (IE53@NTSUVAX) See section 2.7 "Input-Output and Tasking" in "VAX Ada Programmer's Run-Time Reference Manual", p 2-73. I/O on SYS$INPUT, SYS$OUTPUT, SYS$COMMAND, and SYS$ERROR are 'synchronous'. TEXT_IO used ADA$INPUT and ADA$OUTPUT which is normally assigned to SYS$INPUT and SYS$OUTPUT. To get 'async' i/o, assign ADA$INPUT and ADA$OUTPUT to TT: in DCL. Jeff Bartlett Center for Digital Systems Research Research Triangle Institute jb@rti.rti.org
blackje%sungod.tcpip@GE-CRD.ARPA (09/01/87)
Received: by sungod.steinmetz (3.2/1.1x Steinmetz) id AA08368; Mon, 31 Aug 87 19:45:10 EDT Date: Mon, 31 Aug 87 19:45:10 EDT From: emmett black <blackje@sungod> Posted-Date: Mon, 31 Aug 87 19:45:10 EDT Message-Id: <8708312345.AA08368@sungod.steinmetz> To: info-ada@ada20.isi.edu Subject: RE: Re: Help me to solve this problem! ----- Begin Forwarded Message ----- From STRICKLER%SCOVCB.decnet@csbvax.steinmetz Mon Aug 31 13:31:03 1987 Received: from CSBVAX by sungod.steinmetz (3.2/1.1x Steinmetz) id AA07822; Mon, 31 Aug 87 13:30:56 EDT Posted-Date: 31 Aug 87 13:28 EST Message-Id: <8708311730.AA07822@sungod.steinmetz> Date: 31 Aug 87 13:28 EST From: STRICKLER%SCOVCB.decnet@csbvax.steinmetz Subject: RE: Re: Help me to solve this problem! I have not had the time to review the problem in detail, however, I will throw out a comment which may shed some light on the problem. Input/output operations on VAX Ada files take place sequentially (see Programmer's Runtime Reference Manual section 2.7). Thus, if two tasks request I/O to the same file, the second task will wait until all previous I/O on that file is completed. Although I do not know for sure, VAX Ada probably treats the terminal as a "file" and, if it does, a write can not take place while a read is pending. ----- End Forwarded Message -----