This README contains information relevant to the implementation of the GNAT
tasking run time on top of a thread library.

The 'adainclude' subdirectory containing the sources of the GNAT run time is
located along with the 'adalib' subdirectory containing the ALI files
and the static and/or shared GNAT library in the gcc target dependent area:
     target=$prefix/lib/gcc-lib/`gcc -dumpmachine`/`gcc -dumpversion`/

On some operating systems (Solaris Sparc, Linux, AIX), several (two
or three) run times are delivered with the standard binary release.

On Solaris, three run times are provided, called 'rts-native', 'rts-fsu' and
   'rts-pthread'.
On Linux and AIX, two run times are provided, called 'rts-native' and 'rts-fsu'.

rts-native  offers a binding to the native thread package.
rts-fsu     offers a binding to the FSU threads which provide full Annex D
            semantics.
rts-pthread offers a binding to the Solaris POSIX thread package.

Those run times are installed in the target dependant area and contain a
complete source and binary subdirectory. See a detailled description below
to help you choosing between the different run times.

The default run time (when installing GNAT) is rts-native.

This default run time is selected by the means of soft links. For example on
Linux and AIX:

 $(target-dir)
     |
     +--- adainclude----------+
     |                        |
     +--- adalib-----------+  |
     |                     |  |
     +--- rts-native       |  |
     |    |                |  |
     |    +--- adainclude <---+
     |    |                |
     |    +--- adalib <----+
     |
     +--- rts-fsu
          |
          +--- adainclude
          |
          +--- adalib


If another runtime is to be selected on a permanent basis, these soft links
can be modified with the following commands:

    $ cd $target
    $ rm -f adainclude adalib
    $ ln -s rts-fsu/adainclude adainclude
    $ ln -s rts-fsu/adalib adalib

Alternatively, you can specify 'rts-fsu/adainclude' in the file
$target/ada_source_path and 'rts-fsu/adalib' in $target/ada_object_path.
Please refer to the GNAT User's Guide for more information about these files.

If the other run time is to be selected temporarily, this can be
achieved by regular GNAT object or source path selection, either by
setting the environment variables:

    $ ADA_INCLUDE_PATH=$target/rts-fsu/adainclude:$ADA_INCLUDE_PATH
    $ ADA_OBJECTS_PATH=$target/rts-fsu/adalib:$ADA_OBJECTS_PATH
    $ export ADA_INCLUDE_PATH ADA_OBJECTS_PATH

or by using -aI$target/rts-fsu/adainclude 
        and -aO$target/rts-fsu/adalib
on the gnatmake command line, or by using the new switch --RTS, e.g
--RTS=fsu.

You can similarly switch to rts-pthread on Solaris.
 
Choosing between native or FSU threads libraries
------------------------------------------------

Some GNAT implementations offer a choice between two threads
libraries. On Sparc Solaris, Linux and AIX, you can choose to use either:

  o FSU threads

or

  o Native threads

* The native threads correspond to the standard system threads
implementation (e.g. LinuxThreads on Linux, POSIX threads on AIX or
Solaris threads on Solaris). When this option is chosen, GNAT provides
full and accurate implementation of the core language tasking as described
in Chapter 9, but may not (and probably does not) provide
completely accurate implementation of the Annex D (real time)
requirements. Indeed, the reason that we provide the choice
on a given target is typically that we have found that some of the
ACVC tests for Annex D fail using the native threads. We do try to
map the native threads as well as possible onto Ada requirements,
e.g. modifying priorities as required to simulate ceiling locking,
but there are often slight inaccuracies, most often in the area of
absolute respecting of the priority rules on a single
processor. We can't in general say *exactly* what the semantics
that you will get are, because the native threads implementations
are not well enough documented.

On systems where the SCHED_FIFO POSIX scheduling is supported, native
threads will provide a semantic very close to Annex D requirements
(i.e a run-til-blocked scheduler with fixed priorities), but note that
on some systems (in particular Linux and Solaris), you need to have root
priviledges to use the SCHED_FIFO policy.

