Subtasks
-=-=-=-=

Subtasks are an extremely powerful way of doing processing. They are
TAOS-like in the way they can process in multiple threads. The benefits of
TAOS are well known, and most of those benefits are available to tornado
apps.
   A tornado subtask is a normal tornado task, except that it is subject to a
number of restrictions - they are only allowed to access memory within their
own space and within the subtask heap, and can only communicate normally with
their parent and their sibling subtasks. Generally speaking, they fill a
buffer of processed data and pass this to their parent ie; they do their
processing in sections.
   The main advantage of using subtasks is that it allows a bit more of
multithreading than usual with Basic. Due to Basic's structure, execution
cannot occur at different parts of the program at the same time, so by using
subtasks a Basic programmer can still have limited multithreading.
   Another advantage is that with the arrival of multiprocessor Acorn's, the
subtask can be executed on a seperate processor - and thus giving all the
obvious advantages.
   An example of this is a http fetcher. The parent html viewer, is asked to
fetch http://www.acorn.co.uk for example. The parent, a tornado task, starts
up one of its private subtasks stored within its directory (some subtasks are
stored for public use ie; any tornado task can use them) which fetches http:
links.
   The subtask starts, and uses ttcpip: to send a http request. When
receiving confirmation, it passes the message to its parent which displays
the appropriate message. Then the html page arrives in packets, as is in
tcpip's nature, and this is run through, picking out all the references to
graphics/sound/movie. The graphics/movie are then sent for, by the subtask
starting up siblings, which in fact are copies of itself. Each of these
siblings reads in the graphic/first fram of the movie, checks what format it
is, and then starts up the appropriate graphic convertor from the public
convertor library, passing it the reference by which it can send its
processed data to the parent app.
   Ok, so now the picture looks like this:

                         Parent html (www) viewer
                                    | Passes down http://www.acorn.co.uk
                                    |
                                    | Passes up html document
                               http fetcher
  Passes down http://www.         / | \         Passes down http://www.acorn.
 acorn.co.uk/     ---------------   |   ----------------    co.uk/sprite.gif
 drawfile.gif   /      Passes down http://www.acorn.     \
               |             co.uk/movie.rply             |
               |                    |                     |
               |                    |                     |
         http fetcher        http fetcher            http fetcher
  This being a private       Passes | down all     Passes | down all the
 subtask knows its parent  the data | received       data | received
 can plot drawfile, so it           |                     |
 sends its received data            |                     |
 straight back to its     Passes up | when to stop    GIF=>Sprite
 parent. If it were a       sending | data             convertor
 public subtask it would      Replay=>Sprite        This takes the GIF
 check what filetypes the       convertor           and converts it into
 parent can load, and       This takes enough       a sprite, and sends the 
 convert to sprite if it    data to convert the     data, as processed, back
 couldn't handle drawfiles  first frame into a          to the parent
                            sprite and also sends       / | \
                            all the data processed  Delegated tasks
                            straight back to the    The same as below, except
                                  parent            obviously it's multiple
                                  / | \             copies of the GIF=>Sprite
                             Delegated tasks           convertor
                          These are seperate copies
                          of the Replay=>Sprite
                          convertor called when the
                          convertor above this is still
                          processing but is asked to
                          process another segment of
                          data retrieved from ttcpip:

As you can see, processing of all data coming in performed simultaneously,
which means that no matter how quickly the data comes in, it is all
processed, not held up until the processing and conversion routines can deal
with it. The speed and productivity gains are impossible to calculate. It
also means that the parent html viewer may have bits of gif appearing in a
seemingly random order, which I would suggest is not altogether bad.

Subtasks are also subject to constant monitoring - should one fail due to
lack of memory, it's parent is notified and can do what it likes with the
information eg; schedule a retry, or perhaps inform its parent (if a
subtask). It may also display a message/put a question to the user via
Tornado_Query.
   Should a subtask crash, it gets the same treatment as other tornado tasks
- except that again its caller is notified after everything has been cleaned
up. Subtasks can also request that a postslot heap be set up, so they can
store internal memory allocations.
   Another feature of subtasks is that all vdu output is sent to its parent.
This can be used to run normally single-tasking tasks eg; my hopefully
forthcoming animals guessing game door for Newsflash will be the raw program
in Basic as written in 1993, but with a parent 'supervisor' which starts up
the program as a subtask, reads in all graphics input, converts any vdu
colour sequences/cursor positioning into suitable ANSI commands, and spits
that down the line to Newsflash.

Special subtasks
-=-=-=-=-=-=-=-=

Special subtasks currently come in as file convertors. If a user drags a GIF
file onto a tornado app which can only accept Sprites, then the convertor
subtask (stored in tconvert:) list entry called by the 32bit hexadecimal of
the GIF filetype is checked out to find out what that filetype can be
converted to. If it can be converted to a format that is loadable by the app
the file is going to, the GIF file is loaded into tfs: while multitasking,
and the subtask, as specified by the subtask list, is started up. The parent,
Tornado, sets up an area of memory to receive the file, and the subtask
starts spitting out converted Sprite.
   When the subtask finishes, the original GIF data is thrown away and the
file is loaded into the app by Tornado (see the appropriate document about
loading and saving). Voila!
   On saving, in the save box a GIF filesprite is shown, and unless the user
changes it, the file is saved to tfs:, converted back by the appropriate
subtask (this time determined from the entry for the hexadecimal of the
sprite filetype).

Other things about subtasks
-=-=-=-=-=-=-=-=-=-=-=-=-=-

Another thing to be noted here is that Tornado is intelligent about subtasks.
It caches the most recently loaded subtasks so that they may be accessed
quicker, if the user so wants, in tfs: (if present).
   As said above, subtasks may not be necessarily executed on the local
processor. They may also be executed on a second processor, or on a processor
running somewhere on a network. Many people laughed at my original claim that
the processor may be running on the other side of the world, connected via
Internet. This is not unrealistic. Because subtasks communicate by
Tornado_SendSTMessages and Tornado_GetSTMessages, and think they are the only
process running in the machine, they can be run by a suitable
multitasker/server. A client running on the local machine can send the
subtask code down the network to the server, wherein it is cached and can be
kept for future use. All messages between parent and subtask can be run over
the network. Easy!

Summary of subtasks: they are extremely powerful, and their importance in the
Acorn world can only increase, if not within Tornado but by the probable
implementation of TAOS for the Arm series of processors.
