Path: utzoo!attcan!uunet!mcvax!hp4nl!phigate!philmds!leo
From: leo@philmds.UUCP (Leo de Wit)
Newsgroups: comp.sys.atari.st
Subject: Re: Multitasking on the ST
Message-ID: <1067@philmds.UUCP>
Date: 10 Aug 89 11:57:38 GMT
References: <8908021826.AA05333@ucbvax.Berkeley.EDU> <15627@watdragon.waterloo.edu> <1989Aug4.173233.8259@sj.ate.slb.com>
Reply-To: leo@philmds.UUCP (Leo de Wit)
Organization: Philips I&E DTS Eindhoven
Lines: 65

In article <1989Aug4.173233.8259@sj.ate.slb.com> greg@sj.ate.slb.com (Greg Wageman) writes:
   []
|Typically, a task cannot be suspended in a multitasking environment
|until one of two things happens: it makes an operating system call
|which must wait for an external event (such as an "operation
|completed" interrupt) and is then put into a "blocked" state by the
|OS; or, in time-sliced OS's, its time quantum expires.  Some real-time
|multitasking kernels do not require time slicing, so blocking calls are
|the only way a task switch ever occurs.

Read for this moment for 'an operating system call' a GEMDOS call, for
'time quantum' a (number of) VBL interrupts (or other clock generated
interrupts).

|
|The implication is that if the so-called "background" process is doing
|something CPU intensive(e.g. an in-memory sort), it may not make a
|blocking call for a very long time (i.e. several seconds).  The user
|will begin to type characters, generating an interrupt which will
|unblock his foreground task.  The OS will move the now-unblocked
|foreground task to the "ready" task queue, but it *will not begin to
|run* until the background task blocks (or its time quantum expires).
|If the system clock is grainy enough (i. e. the clock "tick" interval
|is very large), or a task context-switch is very expensive, or (yuck!)
|both, hundreds of milliseconds will elapse between the user's keypress
|and the resumption of execution of the foreground task.  Thus, the
|user will perceive a very sluggish response from the foreground task.
|
|The reference to a machine designed from the start for multitasking is
|valid, because proper hardware design can minimize the expense of
|context-switching, provide a suitably fine-grained system clock, and
|include appropriate interrupt support for devices.  Trying to
|retro-fit multitasking into a machine not designed for it is at best a
|frustrating job whose results may not justify the effort.

The discussion about multitasking triggered my interest, so I decided
to try some things out. It appears that context switching is easy if
you do it at the moment of a GEMDOS call: all registers have been saved
on either the stack or the basepage, so in fact all you have to do is
check whether perhaps another process should continue (note the very
small overhead). To be able to have more than one process running
(detach a job), I made a small change to Pexec() so that a new process
can be started, but the parent process is not waiting for the child to
finish. If a process does a call that may involve some time, like
reading a character from the keyboard (Cconin(), Cnecin()), this
process only continues its call when there is a character available, so
it will not unnecessarily block other processes.

Implementing this scheme took only about a rainy afternoon, so you
can't say the effort was that great. What I would like to add is a
time-slice mechanism for CPU bound processes (no GEMDOS calls for a
long time), based for instance on the VBL-interrupt. This is also easy:
if the CPU was in user mode when the interrupt occured (no pending
GEMDOS/(X)BIOS/GEM calls) and the current process has had its slice,
save registers a la GEMDOS and run another process. The blocked reason
that is kept with each process will tell the dispatcher how the
interrupted process must resume when it is ready to.

This program I'll make available through comp.[binaries,sources].atari.st
within a reasonable amount of time (still to do some speed improvement,
the time-slice handling, make it ROM independent and probably the
replacement of C by assembler). Right now it is still wonderfully
small, about 2 or 3 K.

   Leo.