* The FSU threads provide a completely accurate implementation of
Annex D requirements, and operating with FSU threads, as far as we
know, GNAT is 100% compliant with both the core and all annex
requirements. The formal validations for implementations offering
a choice of threads packages are always carried out using the FSU
threads option.

From this, it might seem like FSU threads are the better choice,
but that is by no means always the case. The FSU threads package
operates with all Ada tasks appearing to the system to be a single
thread. This is often considerably more efficient than operating
with separate threads, since for example, switching between tasks
can be accomplished without the (in some cases considerable)
overhead of a context switch between two system threads. However,
it means that you may well lose concurrency at the system
level. Notably, some system operations, such as I/O may block all
tasks in a program, rather than just the calling task. More
significantly, the FSU threads approach likely means you cannot
take advantage of multiple processors, since for this you need
separate threads (or even separate processes) to operate on
different processors.

For most standard kinds of processing, the native threads is
usually the better choice. Use the FSU threads if absolute
conformance to annex D is important for your application, or if
you find that the improved efficiency of FSU threads is significant to you.

Note also that to take full advantage of Florist and Glade, it is highly
recommended to use native threads.

The default threads on Solaris is native Solaris threads.
The default threads on Linux is LinuxThreads.
The default threads on AiX is native AiX threads.

Choice of scheduling policy
---------------------------

When using a POSIX thread implementation, there is a choice of several
scheduling policies: SCHED_FIFO, SCHED_RR and SCHED_OTHER.
Typically, the default scheduling is SCHED_OTHER, while using SCHED_FIFO
or SCHED_RR requires special (e.g root) priviledges.

By default, GNAT uses the SCHED_OTHER policy. To specify SCHED_FIFO,
you can either use a pragma Time_Slice (0.0), use the corresponding
binder option (-T0), or use the
pragma Task_Dispatching_Policy (FIFO_Within_Priorities).
To specify SCHED_RR, you should use a pragma Time_Slice with a value
greater than 0.0, or use the corresponding binder option (-T).

Solaris threads specific considerations
---------------------------------------

Starting with version 3.14, GNAT under Solaris comes a new tasking run time
based on posix threads (rts-pthread).
This run time has the advantage of being mostly shared across all POSIX
compliant thread implementations, and also provides under Solaris 8
the PTHREAD_PRIO_INHERIT and PTHREAD_PRIO_PROTECT semantics that can
be selected using the predefined pragma Locking_Policy with resp.
Inheritance_Locking and Ceiling_Locking as the policy.

The native run time as explained above, is based on the Solaris thread
library (libthread) and is the default library.
The FSU run time is based on the FSU threads.


Starting with Solaris 2.5.1 when using the Solaris threads (default)
the default is for programs compiled with GNAT to take advantage of
multiple processors and actually execute on multiple processors.
The user can also specify a processor on which the program should run
on to emulate a single-processor system. This can be easily done by
setting environment variable GNAT_PROCESSOR to one of the following :

    -2 : use the default configuration (run the program on all
         available processors) - this is the same as having
         GNAT_PROCESSOR unset
    -1 : let the RTS choose one processor and run the program on
         that processor
    0 .. Last_Proc : run the program on the specified processor

  Last_Proc is equal to the value of the system variable
  _SC_NPROCESSORS_CONF, minus one.

IRIX threads specific considerations
------------------------------------

On IRIX, the thread library used differs depending on the compiler used:
The o32 ABI compiler comes with a run time based on the user level 'athread'
library. This means that kernel level capabilities such as non blocking system
calls, time slicing can only be achieved reliably by specifying different
'sprocs' via the pragma Task_Info and the System.Task_Info package. See the
GNAT documentation for more details.

The n32 ABI compiler comes with a run time based on the kernel POSIX threads,
and thus, does not suffer from the limitations mentioned above.

Linux threads specific considerations
-------------------------------------

The default thread library under Linux has the following disadvantages
compared to other native thread libraries:

- The size of the task's stack is limited to 2 megs.
- The signal model is not POSIX compliant, which means that to send a
  signal to the process, you need to send the signal to all threads, using
  e.g killpg().

