[net.micro.amiga] Wait

dillon@CORY.BERKELEY.EDU (Matt Dillon) (09/28/86)

>From: oster@lapis.berkeley.edu (David Phillip Oster)
>Please correct me when I am wrong, but I'm under the impression that the
>Amiga has both time-sliced multi-tasking and, a routine called Wait() that
>lowers the priority of an application.  The application is supposed to
>call Wait() when it has nothing to do.   How do Amiga programmers handle
>continuous mouse tracking so their programs can change the cursor shape as
>the cursor enters different kinds of objects?

	Wait() doesn't just lower the priority of the calling task, it
completely suspends the task until one or more of the requested signals comes
in.   For instance, Your IDCMP port for a window will send a signal to your
task whenever an event that you requested occurs.  Usually, one Wait()'s for
all the signals he's expecting then reads the message(s) from some message
port.  Since messages are queued on the port, it isn't stop and go as you
might think.  If fact, the system gets more efficient under medium input 
loads.

	Continuous mouse tracking is handled by Intuition.  If you've 
requested Intuition track the mouse for you, you will get a stream of 
events over your message port.  Since the mouse tracking is handled
asyncronously by another process, your own process doesn't have to be ready 
to receive the reports... they just queue up on the message port.  Thus, you
get smooth mouse-reporting even if there are other things happenning in
the system, or if the particular process isn't paying close attention to 
the IDCMP message port. (Actually, a lower level device handles the mouse 
tracking on the interrupt level, but you get the reports through Intuition).

>On the Mac, the equivalent routine to Wait() is called SystemTask.
>SystemTask() suspends its caller and gives other applications a chance to
>run.  If you want time sliced multi-tasking, you just queue a task on the
>vertical interrupt queue, to be awakened at a future time that is a
>essentially a parameter of the queue call.  Interrupt handlers are also
>straight forward, and are used in Mac device drivers.

	It is not equivalent.  The major difference is that on the Amiga
you aren't required to call Wait().  The Multi-tasking time-slices the
processes, and a particular process can get preempted unless it specifically
disables Multi-tasking.  Wait() is used when a process has nothing to do...
is waiting for some input.  It doesn't *have* to wait for the input, and
indeed you could Poll your message port(s) in a tight loop, but generally
you just call 'Wait' then do the Poll.

	If you were to do something like read from a file... say:

	Read(fh, buf, 8192)

	The Read() call automatically calls Wait() after it sends DOS the
read request.  When DOS completes the request it sends the return code
back and signal's the calling process.  So if you had two processes running,
and one was doing heavy disk I/O, the second one still gets a good chunk of
the CPU because (A) the first one is almost always waiting for disk requests
to complete and (B) DOS is almost always waiting for disk DMA to complete.
Thus, in some ways, a multi-tasking enviroment can be more efficient than a
single-tasking envrioment.

>My Menu Clock runs as a SystemTask style task, drawing the time in the
>menu bar only when the application has asserted, by calling SystemTask,
>that it is okay to style a couple of cycles to do the drawing. 

	The equivalent Clock program on an Amiga is simply another processes,
usually running at priority 0 (most user processes run at 0).  Basically,
the Clock program uses the TIMER.DEVICE to provide it with a signal every
second, then simply has a Wait/UpdateDisplay loop.

>Mac owners can see mult-tasking by going into an editor, and resizing the
>window to about half screen size.  Bring up the KeyCaps desk accessory
>and put it beside your editor window.  Click on the editor window and
>begin typing.  KeyCaps tracks the state of the keyboard even when it is
>not the top window.  
>(I have written 90% of a desk accessory that uses this
>technique to give a histogram of your instantaneous typing speed, recorded
>over the last 15 minutes, with numerical average speeds for the last 5 and
>15 minuetes. When it is finished, I will post it.)

	Yes, the MAC does a very good illusion of multi-tasking.

>Some things you can't do on a Mac:
>1.) Time-slice Multitask two vanilla application programs. (Andy Hertzfeld
>said that he decided not to do it in Servant because the amount of task
>state you need to swap in the current applications makes the swap to
>slow.)  (You can multi-task applications and desk accessories though. And
>there have been some pretty powerful desk accessories released: Click-On
>WorkSheet, MockWrite and MiniWrite, and Acta (an outline editor) spring to
>mind.)

	Ditto on my last comment... What programmers have been able to do
on the MAC is pretty incredible.

>2.) give tasks of the same class priorities.  Withing the constraints of
>memory, you can have "w" applications active at once, "x" desk accessories,
>"y" vbl tim-slice tasks, and "z" device drivers.

	This is how the Amiga works for the most part, though any one of
the Amiga's tasks, device drivers, and desk accessories (not sure how that
applies) can be any combination of tasks, interrupt servers, or run-time
libraries.

>Are there any Amiga programmers who needed task priorities?  If so, why ?

	I myself have yet to need to use task priorities.  The OS uses
priorities extensively:

	First a little background.  Here is an excerp from Wack's 'tasks'
command to give you an idea of how the Amiga's OS works:

Address NT Pri Stat   SigWait   SPReg Name
$047C98 13   0  run $00000100 $041308 "Background CLI"
$0254B0 13   0 wait $00000100 $0259Be "RAM"
$00DB98 13   5 wait $00000100 $00E6E6 "CON"
$000E98 13  10 wait $00000100 $001236 "File System"
$00C300 13  10 wait $00000100 $00C69E "File System"
$00D78E  1   5 wait $00000300 $00D9A6 "trackdisk.device"
$00695E  1   5 wait $00000300 $006b76 "trackdisk.device"
$0032Ca  1  20 wait $C0000000 $0042D0 "input.device"
$041F48 13   5 wait $00000100 $042A96 "RAW"
		...
		(and others)

	The input.device is triggered by messages sent from actual interrupt
service routines.  The File System and trackdisk.device processes handle the
floppies (one set for each floppy.  Thus, my system has two floppies).
RAM is the RAM disk, CON and RAW are ascii-terminal drivers for windows.  So
by this description, Disk I/O takes precedance over a normal user processes.
However, none of the high-priority processes ever take much time.  Most of
the time they are waiting for disk DMA, Keyboard strokes, etc...  Usually,
user processes use a CLI as a base, so you have one or more
'Background CLIs'.  Named user processes show up when you use exec calls
to create your own processes.
	
	The way process priorities work on the Amiga, a higher priority
process completely pre-empts a lower priority process while it is running.
(it is NOT running when it's in Wait()).  Processes at the same priority
share the processor via time-slice even if they never call Wait().  This
is much different than UNIX, which raises and lowers individual processes
actual priority on the fly.  On UNIX, one process cannot completely lockout
another.  On the Amiga, a higher priority process CAN completely lockout
another.  In fact, there is nothing to prevent you from giving a process
a priority of 30 thus giving it the ability to completely lock out EVERYTHING 
on the amiga at will (except interrupt service routines, but you could
turn them off as well).

	Of course, there are also real interrupts.  input.device ultimately
gets it's information from interrupt routines.  Here is the interrupt
list ('ints' from wack)

IV   Data   Code   Node NT Name
 0 02E3E4 03AAF2 02E470  2 "serial.device"
 1 001EDE FC4A20 001F2C  0 ""
 2 000000 FC134A 000000  0 "server-chain"
 3 0008E8 FC12C6 000000  0 "server-chain"
 4 000914 FC12C6 000000  0 "server-chain"
 5 0008FE FC12C6 000000  0 "server-chain"
 6 0021FE FC6D3A 002274  0 ""
 7 00309E FC3544 00313C  2 "audio.device"
 8 00310A FC3544 0031A8  2 "audio.device"
 9 003176 FC3544 003214  2 "audio.device"
10 0031E2 FC3544 00313C  2 "audio.device"
11 02E3E4 03A854 02E45A	 2 "serial.device"
12 001EDE FC4A38 001F42	 0 ""
13 00092A FC12C6 000000  0 "server-chain"
14 000000 000000 000000  0 ""
15 000940 FC12C6 000000  0 "server-chain"

	As you can see, interrupt vectors on which there is only one device
goes directly to that device driver.  Interrupt vectors which are used by
serveral devices go through a server-chain  (creating/deleting interrupt
servers is handled by exec calls).  They keyboard and mouse are one one of the
server chains (forgot which one).


>I'm not trying to flame, I'm trying to learn.

	Yes, and it's a lot of fun responding to your questions.



						-Matt