--::::::::::
--realtime_rd.me
--::::::::::
PD2:

This subdirectory contains documents and items of Ada
software which address questions and standards dealing with the
real-time use of the Ada programming language.

Documents and information generated and presented by the
Ada Runtime Environment Working Group (ARTEWG) are made available
in this subdirectory.
--::::::::::
--cidissue.doc
--::::::::::




                                    














                                    

                         Catalogue of Ada (*)

                        Runtime Implementation

                             Dependencies

                                    

                                    


                           November 6, 1986






                                    

                             PREPARED BY

                 Association for Computing Machinery
                    Special Interest Group on Ada
                Ada Runtime Environment Working Group







_________

(*) Ada is a registered trademark of the U.S. Government.




                                    
























Copyright (C) 1986 by the Association for Computing  Machinery,  Inc.,
Special  Interest Group on Ada, Ada Runtime Environment Working Group.
Copying without fee is permitted provided that the copies are not made
or  distributed  for  direct  commercial  advantage  and credit to the
source is given.  Abstracting with credit is permitted.   Photocopying
and  electronic  data  transmission of this document are permitted for
private use.




                                   CONTENTS

        1       Rationale  . . . . . . . . . . . . . . . . . . . . . 1
        2       ARTEWG Background  . . . . . . . . . . . . . . . . . 3
        3       Reader's Guide . . . . . . . . . . . . . . . . . . . 7
        4       Implementation Dependencies  . . . . . . . . . . . . 9
        E       Comments . . . . . . . . . . . . . . . . . . . . .  75
        E.1       Old Issues . . . . . . . . . . . . . . . . . . .  75
        E.2       New Issues . . . . . . . . . . . . . . . . . . .  78
        E.3       Evaluations  . . . . . . . . . . . . . . . . . .  81













































                                  i

1  Rationale

The Ada language was defined to be  implementation  independent.   The
designers  of  the  language  chose  to  do  this to avoid tying it to
current technology so that new advances in technology could be readily
accepted.    Consequently  there  are  many  places  in  the  language
definition where implementors of the language are free to decide how a
language  feature  is to be performed (as long as the feature conforms
to the rules of the language).  A simple example  is  the  freedom  to
order  the  execution  of operators in an expression.  This freedom is
both a boon and bane to application developers.  It means  that  there
may be a wide variety of ways that features of the Ada language can be
implemented.  Some of these ways may be good and some may be  bad  for
an  application,  in terms of its performance and reusability.  If the
application  has   significant   requirements   for   performance   or
reusability,   then  these  variations  must  be  known  in  order  to
effectively handle them.

The main goal of this catalogue is to be the one place where  all  the
areas  of  the  Ada  Reference Manual (RM) which permit implementation
flexibilities can be found.  The Ada Runtime Environment Working Group
(ARTEWG)  has  analysed the RM and other associated documents, such as
the Ada Implementor's Guide, to find those areas  where  the  language
definition has left the implementation details up to the Ada compilers
which  implement  them.   The  RM   explicitly   calls   these   areas
"implementation  dependencies",  which  is  the  term the ARTEWG uses,
hence the title of this catalogue.

There are  several  benefits  that  cataloguing  these  implementation
dependencies  provide.   First  it serves as a guideline for analysing
Ada implementation technology.  For each  of  these  dependencies  Ada
compilers  can  be examined to determine how the dependency is handle.
Examining all Ada compilers can  provide  a  full  range  of  the  Ada
implementation technology for each feature.  Each application can then
determine how effectively Ada implementation technology  supports  its
needs  and  indirectly  which  implementation  is  best  suited to the
application.

Another benefit supplied  by  the  catalogue  is  a  laundry  list  of
concerns  for  those  who  are  procuring  an  Ada  compiler.  The Ada
compiler buyer can examine the list to  find  which  dependencies  are
significant  to their application.  Those significant dependencies can
then be one of the criteria which the buyer can use  in  selecting  an
Ada compiler.

This catalogue is not a guideline for writing erroneous programs.   In
analysing the Ada language, all dependencies were enumerated.  For the
sake of completeness, the list includes some dependencies which may be
considered to be erroneous programming.  The ARTEWG in no way endorses
their use in any Ada programming style.

It should be noted that this catalogue is  an  evolutionary  document.
This  initial  version  is  not  the  final word on the implementation
dependencies in Ada.  While the ARTEWG members put considerable effort

                                  1

into the analysis, it is a sure bet that some dependencies were missed
and some dependencies in this catalogue don't belong.  It  is  through
the  review  process that the ARTEWG hopes to improve the contents and
effectiveness of the catalogue.  For this reason, issue submittal  and
review forms are included in the appendix to this catalogue.


















































                                  2

2  ARTEWG Background

The Ada user community wants to know more about  runtime  environments
so  that they can effectively choose among alternative implementations
and argue for better solutions.  There is much anxiety in the Ada user
community that current and future Ada implementations will not satisfy
the runtime requirements for many real applications and that there  is
no means to voice concerns to the AJPO over Ada runtime issues.  While
at the same time there is a lot of energy to work with  the  AJPO  and
Ada  implementors  to  produce  workable and consistent solutions.  To
satisfy these goals it was apparent there was much  work  to  be  done
which  only a serious effort of a dedicated working group, such as the
Ada Runtime Environment Working Group (ARTEWG), could fulfill.

The goals of  the  ARTEWG,  sponsored  by  SIGAda,  are  to  establish
conventions,  criteria,  and  guidelines  for Ada runtime environments
that facilitate the reusability and transportability  of  Ada  program
components, improve the performance of those components, and provide a
framework which can be used to  evaluate  Ada  runtime  systems.   The
ARTEWG  expects  to  be a mechanism for users to interface effectively
with Ada implementors,  thereby  encouraging  development  of  runtime
environments   that  meet  user's  needs.   The  AJPO  recognizes  and
encourages the objectives of the  ARTEWG,  and  is  receptive  to  the
consolidated  voice  of the Ada community as represented by the ARTEWG
on Ada runtime environment issues.

The ARTEWG has established an initial plan of action  which  it  feels
will  address its goals.  This plan of action was developed to produce
results within two years.  The continued operation of ARTEWG  will  be
based on the success of its initial products and services and the need
to  improve  upon  those  products.   The  ARTEWG  has  established  a
framework of baseline tasks as follows:

      *  Elaborate the implementation dependencies both  explicit  and
         implicit  by  examining  the  Ada  Reference  Manual, the Ada
         Implementors'  Guide,  the  current  literature,  and   other
         resources.

      *  Categorize the different implementation choices for  the  Ada
         runtime  environments by gathering empirical evidence through
         an across-the-board evaluation of Ada implementations.

      *  Categorize applications and their  requirements  on  the  Ada
         runtime     environments    through    an    across-the-board
         investigation of DoD applications.

      *  Map    applications    requirements    onto    the    current
         implementations  of Ada runtime environments to determine the
         capability of Ada runtime environments to handle  application
         needs.

      *  Synthesize  the  application   mapping   onto   Ada   runtime
         environments  to  promote  a commonality of interfaces to the
         user to improve effectiveness of the Ada runtime  environment

                                  3

         technology.


The purpose of the ARTEWG products is  to  educate  the  general  user
community  to  the  significance  of the runtime environment to an Ada
program and show ways that the user can  make  educated  decisions  in
selecting and using various Ada runtime environments.  The ARTEWG does
not expect to act as Ada "underwriters lab" or "consumer's union"  but
rather  as  an informational service.  The initial plan of action will
produce the following five baseline products:

      *  Catalogue  of   implementation   dependencies   for   runtime
         environments  which  identifies  all  the  areas  in  the Ada
         language   definition   where   Ada   implementations    have
         flexibility.

      *  Catalogue   of   implementation   approaches   for    runtime
         environments which describes the range of approaches provided
         by the current Ada implementation technology.

      *  Survey of application requirements which is  a  synthesis  of
         DoD mission-critical applications.

      *  Guidelines (i.e., friendly advice) for effectively using  Ada
         runtime  environments;  this  is  derived  from  mapping  the
         synthesis of application requirements onto the current  state
         of Ada runtime environment technology.

      *  Catalogue of proposed  Ada  runtime  environment  interfaces,
         with  rationale  and feasibility, to improve effectiveness of
         the Ada runtime environment technology


Additionally several other by-products will  be  produced  from  these
efforts:

      *  Ada Runtime Transportability Handbook, which  includes  major
         elements of the baseline products.

      *  Catalogue of consistent Ada runtime environment  terminology,
         part of a Canonical Definition to Ada Runtime Environments.

      *  Guidelines for evaluating Ada runtime environments.

      *  Requirements  for  an  effective  Appendix  F  in   the   Ada
         Reference.

      *  File of Ada runtime environment issues.

      *  An annotated bibliography  of  papers,  articles,  and  other
         publications related to runtime environments.




                                  4

As for services, the ARTEWG expects to  accomplish  several  important
services  in  the  course of its work.  By bringing together users and
implementors  as  members,  ARTEWG  will  provide  the  mechanism  for
effectively  interfacing  users  and  implementors  to produce runtime
environments that meet user's needs.  Through the use of  the  Arpanet
and   other  internal  and  external  communication  medium  the  user
community will be able to voice concerns and  propose  recommendations
about Ada runtime environments.  With the attention that AJPO plans to
give ARTEWG, ARTEWG can amplify these concerns and recommendations  to
the appropriate groups which serve the AJPO.

This  document,  the   Catalogue   of   Ada   Runtime   Implementation
Dependencies,  is  the  first  baseline  product produced by the first
baseline task.









































                                  5
                                    






















































                                  6

3  Reader's Guide

The Ada programming language was designed to support a wide variety of
applications  as  well  as a wide variety of computing systems.  In an
attempt to provide maximum language portability while still  retaining
requisite  performance  in  that diverse environment, the Ada language
definition had to walk the fine  line  between  specifying  everything
completely   and   yet  being  flexible  enough  to  permit  efficient
implementation  on   those   diverse   computers.    That   definition
(ANSI/MIL-STD-1815A)   provides   considerable   flexibility   in  the
implementation of features which can impact the  run-time  performance
of  an  Ada  application.   Even  though  a  close  examination of the
reference manual would uncover  some  of  those  areas,  many  of  the
features  are  subtle  and require extensive review to identify.  This
catalogue is an attempt to itemize those "implementation dependencies"
of  Ada and describe their impact on the reusability, transportability
and performance of Ada applications.

To more accurately describe the  relationship  between  implementation
dependencies   and   the  Ada  language,  this  catalogue  maps  those
dependencies  to  the  Ada  reference  manual.   Each   implementation
dependency   is   identified   to   a   particular  chapter,  section,
sub-section, and paragraph of the Ada reference manual.  To facilitate
identification  of  individual issues, and to relate issues to the Ada
RM, each issue has been  assigned  a  unique  issue  number  with  the
following form:

     .
[.
](). Where "" identifies the appropriate chapter of the Ada RM, "
[.)" identifies the paragraph number (shown in the margin of the Ada RM), and "." is a unique number assigned to multiple issues in the same paragraph. 7 In this catalogue, Ada runtime implementation dependency issues are shown using the following format: number -- Topic. Question. Type: Rationale: Brief rationale describing the issue. Example: Brief example showing the issue in Ada. Each issue is identified by its "number" (as described earlier) followed by a brief "topic" line. Each issue is then posed as a specific "question". By identifying the answer to each question for a particular Ada implementation, an Ada application developer can gain a clearer understanding of the impact of those dependencies on the development of the particular application. Each question is followed by a short "rationale" describing why that issue is an Ada implementation dependency. Finally, an Ada "example" is presented which further elucidates the implementation dependency. To help in the development of these issues, if an example could not be generated for a proposed issue, it was decided that the issue did not, in fact, exist. Finally, in order to develop a more refined and complete catalogue, three forms are contained in the appendix: two issues submittal forms and a review form. The issues forms are included to permit new issues to be added or old issues to be modified. Finaly, a review form is included to help in reviewing this catalogue. Your help in improving this document is greatly appreciated. 8 4 Implementation Dependencies 1.6(7).1 Effect of erroneous execution. What is the effect of erroneous execution? Type: Explicit. Rationale: The effect of erroneous program execution should be known to the user. This question must be answered for all specific instances indicated as questions in other chapters. Example: TBD. 1.6(9).1 Effect of incorrect order dependencies. What is the effect of incorrect order dependencies? Type: Explicit. Rationale: The effect of incorrect order dependencies should be known to the user. This question must be answered for all specific instances indicated as questions in other chapters. Example: TBD. 3.2.1(15).1 Evaluation of default expressions. When are default expressions for components of a record evaluated? Type: Explicit, Incorrect Order. Rationale: The check can be made anytime between evaluation and assignment, and all evaluations are done before all assignments. If the check is done after each evaluation and a CONSTRAINT_ERROR is raised, then some of the evaluations will not take place. Example: There is no way to insure that variables have been initialized before being referenced. Some applications may work correctly on some implementations but not on others. 9 3.2.1(17).1 Evaluation of scalar variables. What is the value of a scalar variable that has not been initialized? Type: Explicit, Erroneous. Rationale: The execution of a program is erroneous if it attempts to evaluate a scalar variable with an undefined variable, or attempts to apply a predefined operator to a variable with a scalar subcomponent having an undefined value. Example: TBD. 3.5(5).1 Range constraint evaluation. What is the order of evaluation of simple expressions specifying range bounds? Type: Explicit, Incorrect Order. Rationale: The RM permits an implementation to evaluate the simple expressions of a range constraint in any order. Some applications may work correctly on some implementations but not on others. Example: If a simple expression contains a function with side effects or is dependant upon external events, the evaluation of the range constraint may produce different results. Consider: G: INTEGER := 0; function F return INTEGER is begin G := G + 1; return G - 1; end F; ... S: STRING (F..F); The size of S is either "0..1" or "1..0" (i.e., null) depending upon the order of evaluation of F. 3.5.4(10).1 NUMERIC_ERROR. 10 Does the implementation raise NUMERIC_ERROR on an operation that is not necessary for the result of the larger expression? Type: Explicit. Rationale: Tells about how expressions are evaluated and whether or not some exceptions will be raised. Example: TBD. 3.6(10).1 Index evaluatation order. What order are the evaluation of ranges of index constraints and elaborations of component subtype indications for an array performed? Type: Explicit, Incorrect order. Rationale: TBD. Example: TBD. 3.6.1(11).1 Index constraints. What order are index constraints evaluated? Type: Explicit, Incorrect Order. Rationale: TBD. Example: TBD. 3.7.2(13).1 Discriminant evaluation order. What is the order for evaluation of discriminant associations? Type: Explicit, Incorrect Order. 11 Rationale: TBD. Example: TBD. 3.9(4).1 Elaboration check. Does the implementation eliminate any runtime elaboration checks? Type: Explicit. Rationale: If an implementation does, it will improve performance. Example: TBD. 3.9(5).1 Elaboration of non-Ada subprogram bodies. How does the implementation handle the elaboration of non-Ada subprogram bodies? When are they considered to be elaborated? Type: Implicit. Rationale: TBD. Example: TBD. 3.9(6).1 Task elaboration check. Does the implementation perform elaboration checks for a set of tasks before any of them are activated? Type: Implicit. Rationale: LRM doesn't require that elaboration checks be done for all task bodies before any are activated. 12 Example: TBD. 4.1.1(4).1 Evaluation of an indexed component. In what order are the expressions in an indexed component evaluated? Type: Explicit, Incorrect Ordering. Rationale: The side effects of the expression evaluation may be different based on the order of evaluation chosen. The expressions found in prefix may be evaluated before the expressions for the indices of the indexed component or vice-versa. Likewise, the expressions within the prefix or the expressions for the indices may be evaluated in either left-to-right or right-to-left order. Example: The evaluation of an indexed component evaluates the index expressions and the prefix in an order that is not defined by the language. Since some order is chosen, this means that if any evaluatable construct in a prefix is evaluated, then all such constructs must be evaluated before evaluating the index expressions, or vice-versa. The following example illustrates this point: ... FUNCX (F1, F2) (F3, F4) ... Assuming that F1, F2, F3, and F4 are functions with side-effects and then the following evaluation orders are allowed: F1, F2, F3, F4 F3, F4, F1, F2 F2, F1, F3, F4 F3, F4, F2, F1 F1, F2, F4, F3 F4, F3, F1, F2 F2, F1, F4, F3 F4, F3, F2, F1 All other evaluation orders are not permitted. 4.1.2(4).1 Evaluation of a slice. In what order are the expressions in a slice evaluated? Type: Incorrect Ordering. 13 Rationale: The side effects of the expression evaluation may be different based on the order of evaluation chosen. The expressions found in prefix may be evaluated before the expressions for the range of the slice or visa-versa. Likewise, the expressions within the prefix or the expressions for the range of the slice may be evaluated in either left-to-right or right-to-left order. Example: The evaluation of a slice evaluates the expressions of the range and the prefix in an order that is not defined by the language. Since some order is chosen, this means that if any evaluable construct in a prefix is evaluated, then all such constructs must be evaluated before evaluating the range expressions of the slice, or vice-versa. The following example illustrates this point: ... FUNCX (F1, F2) (F3..F4) ... Assuming that F1, F2, F3, and F4 are functions with side-effects and then the following evaluation orders are allowed: F1, F2, F3, F4 F3, F4, F1, F2 F2, F1, F3, F4 F3, F4, F2, F1 F1, F2, F4, F3 F4, F3, F1, F2 F2, F1, F4, F3 F4, F3, F2, F1 All other evaluation orders are not permitted. 4.1.4(4).1 Implementation-defined attributes. What attributes, in addition to those in Appendix A, does the implementation support? Type: Explicit. Rationale: New attributes provided by an implementation may provide values that are unique to the runtime environment of that implementation. Example: An implementation may provide several additional addressing attributes that extract the base register and displacement components of an address, namely, A'BASE_REGISTER and A'DISPLACEMENT. These attributes would then be applied to the value produced by the ADDRESS attribute, as these examples show: 14 X'ADDRESS'BASE_REGISTER -- produces the base register number X'ADDRESS'DISPLACEMENT -- produces the displacement value Such attributes may not be found in other implementations. 4.2(1).1 Representation of a literal. How are literals represented in the execution program? Type: Implicit. Rationale: Literal values may be represented in the execution program as storage data or as part of the actual machine instructions in the data field of an immediate machine instruction. Additionally redundant occurrences of the same literal in the same or different scope may be represented by the same bit string value in storage. The choice made will effect the size of code and data storage of the program. Example: Some literal values, especially small ones such as integers, booleans, and characters, may be represented as a value in the data field within an immediate instruction of the target computer. Example instructions may be "store immediate" or "add immediate." An implementation may, for efficiency reasons, choose to represent these values directly in the data field of these immediate instructions. Thus the integer expression: A + 2 may be encoded in the following machine instruction sequence: LOAD A ADD 1220 -- where 1220 is the storage location -- containing the integer value 2 or it may be encoded in the following alternative instruction sequence: LOAD A ADDI 2 -- that is, add immediate the small integer -- value 2. 4.3(1).1 Representation of aggregates. How are aggregates represented in the execution program? Type: Implicit. 15 Rationale: Aggregate values may be represented in the execution program as contiguous storage data or they may encoded within a sequence of statements. The choice made will effect the size of the code and data storage of the program. Example: Aggregates may be represented as a contiguous block of storage data. This is true when all the values of the aggregates component are known at compile time. Thus the aggregate: (1|4|7 => 15, 2|3|5|6 => -5, 8..10 => 0) may be represented in a block of ten storage units containing various values of -5, 0, and 15. Conversely, aggregates may be encoded within a sequence of code. This is necessary for aggregates with component values generated at runtime. The sequence of code generated usually varies with the context of use of the aggregate. An assignment statement provides an example of this imnplementation choice: B : = (1..10 => 5, 11..100 => 0); The implementation in this case may choose to generate a sequence of code equivalent to the following Ada statements, instead of generating a contiguous block of storage: for I = 1 to 10 loop B(I) := 5: end loop; for I = 11 to 100 loop B(I) := 0; end loop; Other elements that affect the choice made by the implementation are the availability of space, the availability of high level machine instructions, such as block moves and compares, and the percentage of unique values in the aggregate. 4.3.1(3).1 Evaluation of record component expressions. In what order are the expressions in the component associations of a record aggregate evaluated? Type: Explicit, Incorrect Ordering. Rationale: 16 The expressions found in component associations may be evaluated in either left-to-right, right-to-left or any arbitrary order. In either case the side-effects of the expression evaluation may be different based on the order of evaluation chosen. Example: The evaluation of a record aggregate evaluates the expressions in the component associations in an order that is not defined by the language. As an example for the record aggregate: (A => FUNX, B => FUNY, C => FUNZ) the order of evaluation might be FUNX-FUNY-FUNZ or FUNZ-FUNY-FUNZ. If FUNX or FUNZ affect each other either directly through common global variables or indirectly through calls to the runtime system, the behavior or the results of those evaluations may be significantly different. 4.3.2(10).1 Evaluation order of choices and expressions. In what order are the choices and the expressions for the component associations in an array aggregate evaluated? Type: Explicit, Incorrect Ordering. Rationale: The expressions found in choices must be evaluated before the expressions for the component associations of an array aggregate. Likewise, the expressions in the choices or the expressions for the component associations may be evaluated in either left-to-right, right-to-left, or any arbitrary order. In either case the side-effects of these expression evaluations may be different based on the order of evaluation chosen. Example: The evaluation of an array aggregate evaluates the choices and then the expressions in the component associations in an order that is not defined by the language. As an example for the array aggregate: (1..FUNA => FUNX, FUNA + 1..FUNB => FUNY, FUNB +1..100 => FUNZ) the order of evaluation might be FUNA-FUNB=FUNX-FUNY-FUNZ or FUNB-FUNA-FUNZ-FUNY-FUNZ. If FUNA or FUNB or FUNX or FUNZ affect each other either directly through common global variables or indirectly through calls to the runtime system, the behavior or the results of those evaluations may be significantly different. 17 4.3.2(11).1 Order of constraint checking. Are constraints on choices or on the values of expressions of component associations checked before all choices or expressions are evaluated? Type: Explicit. Rationale: The RM leaves an implementation free to perform constraint checks before all the choices or expressions are evaluated. If the consequence of performing a constraint check is to raise an exception, then an additional consequence is that certain expressions or choices may not have yet been evaluated. Example: Take the simple aggregate below: (1..5 => EXPX, 6..10 => EXPY) Implementations are free to generate code that performs constraint checking either after one or both expressions are evaluated. Assume that the side-effects from evaluating the expressions in any implementation will cause the value of EXPY to raise a CONSTRAINT_ERROR if it is evaluated before EXPX. If an implementation performs constraint checking after each expression is evaluated then the EXPX will not be evaluated if the order of evaluation is EXPY-EXPX. 4.5(5).1 Evaluation of operands in an expression. In what order are the operands in an expression evaluated? Type: Explicit, Incorrect Ordering. Rationale: The side-effects of the operand evaluation may be different based on the order of evaluation chosen. The operands found in expression may be evaluated in any order. Example: The evaluation of an expression evaluates the operands in the expression in an order that is not defined by the language. As an example for the expression OPNDX + OPNDY + OPNDZ, the order of evaluation might be OPNDX-OPNDY-OPNDZ or OPNDZ-OPNDY-OPNDX as well as others. If OPNDX or OPNDZ affect each other either directly through common global variables or indirectly through calls to the runtime system, the behavior or the results of those evaluations may be significantly different. 18 4.5(7).1 Raising NUMERIC_ERROR exception. In an expression, if an operand yields a value outside the base type, yet the result is mathematically correct, is NUMERIC_ERROR exception raised? Type: Explicit. Rationale: The NUMERIC_ERROR exception check for the value of an expression is required to be performed on the final result of the expression. For some base types, an implementation may calculate intermediate results with greater precision than that requested for the base type of the expression, which may avoid the NUMERIC_ERROR exception as long as the result is a value of the base type. Example: Consider: X := (A * B)/C; Suppose A, B, C, and X are INTEGER variables. NUMERIC_ERROR need not be raised if A*B lies outside the range of the base type as long as the quotient lies with the range. If the quotient does not lie within the range, then NUMERIC_ERROR should be raised. 4.5.7(7).1 NUMERIC_ERROR exception for real operations. What happens when the result of a real operation in an implementation, whose value of MACHINE_OVERFLOWS is false, is not in the range of safe numbers? Type: Explicit. Rationale: The RM does not require that an implementation whose MACHINE_OVERFLOWS is false to raise NUMERIC_ERROR when the result of a real operation has an model interval that is undefined. This error condition may go undetected. Example: The example most often cited for this case are computers that don't permit easy detection of overflow situations. 4.5.7(10).1 Comparisons of real operands. 19 For a relational operator what is the range of accuracy for the relational comparison? Type: Implicit. Rationale: For the result of a relation between two real operands, the result can be any value obtained by applying the mathematical comparison to a value arbitrarily chosen in the corresponding operand model intervals. This potential imprecision makes the results of comparisons implementation dependent. Example: Consider that "not (A < B)" need not be equal to "(A >= B)" under certain circumstances. This happens when the model intervals associated with A and B have more than one value in common. The values of A and B are, for non-model numbers, implementation defined within certain limitations, which consequently makes the results of comparisons implementation dependent. 4.6(7).1 NUMERIC_ERROR exception for real conversions. What happens when the result of a conversion to a real type on an implementation, whose value of MACHINE_OVERFLOWS is false, is not in the range of safe numbers? Type: Implicit. Rationale: The RM does not require that an implementation whose MACHINE_OVERFLOWS is false to raise a NUMERIC_ERROR when the result of a conversion has an model interval that is undefined. This error condition may go undetected. Example: The example most often cited for this case are computers that don't permit easy detection of overflow situations. 4.6(7).2 Rounding for integer conversions. In a conversion of a real value to an integer type, if the operand is halfway between two integers which way is it rounded? Type: Explicit. Rationale: 20 The RM does not specify what kind of rounding is to be performed when converting real values, whose values lie in between two integers, to integer types. Example: Here is a list of some of the different kinds of rounding that can be applied to real-to-integer type conversion: INTEGER(1.5) -> 2 and INTEGER(-1.5) -> -2 -- normal INTEGER(1.5) -> 2 and INTEGER(2.5) -> 2 -- round to even INTEGER(-1.5) ->-1 and INTEGER(-2.5)->-3 -- round to even -- 2's complement INTEGER(1.5) -> 2 and INTEGER(-1.5) -> -1 -- round up INTEGER(1.5) -> 1 and INTEGER(-1.5) -> -2 -- round down 4.8(7).1 Storage reclamation. Does the implementation do any automatic resource reclamation of storage occupied by an object created by an allocator once the object is no longer accessible, and if it does when is the reclamation performed? Type: Implicit. Rationale: An implementation may (but need not) reclaim the storage occupied by an object created by an allocator, once this object has become inaccessible. This form of reclamation or garbage collection affects the speed and data storage of the executable program. Example: An implementation may use one of many garbage collection schemes to reclaim objects created by allocators which are no longer accessible. A garbage collection scheme usually works by periodically searching over all such objects to find the ones that are inaccessible. In addition to this overhead these schemes require some ongoing bookkeeping to maintain the accessibility of objects created by allocators. This is a classic case of time versus space performance tradeoff. The timing of the reclamation may be critical to the performance of the application. If the reclamation is performed too much it may affect the timing while if the reclamation is performed too little the application runs the risk of running out of storage. Finally being largely non-deterministic the reclamation may be timed to occur during a critical portion of the application affecting the timing of the application. 4.9(12).1 Accuracy of static real expressions. 21 What differences exist between the accuracy of compile-time evaluation versus runtime evaluation of static expressions? Type: Implicit. Rationale: An implementation is not required to produce the same value for a static expression by compile-time evaluation on a host computer system as it would produce for the same expression at runtime on the target computer system. These values are only required to be in the same model number interval. An implementation is required to evaluate a static expression at compile-time when the context requires a static expression. The consequence of this potential imprecision makes the results of comparisons implementation dependent. Example: Consider the following declaration with the static real expression: SOMETHING : REAL := EXPX + EXPY + EXPZ; Now consider this function: function WOW (A : REAL := EXPX, B : REAL := EXPY, C : REAL := EXPZ) return REAL is...end; If within WOW there is a relational expression: (A + B + C) = SOMETHING it may not produce an equal comparison when WOW is called with no parameters. This happens when the model intervals associated with the REAL type have more than one value in common. The values of SOMETHING and (A + B + C) are, for non-model numbers, implementation defined within certain limitations, which consequently makes the results of comparisons implementation dependent. 4.10(5).1 Raising NUMERIC_ERROR exception. What happens when the result of a non-static universal real operation in an implementation is not in the range of safe numbers of the most accurate predefined floating point type? Type: Implicit. Rationale: The RM does not require that an implementation to raise a NUMERIC_ERROR when the result of a real operation has an model interval that is undefined. This error condition may go undetected. 22 Example: The example most often cited for this case are computers that don't permit easy detection of overflow situations. Statements 5.1(5).1 Execution of a null statement. Does the NULL statement generate code which consumes resources? Type: Explicit. Rationale: Code efficiency considerations. Example: TBD. 5.2(3).1 Assignment statement evaluation. In what order are the variable-name and expression evaluated om an assignment statement due to side effects of functions? Type: Explicit, Erroneous. Rationale: TBD. Example: TBD. 5.2(3).2 Assignment statement evaluation. In what order are the variable-name and expression evaluated om an assignment statement due to side effects of functions? Type: Explicit, Incorrect Order. Rationale: TBD. Example: 23 TBD. 5.4(1).1 Case statement implementation. If the compiler chooses between a jump table and a series of comparisons and braches to implement the case statement, what criteria does the compiler use to make the selection and what user control is supplied over the selection? Type: Explicit. Rationale: The optimal choice may not always be determinable by the compiler. Applications which are limited in the amount of space available to store jump tables, but which have sufficient instruction space, may want to force the compiler to never use jump tables. Example: TBD. 5.6(4).1 Elaboration of block statement. What overhead does the elaboration of a block statement have on the runtime state of the program? Type: Explicit. Rationale: For machines containing a based addressing mode, are the base registers reallocated? Effective use of base registers is a key to good code efficiency for machines like the MIL-STD-1750A. Example: TBD. 6.1(10).1 Static allocation. If a procedure is not called recursively, nor in the presence of tasking, can local objects be allocated statically? What control does the user have over the storage allocation process? Type: Explicit. Rationale: 24 The RM states that all subprograms can be called recursively and are reentrant. This question deals only with those cases in which sufficient information to realize that there is no requirement for more than one copy of local objects is available to the compiler. In these instances, static allocation of local objects is possible, and static allocation may incur less runtime overhead than dynamic allocation. If the amount of static memory available to an application is limited, though, dynamic allocation could be preferable to static allocation. Therefore, the user could desire the capability to choose whether static or dynamic allocation is used for local objects. Example: Assuming that it is known that there is only one copy of the following function and that it is not called recursively and that reentrancy is not needed, can the variable SUM be allocated statically? (The example is from section 6.5 of the RM.) function Dot_Product (Left, Right : VECTOR) return REAL is Sum : REAL := 0.0; begin ... 6.2(5).1 Value of scalar out parameters. For subprograms that do not update scalar out parameters, what is the value upon return from the subprogram? Type: Explicit. Rationale: The RM states that the value of a scalar out parameter that is not updated is by the called subprogram is undefined upon return. There are several different actions a compiler could take in this situation, each resulting in a different runtime behavior of the program. Some of the possible actions, of which some may not be clearly legal, are: (1) Copy back whatever bit pattern is in the storage location associated with the parameter (possibly causing a CONSTRAINT_ERROR exception), (2) Omission of the copy back operation, (3) Raise the PROGRAM_ERROR exception at runtime. In addition, a compile-time diagnostic message could be generated. It is not possible to detect all instances of non-updated out parameters before program execution. Does the compiler generate execution time code to check for this situation? The behavior of a compiler affects 25 the behavior of the application program. Example: In the following code fragment, the actual parameter associated with A is never updated and the actual parameter associated with B may not be updated: procedure P (A : out POSITIVE; B : out POSITIVE) is begin if Some_Boolean then B := 1; end if; end P; What are the values of A and B upon completion of P? 6.2(7).1 Parameter passing mechanism. For composite types (arrays, records and tasks), passed as out parameters, when is copy-in/copy-out used instead of "call by reference"? Does the user have any control over the parameter passing mechanism employed? Type: Explicit, Erroneous. Rationale: The design of the parameter passing mechanism has a large effect upon the overall quality of programs generated by a compiler. Using copy to pass composite types may cause an application to incur an unacceptably large penalty in either execution usage or storage usage. Example: Using copy to pass a one-word record or packed array incurs a much smaller overhead than passing a large record or array. 6.2(7).2 Parameter passing conventions. How are parameters passed from calling subprogram to called subprogram? Are parameters passed via registers, on a stack, or in some special area reserved for parameters, or in some other manner? Type: Implicit. Rationale: How parameters are passed affects the execution efficiency of a program and, therefore, is a valuable piece of information for the program design process. 26 Example: The RM allows compiler implementors to select parameter passing conventions. One implementation may pass a function result back on a stack, while another may utilize a specific register. 6.3.2(4).1 pragma INLINE. Under what circumstances are subprograms expanded inline when pragma INLINE is specified? In particular, if the body of the subprogram to be placed inline is compiled in another compilation unit or subunit, will the inline process take place? Type: Explicit. Rationale: The use of pragma INLINE indicates a desire for the subprogram to be expanded inline whenever it is called. The RM, though, specifically reserves to each compiler implementation an arbitrary decision as to whether a subprogram will actually be expanded inline. Thus, the rules that govern when pragma INLINE will be honored are of concern to program designers and implementors. Example: Consider the following compilation units: procedure X is ... end X; pragma INLINE (X); with X; procedure Y is begin X; end Y; Will procedure X be placed inline in Y; 6.4(6).1 Order of evaluation of parameter associations. In what order are parameters evaluated? Type: Explicit. Rationale: Side-effects of expression evaluation may be different based on the order of evaluation chosen. Example: 27 For the function call: FUNC (F1, F2, F3); the parameters may be evaluated in any order, i.e., F1 F2 F3, F1 F3 F2, F2 F1 F3, F2 F3 F1, F3 F1 F2, F3 F2 F1. If the execution of these functions involve side-effects, the effect of execution could be affected. 6.4(6).2 Order of copy back of out and in out parameters. In what order are parameters of modes out and in out copied back at the conclusion of a subprogram call? Type: Explicit. Rationale: The order in which parameters are copied back may affect the execution behavior of a program. Example: Assume the following procedure definitions: procedure P (A : out integer; B : out integer) is begin A := -1; B := 5; end P; and, procedure Q is X : positive := 1; Y : positive := 1; begin P (INTEGER'X, INTEGER'Y); ... end Q; The CONSTRAINT_ERROR exception on the value of X may be raised before or after Y is updated. 28 Subprograms 8.6(1).1 package STANDARD. Is a single package STANDARD implied for the compilation of a distributed Ada program? Type: Explicit. Rationale: Without multiple STANDARD packages, heterogenous processors cannot be supported. Example: TBD. 9.1(6).1 Code sharing for objects of the same task type. Is the code of a task body shared among multiple occurrences of the same task type? In what cases is the task body shared? not shared? Type: Explicit. Rationale: Significant memory savings can be realized if the code of the body of a task type can be shared. However, in a debug environment, the user may desire to disable code sharing. Example: TBD. 9.2(2).1 Static allocation of tasks. Can tasks in library level packages be statically allocated? Type: Explicit. Rationale: For many programs, the number of tasks are known at compile time. These tasks are declared in library level packages. They execute as infinite loops and never terminate. In such systems, the job of the system designer is easier if tasks can be statically allocated at compile/link-time. Static allocation permits ROMable code, reduces runtime overhead, and has the advantage that the memory requirements of code and space is known at compile/link-time. 29 Example: TBD. 9.2(2).2 Task storage. How is storage for tasks allocated (stack/heap)? If task storage allocation has fixed limits, what types of storage are fixed, and what are the default values for the amount allocated? What is the minimum execution time required for task elaboration? What is the worst case time, and what factors effect this time? Type: Explicit. Rationale: TBD. Example: TBD. 9.3(1).1 Execution order. What is the algorithm that determines the execution order of the activation of tasks on monoprocessor and multiprocessor systems (if applicable)? Type: Implicit. Rationale: The efficiency of the system design may depend on the scheduler algorithm. In a monoprocessor environment, the execution of parallel tasks can be interleaved. Possible interleaving algorithms include: preemptive priority, time slice, and run until blocked. Example: Assuming that the declaration of a task object causes a task to be put on the RTE run queue, the order that it is put on the run-queue and the algorithm used affects the execution order. Tasks can go on the run-queue FIFO in the order declared which means that they will execute in the order declared. Tasks can be placed on the run-queue by priority which means that the highest priority task declared will execute first. 9.3(1).2 Execution order. 30 What is the algorithm that determines the normal execution order of parallel tasks on monoprocessor and multiprocessor systems (if applicable)? If the Ada Runtime System is on top of a host operating system, how does the execution order algorithm of Ada tasks interact with the operating system? Type: Implicit. Rationale: The efficiency of the system design may depend on the scheduler algorithm. Example: TBD. 9.4(13).1 Task termination. When the main program terminates, what happens to tasks declared in library packages? Type: Implicit. Rationale: The RM does not define whether such tasks are required to terminate. For some applications it is desirable that such tasks not terminate. For example, the main program may contain initialization code only and the library level tasks performing all the normal processing. The main program terminates when the initialization is done, leaving the library tasks to continue. Other applications may desire that all tasks terminate when the main program terminates. Example: An example of this case is when the main program performs the active processing of the application and the tasks are server tasks that are only called by the main program. When the main program terminates, the dependent tasks are no longer required. 9.5(14).1 Rendezvous optimizations. What rendezvous optimizations are available? Type: Implicit. Rationale: The efficiency of the tasking operations is a concern for many applications. Various implementations of rendezvous have been proposed and documented. Some implementations of tasking rendezvous may be more 31 efficient than others. A simplified measurement of the efficiency of a rendezvous is the number of context swaps required to complete the rendezvous. Example: Most general purpose rendezvous implementations require two context swaps; one to switch to the called task, and one at the end of the accept body to switch back to the calling task. If the compiler can recognize or be told of special conditions, then the rendezvous cost can be reduced. One such special condition is a passive server task that is executed only when called. A rendezvous call to a passive server task (or monitor task) can be optimized to execute in the context of the caller. This means that no context swaps may be required. Because the passive server task can execute in the context of the caller, it does not need its own stack or task control block. Real-time applications that use tasking should be concerned about the rendezvous implementation and the possible tasking special cases that can be optimized by the compiler and run time environment. 9.6(1).1 Delay Implementation. What is the implementation of the delay statement? What is the resolution of response to the delay value? Is the delay expiration a scheduling event? Type: Implicit. Rationale: The implementation of the delay statement is a concern to the real-time user. When a task completes its delay, it is desirable that the delay expiration be a scheduling event, and that the delayed task immediately preempt a current task of lower priority Example: TBD. 9.6(4).1 Type DURATION. What is the implementation of type DURATION? What is DURATION'SMALL? What is SYSTEM.TICK? Is there an upper limit to the duration in a delay statement? Type: Explicit. Rationale: The implementation of type DURATION will determine the resolution of the delay expression. The relationship between type DURATION and the basic clock cyle, SYSTEM.TICK, will determine the resolution of the 32 actual delay. Example: TBD. 9.6(5).1 Package CALENDAR. What is the implementation of type TIME in package CALENDAR? Type: Implicit. Rationale: TBD. Example: TBD. 9.7.1(5).1 Guard conditon evaluation. What is the order of evaluation for guard conditions in a selective wait? When is the delay alternative (if present) evaluated? When are the family indexes (if present) evaluated? Type: Implicit. Rationale: TBD. Example: TBD. 9.7.1(6).1 Selective wait alternatives. What is the algorithm to select from the open alternatives in a selective wait? Type: Implicit. Rationale: The RM states that the choice is arbitrary. However, some applications may be concerned with how arbitrary is defined. Example: 33 For some applications a FIFO choice of open alternatives is adequate. Other applications may require that if tasks of different priorities are queued on different open alternatives then the alternative that has the highest priority task waiting on it be selected. 9.7.1(8).1 Delay alternatives. What algorithm is used to select from delay alternatives of the same delay in a selective wait? Type: Implicit. Rationale: TBD. Example: TBD. 9.8(1).1 Task priorities. What is the range of subtype PRIORITY? Are task priorities implemented? What is the default priority of a task (and of the main program) if one is not explicitly given via the pragma PRIORITY? Type: Explicit. Rationale: An embedded system contains applications that have different execution requirements. Time and response critical applications must be guaranteed to run when required. Knowing whether or not priorities are implemented, the number of priority levels available, and the default priority of tasks and the main program is necessary for designing usable embedded systems. Example: For example, if a system designer is aware that a particular runtime environment supports three levels of priority (subtype PRIORITY is INTEGER range 0..2) and that the assigned default priority is the lowest priority (0) then the following conclusions may be made: Interrupt handlers should be priority 2, foreground processing should be priority 1 and background processing should be priority 0. This particular set-up exemplifies a disadvantageous situation of have a single priority level available for foreground processing. Since some foreground processes will be more time-critical than others, elaborate scheduling will be needed to meet requirements. This scheduling will increase the complexity of the designed code. 34 9.8(4).1 Task priority. Since a task is suspended until the completion of subtask activation, is it possible that a low priority activation could result in a very long suspension of a high priority task? Type: Implicit. Rationale: An embedded system, the suspension of a high priority task could prevent the response to a time critical event and degradation of the system. Example: During the execution of an Ada program, a low priority task spawns a task. While the activitation of this spawned task is occurring, a high priority task becomes ready to execute. 9.8(4).2 Multi-processor task scheduling. How sensitive is pre-emptive scheduling to distribution of tasks multi-processors? Type: Explicit. Rationale: Some computers provide more than one processor for an Ada program. Thus, tasks must be distributed among processor resources in accordance with the RM. Example: With tasks running on separate physical CPUs, it is conceivable for a medium priority task to be blocked on CPU 1 (by a higher priority task on CPU 1) while a lower priority task on CPU 2 is executing. 9.8(5).1 Scheduling order of tasks with same priority. What is the scheduling order of tasks with the same priority? What the scheduling rules for tasks without explicit priorities? Type: Implicit. Rationale: The RM explicitly declines to define the answers to these questions, however this knowledge must be known by the designers of an embedded system to ensure required system performance. 35 Example: Assume an Ada program has three tasks of the same priority. The three tasks execute delay statements such that they will all be eligible to execute at the exact same time. If the tasks don't execute in a FIFO manner, this could affect system design choices. 9.8(5).2 Rendezvous between tasks without priorities. What is the priority of a rendezvous between two tasks without explicit priorities? Type: Implicit. Rationale: The RM explicitly declines to define the answers to these questions, however this knowledge must be known by the designers of an embedded system to ensure required system performance. Example: Two tasks without explicit priority conduct a rendezvous. If the priority given to the rendezvous is higher than a task with an explicit priority, the Ada program may perform in a manner unpredictable by the program designer. 9.8(5).3 Rendezvous within multi-processor system. With two tasks in a multi-processor system rendezvous, how are task priorities among processors resolved? Which processor is the rendezvous performed on? Type: Implicit. Rationale: The RM defines the priority of a rendezvous in which at least one of the tasks engaged has an explicit priority. The RM explicitly declines to define the priority of a rendezvous between tasks without explicit priorities. The implementation of a rendezvous must be known by the designers of an embedded system to ensure required system performance. Example: Two tasks, each on different processors, conduct a rendezvous. The priority of the rendezvous is less than one task coming off the delay queue but greater than the priority of another task coming off the delay queue, the rendezvous should be conducted in accordance to the RM. In the case of a rendezvous between two tasks without explicit priorities, if the priority given to the rendezvous is higher than a task with an explicit priority, the Ada program may perform in a 36 manner unpredictable by the program designer. 9.9(4).1 Representation attributes of a task. What is the result of specifying the representation attributes STORAGE_SIZE and SIZE for a task object? Type: Explicit. Rationale: One should be able to control the amount memory used by a task. Example: To specify a task type, one might declare the type: task type CONTROLLER is entry ACQUIRE; entry RELEASE; end CONTROLLER; and then restrict the size of tasks of this type by the following statement: for CONTROLLER'SIZE use 256*BYTE; 9.10(4).1 Abort evaluation order. What is the order of evaluation of task names in an ABORT statement? Type: Implicit. Rationale: The order of evaluation is explicitly undefined by the language yet must be known by a system designer. Example: Assume there exist three tasks A, B, and C running within an Ada program. The following statement is executed: abort A,B,C; The program designer might have intended for the tasks to be aborted in a left to right order. If the implementation did not follow such an order, the designer would reorder the task identifiers in the abort statement. 9.10(8).1 Abort completion. 37 Can a task be aborted (and go to completion) while updating a variable? Type: Implicit, Incorrect Order. Rationale: The RM explicitly states the value of a variable is undefined if the task updating the variable is abnormally completed during the update. An implementation may prevent a task from being aborted while updating a variable and thus prevent a variable from being undefined. This may be extremely crucial in the case of a shared variable. Example: Two tasks both share a variable A. The first task uses A for calculations, the other task updates A periodically. If the second task is aborted during the update of A, then A becomes undefined. This raises an exception in the first task and may stop critical calculations. The system designer must be aware of this. 9.11(7).1 Shared variables. What is the implementation mechanism for shared variables? Type: Implicit, Erroneous. Rationale: If a particular task is reading or updating a shared variable between two synchronization points, other tasks must be prevented from reading or updating the shared variable. The amount of protection of shared variables without using pragma SHARED should be known. The ability of an implementation to detect if a program is erroneous as described in the Ada RM 9.11(6) should be known. Example: Two tasks A and B share a variable C. If task A is updating variable C then task B can't access variable C and must be blocked. 9.11(8).1 Shared variables. Are local copies of shared variables maintained within tasks? If so, what is the implementation mechanism for maintaining the local copy? Type: Explicit, Incorrect Order. Rationale: 38 The task with the local copy should treat all reads and writes of the shared variable as reads and writes of the local copy. If the store of the local copy into the shared variable is done before a synchronization point, the implementation mechanism must guarantee that effect is the same as the canonical order (RM 11.6(2)). Example: TBD. 9.11(11).1 pragma SHARED. What is the implementation mechanism of pragma SHARED? Type: Implicit, Incorrect Order. Rationale: This pragma should be restricted to variables declared by an object declaration and whose type is scalar or access type. Each direct reading and direct updating must be implemented as an indivisible operation. How the shared variable is implemented as a synchronization point should be described. The implementation should detect if the pragma doesn't appear before every occurrence of the name of the shared variable(other than in an address clause). Any special synchronization mechanisms should be described. Example: TBD. 9.11(11).2 Shared variables. What objects are supported with indivisible update operations? Type: Implicit, Incorrect Order. Rationale: All objects of scalar or access type should be supported with indivisible update operations when pragma SHARED is used (includes enumeration types). Exceptions to this should be explained. If there are allowed objects for which indivisible read and update operations are not yet implemented (e.g. during an interim release of a compiler) it should be documented. Indivisible read and update operations implemented for composite types should not be allowed as it is prevented by the language. Example: 39 TBD. 10.1(8).1 Main program initiation mechanism. How is the main program initiated from the external environment? Type: Explicit. Rationale: The RM states that the main program acts as if it were called by some environment task. The details of main program initiation are left to each implementation. These details can be important in the design of systems. Some representative questions are: (1) To what extent are facilities of a co-resident operating system utilized to govern execution? (2) If there is no resident operating system, does the compiler assume it has exclusive use of hardware facilities such as interrupt vectors? (3) Can multiple programs co-exist in a single target environ-ment? Example: Can a program written in Ada coexist with programs in other languages or other Ada programs? 10.1(8).2 Restrictions on main program. What restrictions are placed on the parameters and results of a main program? Type: Explicit. Rationale: The facilities provided for a main program to receive information from its external environment and to return information back affects the design of systems. This information is required to be supplied in the Appendix F documentation for an implementation. Example: The RM requires that a parameterless procedure be capable of being a main program, but other types of subprograms may be main programs also. If an implementation permits subprograms that are main programs to have parameters, what are the semantics associated with both in and out modes? If an implementation permits a function to be a main program, what is the semantic meaning given to the function result? (Typically, it is used as some sort of return code.) If parameters or function results are permitted, what data types are permissible? 40 10.2(1).1 Separate subunits and pragma INLINE. Are subroutines containing pragma INLINE actually expanded inline when the body to be expanded inline is a separate subunit? Type: Implicit. Rationale: The use of pragma INLINE indicates a desire for the subprogram to be expanded inline whenever it is called. The RM specifically reserves to each compiler implementation an arbitrary decision as to whether a subprogram will actually be expanded inline. Thus, the rules that govern when pragma INLINE will be honored are of concern. Example: Will UTIL be expanded inline in the following example? package body PACK1 is procedure UTIL is separate; procedure P is separate; end PACK1; separate (PACK1) procedure UTIL is pragma INLINE ... end UTIL; separate (PACK1) procedure P is begin UTIL; end P; 10.4(1).1 Linking library units into a program. Are unneeded elements of a program library or runtime system linked into a program? Are unneeded parts of a package body linked into a program? Type: Implicit. Rationale: Linking unneeded library units into a program results in a waste of storage space. Example: If all subprograms in a package body are linked into a program instead of just those needed, then storage space is consumed that is not necessary. The answers to these questions affects the design of application programs. 41 10.5(5).1 Elaboration order of compilation units. In what order are compilation units elaborated? Type: Explicit. Rationale: The RM does not provide a complete algorithm for the elaboration of compilation units of a program. Example: For the main prograam: with A, B; procedure X is ... A and B can be elaborated in any order, assuming there are no dependencies between them. 10.5(5).2 Elaboration prior to program execution. To what extent is elaboration accomplished prior to execution? Type: Implicit. Rationale: Code explicitly generated to accomplish elaboration generally constitutes overhead that should be avoided. Example: package PACK1 is C : constant INTEGER := 6; end PACK1; In this case there should be no overhead involved in the elaboration of the object C. 11.1(1).1 Exception representation. How are unique identifiers for exceptions created? Type: Implicit. Rationale: An exception must be uniquely represented in an executing Ada program. How this mapping from exception name to unique identifiers is done may have an impact on the speed and size of the generated code. 42 Example: Some implementations represent an exception as a pointer to a string containing the actual exception name. This is useful for debugging and error reporting. However, for embedded systems where no textual I/O is available it may be wasteful to keep the string representation of every exception name in memory. 11.1(6).1 NUMERIC_ERROR. Is the raising of NUMERIC_ERROR supported in hardware? Type: Implicit. Rationale: It would seem more efficient if overflow detection is supported through hardware since code does not have to be generated after every arithmetic operation that could cause overflow. Example: TBD. 11.1(7).1 PROGRAM_ERROR. Is PROGRAM_ERROR ever raised because of an erroneous program? Type: Explicit, Erroneous. Rationale: If PROGRAM_ERROR is raised in such circumstances the user would like to know what these circumstances are so the user can handle the exception if appropriate. Example: TBD. 11.1(7).2 PROGRAM_ERROR. Is PROGRAM_ERROR ever raised because of incorrect order dependencies? Type: Explicit, Erroneous. Rationale: If PROGRAM_ERROR is raised in such circumstances the user would like to know what these circumstances are so the user can handle the exception if appropriate. 43 11.1(9).1 Implementation-defined exceptions. What additional exceptions are provided? Type: Explicit. Rationale: Users may wish to handle these exceptions. As such, it is necessary to know what these exceptions are and under what circumstances they can be raised. Example: One Ada implementation defines an exception NON_ADA_ERROR in package system. This exception is raised when non-Ada code is imported into an Ada program, and that code then signals a condition. The user can then explicitly handle this exception in an exception handler in the Ada code. 11.2(3).1 Exception handler overhead. What is the overhead if a code sequence has an exception handler associated with it, yet no exceptions are raised during execution of that code? Type: Implicit. Rationale: Since exceptions are used to indicate "exceptional situations", exception handlers should not be executed during normal program execution. It is therefore desirable to have minimal overhead associated with entering and exiting an exception handler's scope. Example: Consider the following example: function FACTORIAL (N : POSITIVE) return FLOAT is begin if N = 1 then return 1.0; else return FLOAT(N) * FACTORIAL(N-1); end if; exception when NUMERIC_ERROR => return FLOAT'SAFE_LARGE; end FACTORIAL; If the overhead for entering the scope of an exception handler is significant, the execution time for this function might be higher than if the function had been written to explicitly check the operands of 44 the multiply before performing the multiply. If the overhead were low, the above example would execute faster than if it had been coded with explicit checks. 11.2(6).1 Non-Ada exceptions. Are "exceptions" which are raised in non Ada subprograms handled by Ada exception handlers? Can Ada exceptions raised in Ada subprograms be handled by non-Ada subprograms? Type: Implicit. Rationale: When a non-Ada subprogram is called the user must be aware of whether or not it can raise any exceptions. If it can, the user must know which exceptions it can raise, how they are raised and if they are propagated to the Ada routine that called the non-Ada code. Example: Assume a non-Ada function is called from an Ada subprogram. During the execution of the function a divide by zero is performed. If the non-Ada language does not support a mechanism for handling such an exception, the exception might be propagated as NUMERIC_ERROR to the calling Ada subprogram. 11.3(3).1 Exception raise overhead. What is the overhead associated with the execution of a raise statement? Type: Implicit. Rationale: The overhead associated with raising an exception might influence an implementation choice between using the raise or returning a status as a parameter. Example: A user might design a package to do matrix manipulations. Included in this package could be a subprogram that finds the inverse of a matrix. If raising an exception is a very high overhead operation, one might define the subprogram as follows: procedure Inverse (In_Matrix : in MATRIX; Out_Matrix : out MATRIX; Matrix_Is_Singular : out BOOLEAN); 45 But if raising an exception is not a high overhead operation, a better interface might be: Is_Singular : exception; function Inverse (In_Matrix : in MATRIX) returns MATRIX; where the function would raise the exception Is_Singular if the matrix was singular. 11.4(1).1 Exception handler overhead. What is the overhead associated with finding a handler when an exception is raised? Type: Implicit. Rationale: The overhead associated with finding a handler when an exception is raised might influence implementation choices of where handlers are placed. Example: Consider the following recursive function: Number_Too_Large : exception; function Factorial (N : POSITIVE) return FLOAT is begin if N = 1 then return 1.0; else return FLOAT(N) * Factorial(N-1); end if; exception when others => raise NumberToo_Large; end Factorial; If the overhead for finding an exception handler were large, a more efficient solution might be to only raise the exception for the expected exceptions, and not define a "when others" clause. 11.4.1(5).1 Main program termination. What happens when the execution of the main program is abandoned after an unhandled exception? Type: Explicit. Rationale: 46 A user may desire to intercept such exceptions "outside of" the Ada program. Example: On many host systems a message is written out to a standard output device. Often on an embedded system no such device exists. Declarations 11.6(5).1 Error detection, efficiency. Could use of the optimizer cause exceptions that otherwise might not occur? Type: Implicit. Rationale: Through code motion and re-ordering of expression evaluation an exception that would otherwise not occur might be raised. During debugging the code might be tested without the optimizations turned on, and then after the code was thoroughly tested the code would be recompiled with full optimizations. The user would not want new exceptions introduced at this point without some warning that this might occur. 11.6(11).1 Code optimization. How do optimizing code movement and exceptions interact to affect the results of code sequences? Type: Explicit. Rationale: Certain code movements could cause an exception to occur earlier than its textual position would indicate. If this situation can arise, the user may want to enclose statements within a block to get more control over where the exception is raised. Example: Consider the following example (cf. IG, page 11-14). since the order of operand evaluation is not defined by the language, given: begin D := 30; if A = D/(A-3) or A = B(50) then ... exception ... 47 There is no guarantee that NUMERIC_ERROR will be raised instead of CONSTRAINT_ERROR if A = 3. Either operand of the or statement can be evaluated first. Moreover, if CONSTRAINT_ERROR is raised, there is no guarantee that D = 30 in a handler for this exception, since B(50) can be evaluated before the assignment to D is performed. If the user wishes to insure that D has the value of 30 in the exception handler, a block should be placed around the assignment to D. 11.7(18).1 pragma SUPPRESS. For each check that can be suppressed, what is the effect (or possible effect) of an error arising with that check being suppressed? Type: Explicit, Erroneous. Rationale: Even though such a program is erroneous, the user may wish to know when this occurs. Example: One method used to generate random numbers is to multiply large integers to cause integer overflow. If an implementation chose always to give a result of zero in such situations, the random number generator would not work. 11.7(18).2 pragma SUPPRESS. For each check that can be suppressed, is there an overhead associated with suppressing the check? Type: Implicit. Rationale: When exceptions are suppressed the user may not want extra code added to explicitly ignore exceptions. But if the exception is handled through hardware it may not be possible to fully suppress. Example: Consider a machine that has an unmaskable interrupt associated with fixed point overflow. An Ada implementation for this machine might associate an interrupt routine for the overflow interrupt that raised NUMERIC_ERROR. In order to suppress NUMERIC_ERROR the implementation might then generate an exception handler like the following for all arithmetic operations that could cause overflow : exception when NUMERIC_ERROR => null; end; 48 11.7(20).1 pragma SUPPRESS. Under what circumstance is the SUPPRESS pragma ignored? Type: Explicit. Rationale: If it is too expensive to suppress an exception the user would wish to know why, and what exceptions this was true for. Example: The same example as above is applicable here. 12.2(2).1 Generic bodies and separate. Will generic instantiations work when the body to be instantiated is separate? Type: Explicit. Rationale: An efficient implementation of generics will provide for code body sharing even when the body is separate. Example: TBD. 12.3(5).1 Shared code for generics. Are generics implemented using shared code? Type: Implicit. Rationale: If each implementation of a generic requires its own separate instance of the generated code, a program may use more space than if the same code is reused (to the extent applicable) for each instantiation. Conversely, there may be an execution time penalty for certain types of code sharing. Can the user affect the degree of code sharing? Example: TBD. 12.3(5).2 Order of elaboration. 49 In what order are explicit generic actual paramters evaluated? Type: Implicit, Incorrect Ordering. Rationale: For each elaboration of a generic instantiation, expressions that are supplied as explicit generic actual parameters or as constituents of variable names or entry names may be evaluated in some order not defined by the RM. For expressions with side-effects, the order of evaluation may affect the results of the program. Example: TBD. Features 13.1(10).1 Expressions in representation clauses. What is the interpretation of expression that appear in representation clauses? Type: Explicit. Rationale: The RM defines that the interpretation of the expressions that appear in representation clauses is implementation dependent. These interpretations are documented in Appendix F of the RM. Example: An implementation may have a convention that distinguishes the value of an expression as an address of a storage location or as an address of machine register. 13.1(10).2 Acceptance of representation clauses. What representation clauses are accepted by an implementation? Type: Explicit. Rationale: The RM allows an implementation to limit its acceptance of representation clauses to those that can be handled simply by the underlying hardware. These limitations are documented in Appendix F of the RM. 50 Example: An implementation may not accept any representation clauses. 13.1(12).1 Packing algorithm for the pragma PACK. What is the algorithm used for minimizing the space between components of a type specified in the pragma PACK? Type: Implicit. Rationale: The RM defines packing to mean that the gaps between the storage areas allocated to consecutive components of record or array types should be minimized. Yet from one implementation to another even on the same underlying system the size of the gaps may be different. Example: Consider a pair of components that are three bits and six bits in length on a byte addressable machine. Will the second component be allocated at the fourth bit of the first byte or the first bit of the second byte? The algorithm to implement PACK determines its utility on a large number of applications. 13.1(13).1 Additional representation pragmas. What additional representation pragmas are provided by the implementation? Type: Explicit. Rationale: The RM allows an implementation to be provide additional representation pragmas which are documented in Appendix F of the RM. Example: An implementation may define a representation pragma that allows the user to select from several representations of a subprograms, such as one for recursive and one for non-recursive subprograms. 13.2(5).1 Packing impact to composite with length clauses. What impact does the length clause have on the packing algorithm of composite types? 51 Type: Explicit. Rationale: The RM specifies that a size specification for a composite type may affect the size of the gaps between the storage areas allocated to consecutive components. An implementation may allow the user to specify a size (i.e. length) which may pack the components of that type. Example: Consider an array type "A" with 200 integer components where each component may have a size of three bits. An implementation may allow the length of A to be 1600 bits, implying that each component is packed one to a byte; or A to be 800 bits, implying that two comonents are packed to a byte; or even 600 bits, implying no storage space between components. 13.2(8).1 Storage reserved for a collection size. What is considered to be part of the storage reserved for a collection of an access type? Type: Implicit. Rationale: Contents of the storage reserved for a collection of an access type is implementation dependent. The control afforded by the length clause is relative to the implementation conventions. To accurately predict the storage requirements for a collection, the user must know the manner allocation used for access collections. Example: The allocation scheme used by an implementation may use internal tables and links which are allocated from the storage space for the access collection. The formulas for calculating these must be known for accurate prediction of collection sizes. 13.2(10).1 Storage reserved for a task activation. What is considered to be part of the storage reserved for the activation of a task? Type: Implicit. Rationale: 52 The contents of the storage reserved for an activation of a task is implementation dependent. The control afforded by the length clause is relative to the implementation conventions. To accurately predict the storage requirements for an activation of a task, the user must know the manner of allocation used for task activations. Example: The task management scheme of an implementation uses internal tables and links (sometimes called task control blocks) which may be included in the storage space for the activation of a task. The formulas for calculating these must be known for accurate prediction of task activation sizes. 13.3(1).1 Enumeration representation expressions. What are the limitations on expressions that appear in enumeration representation clauses? Type: Implicit. Rationale: The RM defines that the interpretation of the expressions that appear in representation clauses is implementation dependent. These interpretations are documented in Appendix F of the RM. Example: An implementation may have a convention that only allows unsigned integers to represent enumeration literals. 13.4(4).1 Limitations on record alignments. What are the restrictions on the allowable alignments for record representation clauses? Type: Explicit. Rationale: The RM defines that an implementation is permited to place restrictions on the allowable alignments for record representation clauses. These restrictions are documented in Appendix F of the RM. Example: Due to hardware restrictions an implementation may require that all record representation clause have an alignment that places them on word boundaries. 53 13.4(5).1 Ordering of bits in record representations. What is the ordering of bits of storage units in component clauses within record representation clauses? Type: Explicit. Rationale: The RM defines that the ordering of bits in storage units is machine dependent. The ordering of bits will affect the range values used in component clauses within record representation clauses. Example: On some computer systems the most significant bit is the zeroth bit while on other computer systems the least significant bit is the zeroth bit. 13.4(5).2 Overlapping storage boundaries in records. Is a component allowed to overlap a storage boundary within record representation clauses? Type: Explicit. Rationale: The RM permits an implementation to define whether and how a component of a record is allowed to overlap a storage boundary. Permitting a component to overlap a storage boundary will supporting tighter packing of components in the storage layout of a record. Example: Addressing constraints of some computer systems may force implementations to prohibit boundary crossings. 13.4(6).1 Storage layout for record types. Where does an implementation place a record component which has no component clause in a record representation clause? Type: Explicit. Rationale: If no component clause is given for a component, the choice of the storage place for the component is left to the implementation. The implementation may unintentionally place a component in a gap that the user had left open for logical reasons. 54 Example: One implementation may place all components without component clauses following the placement of the last user placed component, while another implementation may attempt to place components in unused gaps. 13.4(8).1 Names of implementation-dependent components. What are the conventions used for any implementation-dependent components generated in records? Type: Explicit. Rationale: An implementation may generate names for implementation-dependent components that are added to a record. To select storage places for these implementation-dependent components in component clauses, it is necessary to know the naming conventions for these components. Example: An implementation may add a implementation-dependent component to hold the offset of another component within the record layout. 13.5(3).1 Expressions in address clauses. What is the interpretation of expressions that appear in address clauses? Type: Explicit. Rationale: The RM defines that the interpretation of the expressions that appear in address clauses is implementation dependent. These interpretations are documented in Appendix F of the RM. Example: An implementation may have a convention that distinguishes the value of an expression as an address of a storage location or as an address of machine register. 13.5(8).1 Overlays. What is the effect of using address clauses for overlaying objects, program units, or interrupts? 55 Type: Explicit, Erroneous. Rationale: The RM defines that any program using address clauses to achieve the overlaying of objects, program units, or interrupts is erroneous. An implementation may provide some detection of this erroneous situation, either at compile-time or at run-time. Example: An error message at compile-time would be very useful in drawing attention to this hard-to-find error. 13.5.1(2).1 Direct execution of interrupt entry calls. Under what conditions, if any, will an implementation enable the hardware to directly execute the accept statements associated with an interrupt entry call? Type: Implicit. Rationale: The RM defines that an interrupt entry call acts an an entry call issued by a hardware task whose priority is higher than the priority of the main program and any user-defined task. This enables an implementation to implement the interrupt entry call having the hardware directly execute the appropriate accept statements, which is absolutely necessary for many real-time applications. Example: One condition that is required on many implementation for hardware direct execution of interrupt entry calls is that there is no other calls to the entry from the application software. An implementation may require a special pragma that specifies that only hardware interrupts will cause interrupt entry calls. 13.5.1(3).1 Restrictions on terminate alternative. What further requirements are imposed by an implementation for selection of the terminate alternative that may appear in the same select statement with an accept alternate for an interrupt entry? Type: Explicit. Rationale: Further requirements may be necessary to prevent the premature selection of the terminate alternative. 56 Example: Selecting the terminate alternative may complete the task which contains the only accept statements which can handle the interrupt entry calls, leaving the hardware unserviced. This would be fatal to most applications. 13.7(2).1 Definition of package SYSTEM. What is the definition of package System? Type: Implicit. Rationale: This is information that is basic for many applications. Example: The information is critical to developing very target dependent code, such as I/O device drivers or operating systems. 13.7.2(3).1 Meaning of the ADDRESS representation attribute. What is the meaning of the ADDRESS representation attribute? Type: Implicit. Rationale: For systems programming applications it is important to know the meaning for the ADDRESS attribute for various objects. Example: Consider the object of an access variable X. What is the value of X.all'ADDRESS when allocated objects may include additional storage for internal storage links? If the storage links are placed at the beginning of the allocated object, the ADDRESS attribute may point to the storage link as opposed to the actual value of the allocated object. 13.7.2(5).1 Definition of other representation attributes. What is the actual definition of the attributes: POSITION, FIRST_BIT, LAST_BIT and STORAGE_SIZE? Type: Implicit. 57 Rationale: The meaning for these attributes are unchanged from one implementation to another. But the actual values of these attributes may change from one implementation to another. Use of these attributes should be isolated to implementation or machine dependent program units. Example: For the same record type R and the same component C of R, the value of R.C'POSITION may be different from one implementation to another. 13.8(4).1 Machine code inserts. Is the package MACHINE_CODE supported and how are the machine features supported? Type: Explicit. Rationale: This package is one way for expressing machine level operations that are not otherwise expressable in Ada language; the other way is an interface to an assembly language subprogram. Example: Example machine level operations are those which change the machine state, such as disabling interrupts or manipulating machine registers. An implementation may require the pragma INLINE for any machine code subprogram or may exclude parameter passing. 13.9(4).1 Interface to other languages. Is the pragma INTERFACE supported and how is this interface supported? Type: Explicit. Rationale: This is critical feature for reusing existing software in other languages. While the RM only describes this feature with respect to the calling conventions to non-Ada software, an implementation will need to consider the implications of interfacing to these routines on other features of the Ada language. Example: An implementation will need to consider how an error that occurs when the non-Ada subprogram is executing is handled by the calling Ada program. 58 13.10.1(6).1 Accessing unchecked deallocated objects. What is the effect of accessing an unchecked deallocated object through a redundant designator? Type: Implicit. Rationale: The RM states that an deallocated object which is accessed through a redundant designator is erroneous. While the effect of such an access is not defined by the language, an implementation will choose some action to be performed to handle this problem at runtime. Example: An implementation may choose to provide an elaborate runtime check to insure there is no other references when the FREE procedure is invoked. That is, when X and Y designate the same object and FREE(X) is executed, the runtime may supply a special value to Y, which indicates the object is no longer available. If Y is not changed, the next access through Y would be capable of raising an exception. 13.10.2(2).1 Restrictions on unchecked type conversions. What restrictions, if any, are imposed on unchecked type conversions by the implementation? Type: Explicit. Rationale: The RM permits an implementation to place restrictions on unchecked type conversions. Example: An implementation may not permit unchecked type conversions, altogether, or it may limit it to types whose sizes are the same. 14.1(1).1 FORM parameter. What system-dependent characteristics defined in the FORM parameter can affect input-output operations? Type: Explicit. Rationale: The effects of system-dependent characteristics defined in the FORM parameter may potentially affect input-output operations. Dependence upon these effects may potentially affect the performance, 59 reusability, and transportability of a program unit. Example: A program may depend upon the FORM parameter to control shared access to an external file. This program may not be reusable/transportable under implementations that do not support the explicit sharing/nonsharing of files. 14.1(7).1 External file status. What is the disposition of the external file associated with a non-closed file following completion of the main program? Type: Explicit. Rationale: The disposition of the external file associated with a file that is not closed prior to completion of the main program in which it was opened may potentially affect the execution of subsequent programs. Dependence upon a specific disposition can potentially affect the transportability of a group of programs. Example: A program that depends upon the implementation to close all opened files upon program completion may result in external files being unavailable to subsequent programs under implementations that do not close opened files and leave the associated external files as unavailable, e.g, currently in use. 14.1(7).2 Input-output of access type objects. What is the effect of input-output for access type objects? Type: Explicit. Rationale: The facility to input and output access type objects may potentially affect the performance, reusability, and transportability of a program unit. Example: A program that depends upon a facility to output and then subsequently input access type objects may not be transportable to an implementation that raises the Use_Error exception when an access type object is output. 60 14.1(11).1 Implementation-defined exceptions. What implementation-defined exceptions are available? Type: Explicit. Rationale: The availability and use of implementation-defined exceptions may potentially affect the performance, reusability, and transportability of a program unit. Example: A program unit that depends upon an implementation-defined exception for input-output processing may not be reusable when combined with a program unit that is executed under an implementation that does not support the exception. 14.1(13).1 Sharing external files. What are the effects of associating more than one file with a single external file? Type: Explicit. Rationale: The effects of sharing an external file among more than one file can affect input-output operations. Dependence upon these effects may potentially affect the reusability, and transportability of a program unit. Example: A program that depends upon the facility to share an external file among concurrently executing tasks may not be transportable to an implementation where an external file may only be associated with a single file. In such implementations, once an association is made, subsequent attempts to associate the external file with another file may raise an exception. 14.2.1(3).1 Size of a direct access file. What is the maximum size of a direct access file? Type: Explicit. Rationale: 61 Dependance upon a specific maximum size for a direct access file for input and output processing may potentially affect the reusability, and transportability of a program unit. Example: A program unit that depends upon the maximum size of a direct access file equal or greater than the value of Integer'LAST may not be reusable under an implementation that supports a smaller value. The following code fragment illustrates the dependency: function Random return Positive; ... Set_Index (File, Random); -- Constraint_Error may be raised. 14.2.1(3).2 Temporary file status. What is the status of temporary files after completion of a main program? Type: Implicit. Rationale: The status of temporary files following the completion of the main program may potentially affect the performance of subsequent program execution. The RM states that temporary files are not accessible following completion of the main program but does not require the deletion of the associated external files (cf. 14.1(7)). Example: A program that makes excessive use of temporary files without explicitly deleting them prior to completion may disrupt execution of a subsequent program unless the implementation ceases the existence of the external files upon program completion. 14.2.1(3).3 Null FORM argument string. What is the effect of a null Form argument string? Type: Implicit. Rationale: The use of a null FORM argument string may potentially affect the reusability and transportability of a program unit when a file is Created or Opened. 62 Example: A program that depends upon the implementation to provide default options for external files may not be transportable or reusable under implementations that require a non-null FORM argument string when Creating or Opening a file. In these implementations the exception Use_Error is raised. 14.2.1(3).4 Existing external files. What is the effect of a Create when the specified external file exists? Type: Implicit. Rationale: The use of the effect of attempting to Create a file that is associated with an existing external file may potentially affect the performance, reusability, and transportability of a program unit. An implementation may raise the exception Use_Error, or create a new version of the external file, or overwrite the existing external file. Example: A program that depends upon Create to overwrite an existing external file may degrade system performance under an implementation that creates a new version of the external file. 14.2.1(9).1 Temporary file status. What is the status of a temporary file after it has been closed? Type: Implicit. Rationale: The status of the external file associated with a temporary file that has been closed may potentially affect the performance, reusability and transportability of a program unit. Example: A program unit that depends upon the facility to access the external file associated with a temporary file after it has been closed, may not be reusable or transportable to an implementation that does not support the facility. The following code fragment illustrates the dependency: Create (File, OUT_MODE, ""); File_name := Name (File); -- Assumes that Name will return the name of the 63 -- external file associated with the temporary file. ... Close (File); Open (File, IN_MODE, File_Name); -- Name_Error may be raised if external file -- ceased to exist as a result of closing the -- temporary file. 14.2.1(13).1 Deletion of shared external files. What is the effect of attempting to delete a file that is associated with a shared external file? Type: Implicit. Rationale: The effect of attempting to delete a file that is associated with an external file that is currently associated with another file may potentially affect the reusability, and transportability of a program unit. Example: A program that depends upon a specific exception to be raised as a result of deleting a shared external file may not be transportable to an implementation that does not raise the same exception. The following code fragment illustrates the dependency: File_Name := External_Name; Open (File_1, IN_FILE, File_Name); Open (File_2, IN_FILE, File_Name); -- Exception may be raised if sharing an external file -- is not supported. ... Delete (File_1); -- Exception may be raised if File_2 has not been closed. ... Read (File_2, Item); -- Exception may be raised if Delete was performed. 14.2.1(21).1 Name of an temporary external file. What is the effect of calling the function Name with a temporary file? Type: Implicit. Rationale: The use of the effect of attempting to obtain the name of the external file associated with a temporary file may potentially affect the reusability, and transportability of a program unit. 64 Example: A program that depends upon the function Name to obtain the [ame of the external file associated with a temporary file may not be reusable or transportable to an implementation that does not support the facility. 14.2.2(4).1 Uninterpretable elements. What is the effect of reading an element that cannot be interpreted as a value of the expected type? Type: Explicit. Rationale: The use of the effect of reading an element that cannot be interpreted as a value of the expected type may potentially affect the reusability and transportability of a program unit. Example: A program unit that depends upon the exception Data_Error to be raised when reading an element that cannot be interpreted as a value of the expected type may not be reusable when combined with a program unit that is executed under an implementation that does not raise the exception. The following code fragment illustrates the dependency: declare function Read_Data return Element_Type is ... begin ... Read (File, Item); -- Data_Error is assumed to be raised -- for uninterpretable value for Item. return Item; end Read_Data; begin ... Item := Read_Data; -- Data validity dependent on Data_Error. exception when Data_Error => -- Invalid data dependency. end; 14.3(7).1 Terminators. What are the effects of end of a line, page, and file terminators on the input and output of control characters? 65 Type: Explicit. Rationale: The use of the effects of the representation of line, page, and file terminators may potentially affect the reusability and transportability of a program unit. Example: A program unit that depends upon a specific representation for line, page, and file terminators may not be reusable when combined with a program unit that is executed under an implementation that does not support this representation. 14.3.4(50).1 Count'LAST. What are the effects on input and output operations of exceeding Count'LAST? Type: Implicit. Rationale: The use of the effect of exceeding Count'LAST in input and output operations may potentially affect the performance, reusability and transportability of a program unit. Example: A program unit that depends upon the facility to exceed Count'LAST on input or output may not be reusable when combined with a program unit that is executed under an implementation that does not support the facility. 14.3.4(8).1 Waiting for page terminators. What is the effect of reading a line terminator from an interactive device using Get_Line and Skip_Line? Type: Implicit. Rationale: The use of the effect of reading a line terminator from an interactive device may potentially affect the reusability and transportability of a program unit. An implementation may choose either to wait for a subsequent page terminator or to continue when the external file represents an interactive device and does not contain page terminators. 66 Example: A program unit that depends upon Get_Line and Skip_Line returning as soon as a line terminator is read for an external file that represents an interactive device may not be transportable under an implementation that always checks for the presence of a page terminator following the line terminator. In such an implementation, additional input must be read before Get_Line and Skip_Line can return. 14.3.6(1).1 Buffering file input and output. What is the effect of file buffering on text input and output operations? Type: Implicit. Rationale: The use of the effect of file buffering may potentially affect the reusability and transportability of a program unit. Implementations may buffer text so that the result of an input or output operation may be delayed. Example: A program unit that depends upon the immediate result of an output operation may not be reusable under an implementation where the operation is delayed pending the next input or output operation. The following code fragment illustrates the dependency: ... Put (Control_Console, "Shutdown Nuclear Reactor NOW! "); -- Dependency on non-buffered input so that -- text is displayed in a timely manner. delay Shutdown_Period; if Shutdown_Successful then Put_Line (Control_Console, " -- Shutdown completed"); else raise Insurance_Liability; end if; 14.3.6(13).1 End of line and end of string. What is the effect of reading a line when the end of string coincides with the end of line? Type: Implicit. Rationale: 67 The use of the effect of reading a line where the end of string coincides with the end of line may potentially affect the reusability and transportability of a program unit. An implementation may or may not call Skip_Line under these conditions. Example: A program unit that depends upon the effect of Get_Line calling Skip_Line when the end of line coincides with the end of string may not be transportable to an implementation that does not call Skip_Line under the same conditions. The following code fragment illustrates the dependency: TEXT_IO.Set_Line_Length (Text_File, 0); ... for Next_String in Text_Array'RANGE loop TEXT_IO.Put_Line (Text_File, Text_Array(Next_String)); end loop; ... for Next_String in Text_Array'RANGE loop TEXT_IO.Get_Line (Text_File, Text_Array(Next_String)); -- Dependency on Get_Line calling Skip_Line -- if all of the above output strings are -- to be input. end loop; An implementation that elects not to call Skip_Line when the end of string is reached causes the latter code fragment to input strings only on every other Get_Line, because a Get_Line is use to process each line terminator. 14.3.9(7).1 Representation of non-graphic characters. What are the effects of inputting a non-graphic character? Type: Implicit. Rationale: The use of the effects of reading a non-graphic character may potentially affect the reusability and transportability of a program unit. The representation of non-graphic characters when Enumeration_IO is instantiated for the type Character may vary. Furthermore, a non-graphic character that has been output using Put may raise the exception Data_Error when input using Get. Example: A program unit that depends upon a specific representation of a non-graphic character may not be reusable when combined with a program unit that is executed under an implementation that does not support the same representation. The following code fragment illustrates the dependency: 68 with TEXT_IO; use TEXT_IO; function Is_Null (File : File_Type) return Boolean is Item : Character; Char_IO is new ENUMERATION_IO (Character); begin Char_IO.Get (File, Item); -- Data_Error may occur in an implementation where the -- the function is reused does not support the input -- of non-graphic characters. return Item = ASCII.NUL; end Is_Null; with Is_Null; ... Enum_IO is new ENUMERATION_IO (Character); ... Enum_IO.Create (Enum_File, OUT_FILE, "Null_File"); Enum_IO.Put (ASCII.NUL); -- Output of the null character does not guarantee -- that it can be successfully read by a different -- implementation. Enum_IO.Close (Enum_File); Enum_IO.Open (Enum_File, IN_FILE); Null_File := Is_Null (Enum_File); ... A(18).1 Image of non-graphic characters. What is the IMAGE of a non-graphic character? Type: Implicit. Rationale: The RM does not define the IMAGE of non-graphic characters; this is left to the implementation. Example: The RM defines the list of graphic characters in Section 2.1 on the Character Set. All other characters are non-graphic characters. Note: Several of the other predefined attributes are implementation dependent in an absolute sense; but they are not in a relative sense. For example, P'POSITION may be positive or negative depending on an implementation; but adding its value to the starting address of the enclosing record object will always yield the address of the component P regardless of the sign of the POSITION value. Should these be added to the list of implementation dependencies? The others include: ADDRESS, FIRST_BIT, LAST_BIT, MACHINE_EMAX, MACHINE_EMIN, MACHINE_MANTISSA, MACHINE_RADIX, STORAGE_SIZE, and STORAGE_SIZE. 69 B(4).1 pragma INLINE. Under what circumstances are subprograms, with pragma INLINE, not expanded inline? Conversely, under what circumstances are subprograms, without pragma INLINE, expanded inline? Type: Explicit. Rationale: The RM does not require that an implementation must expand the subprogram call inline. An implementation is free to follow or ignore the recommendation of the pragma. In fact the absence of the pragma does not ensure against inline expansion. Example: TBD. B(4).2 pragma INTERFACE. What programming languages (including various versions) are supported by the pragma INTERFACE? Type: Explicit. Rationale: The RM allows an implementation to interface Ada programs to non-Ada subprograms through this pragma but it does not define which languages those may be. That is left up to the implementation. Example: TBD. B(4).3 pragma INTERFACE. What restrictions does the implementation place on the pragma INTERFACE? Type: Explicit. Rationale: The RM does not require that all implementation provide this pragma. An implementation may place restrictions on the allowable forms and places of parameters and calls. Example: 70 An implementation may require that all such calls to non-Ada programs through the use of the pragma INTERFACE be made only at the top level of the application, such as a library unit or the main subprogram. B(8).1 pragma OPTIMIZE. What exactly is the effect of the pragma OPTIMIZE or , conversely, the effect of not using the pragma at all? Type: Explicit. Rationale: The RM is not specific about the semantics of this pragma. It only says that TIME or SPACE will be the primary optimization criterion. Furthermore the lack of this pragma may produce still another criterion for optimization. Example: For each feature of the language or combination of features there may be several "best" transformations, some that are space efficient while others that are time efficient. This could result in the unusual situation where forcing the compiler to select TIME over SPACE may result in a less efficient overall program. Not specifying the pragma may result in yet another transformational strategy which could combine the some of both TIME or SPACE efficient optimizations. B(9).1 pragma PACK. What is the effect of the pragma PACK on the type of the Ada program? Type: Explicit. Rationale: The RM only requires that this pragma specify that storage minimization should be the main criterion when selecting the representation of a record or array type. The specific details are left up to an implementation. B(14).1 pragma SUPPRESS. What exactly is the effect of the pragma SUPPRESS? Type: Explicit. Rationale: 71 The presence of a SUPPRESS pragma gives permission to an implementation to omit certain runtime checks. The pragma does not issue an order to suppress the checks; therefore an implementation can choose not to suppress the checks. Example: An implementation may choose not to suppress some checks despite the presence of the pragma when the checks are implemented by the underlying hardware. It would either be impossible to suppress or extremely inefficient to do so. C(6).1 INTEGER representation. What is the representation of the predefined type INTEGER? Type: Implicit. Rationale: An implementation is free to choose the range of values for the predefined type INTEGER. Example: An implementation usually chooses the range of the normal integer representation for a machine as the range for the predefined INTEGER type. For a 16-bit machine this may be the range of 16-bit signed integers. In this instance, the following code fragment is potentially nonreusable depending upon the time of day it is executed: use CALENDAR; Integer_Seconds := INTEGER (Seconds(Clock)); -- NUMERIC_ERROR may be raised. C(7).1 SHORT_INTEGER and LONG_INTEGER representations. What is the representation of the predefined type SHORT_INTEGER and LONG_INTEGER? Type: Implicit. Rationale: An implementation may provide additional predefined integer types. Example: An implementation usually chooses the range of the short integer representation for a machine as the range for the predefined SHORT_INTEGER type and the range of the double length integer representation for a machine as the range for the predefined 72 LONG_INTEGER type. For a 16-bit machine this may be the range of 8-bit signed integers for SHORT_INTEGER and for LONG_INTEGER. C(9).1 FLOAT representation. What is the representation of the predefined type FLOAT? Type: Implicit. Rationale: An implementation is free to choose the range and accuracy of values for the predefined type FLOAT. Example: An implementation usually chooses the range and accuracy of the normal floating point representation for a machine as the range for the predefined FLOAT type. For a 32-bit machine this may be the range of 32-bit signed floating point representation. C(10).1 SHORT_FLOAT and LONG_FLOAT representations. What is the representation of the predefined type SHORT_FLOAT and LONG_FLOAT? Type: Implicit. Rationale: An implementation may provide additional predefined floating point types. Example: An implementation usually chooses the range and accuracy of the short floating point representation for a machine as the range for the predefined SHORT_FLOAT type and the range and accuracy of the double length floating point representation for a machine as the range for the predefined LONG_FLOAT type. For a 32-bit machine this may be the range and accuracy of 16-bit signed floating point representation for SHORT_FLOAT and the range and accuracy of 64-bit signed floating point representation for LONG_FLOAT. C(19).1 DURATION representation. What is the representation of the predefined type DURATION? Type: Implicit. 73 Rationale: An implementation is free to choose the range and accuracy of values for the predefined type DURATION, within the restrictions that it must represent at least 86400 seconds and that DURATION'SMALL must not be greater than 20 milliseconds. Example: TBD. 74 E Comments This catalogue is an evolving document. Recipients, particularly ARTEWG advisory members, are invited to contribute to this evolution by commenting on old issues, submitting new issues, or completing the evaluation form to review this catalogue. To expedite a timely review, it is not necessary to evaluate all dependencies. Furthermore, separate evaluation forms for one or more dependencies may be submitted individually at the convenience of the reviewer. We would appreciate comments being sent via one of the three forms described later. These forms have been prepared to facilitate both electronic and manual processing. Therefore, the explanatory text accompanying the forms should be read carefully in order to expedite their processing. Completed forms may be returned to the ARTEWG either by electronic mail to ARTSUPPORT@ADA20.ISI.EDU or by U.S. Mail to the following address: Mr. Michael Kamrad SIGAda ARTEWG Chairperson Honeywell Research Center MS 65-2100 3660 Marshal St., NE Minneapolis, MN 55418 For comments sent via U.S. Mail, it will assist us if you are able to send them on a 5 1/4 inch double-sided, double-density MS-DOS format diskette -- but even if you can manage this, please also send a paper copy, in case of problems with reading the diskette. E.1 Old Issues If you wish to comment on an existing Ada runtime implementation dependency in this catalogue, please use the "old issues" form described below. An electronic copy of the form is available in the file CID-OLD-ISSUE.FORM on the Arpanet node ADA20.ISI.EDU. All issues are sorted and processed mechanically in order to simplify their analysis and to coordinate them with other implementation dependencies. To aid this process, you are kindly requested to use the following format: !section ... !source ... !comment ... The "!section" line should include the chapter, section (sub-section), and the paragraph number (enclosed in parenthesis) of the Ada runtime implementation dependency from this catalogue that you wish to comment on. 75 The "!source" line should include your name, and the date in the form "yy-mm-dd". The "!comment" section should then describe the comment (with multiple lines if necessary). A complete example is shown below: !section B(14).1 !source Kamrad, M. 86-07-07 !comment The presence of a SUPPRESS pragma gives permission to an implementation to omit certain runtime checks. The pragma does not issue an order to suppress the checks_; therefore an implementation can choose not to suppress the checks. Comments may range from simple typographical or wording changes to complete modifications or additions to existing question, rationale, or example sections. By refining the existing issues, future releases of this catalogue will more accurately reflect the needs and concerns of the Ada community. To assist in the creation of comments, two blank comment forms are shown on the following page. 76 !section !source !comment -------------------------------------------------------------------- !section !source comment 77 E.2 New Issues If you wish to add a new Ada runtime implementation dependency to this catalogue, please use the "new issues" form described below. An electronic copy of the form is available in the file CID-NEW-ISSUE.FORM on the Arpanet node ADA20.ISI.EDU. All issues are sorted and processed mechanically in order to simplify their analysis and to coordinate them with other implementation dependencies. To aid this process, you are kindly requested to use the following format: !section ... !source ... !topic ... !question ... !type ... !rationale ... !example ... The "!section" line should include the chapter, section (sub-section), and the paragraph number (enclosed in parenthesis) of the Ada RM location from which this implementation dependency was derived. The "!source" line should include your name, and the date in the form "yy-mm-dd". The "!topic" line should contain a short name for (or description of) the identified dependency. The "!question" section should then describe the dependency by multiple lines. Note that the particular dependency should be written as a question whose answer would identify the implementation approach used by a particular Ada language translator system. The "!type" section should identify the type of the issue. Use "explicit" if the issue is explicitly identified in the Ada RM, "implicit" if it is derived, "erroneous" if its use would result in an erroneous Ada program, and "incorrect ordering" if its use would constitute an incorrect ordering error as defined in the Ada RM. The "!rationale" section should justify the Ada runtime implementation dependency. The "!example" section should contain a brief Ada example (or textual description of a situation) in which the issue would surface. 78 A complete example is shown below: !section 9.7.1(6).1 !source Pratt, K. 86-10-14 !topic Selective wait alternatives. !question What is the algorithm to select from the open alternatives in a selective wait? !type Implicit. !rationale The RM states that the choice is arbitrary. However, some applications may be concerned with how arbitrary is defined. !example For some applications a FIFO choice of open alternatives is adequate. Other applications may require that if tasks of different priorities are queued on different open alternatives then the alternative that has the highest priority task waiting on it be selected. Because issues are sorted and processed mechanically, new issues may be submitted without fear of duplication. Each new issue will be analyzed by the ARTEWG and its relevancy to existing issues will be determined. After refining the rationale and example (if necessary), the issue will be included in future releases of this catalogue. To assist in preparing new issues, a sample form is shown on the following page. 79 !section !source !topic !question !type !rationale !example 80 E.3 Evaluations If you wish to evaluate this catalogue (rather than comment specifically on each issue), you should fill out the following evaluation form. An electronic copy of the form is available in the file CID-REVIEW.FORM on the Arpanet node ADA20.ISI.EDU. For each dependency, the reviewer is requested to respond to three questions pertaining to its validity, future action required, and the significance of the dependency. The validity question may be answered in one of the three following ways: V - The dependency is a valid implementation dependency. N - The dependency is not a valid implementation dependency. U - The dependency is not clear and it is uncertain whether it is a valid dependency. The future action question may be answered in one of the three following ways: M - The dependency should be maintained because it is useful in evaluating Ada environments. R - The dependency should be removed because it is not useful in evaluating Ada environments. E - The dependency requires further explanation and rationale to determine its utility in evaluating Ada environments. The significance question is subdivided into two categories relating to the performance and reusability of Ada application code. The first category, performance, may be answered in one of the two following ways: L - The use of this dependency is likely to have a significant effect on improving performance. U - The use of this dependency is unlikely to have a significant effect on improving performance. The second category, reusability, may be answered in one of the two following ways: L - The use of this dependency is likely to have a significant effect on compromising reusability or transportability. U - The use of this dependency is unlikely to have a significant effect on compromising reusability or transportability. 81 |----------------------------------------------------------------| | Runtime | | | Significance | | Dependency | Validity | Action |-------------------------| | | | | Efficiency| Reusability | |--------------|-----------|-----------|-----------|-------------| | Identifier | V | N | U | M | R | F | L | U | L | U | |==============|===|===|===|===|===|===|=====|=====|======|======| | 1.6(7).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 1.6(9).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 3.2.1(15).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 3.2.1(17).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 3.6(10).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 3.6.1(11).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 3.7.2(13).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 3.9(4).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 3.9(5).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 3.9(6).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 4.1.1(4).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 4.1.2(4).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 4.1.4(4).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 4.3.3(3).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 4.3.2(10).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 4.3.2(11).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 4.5(5).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 4.5(7).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 4.5.7(7).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 4.5.7(10).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 4.6(7).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 4.6(7).2 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| 82 |----------------------------------------------------------------| | Runtime | | | Significance | | Dependency | Validity | Action |-------------------------| | | | | Efficiency| Reusability | |--------------|-----------|-----------|-----------|-------------| | Identifier | V | N | U | M | R | F | L | U | L | U | |==============|===|===|===|===|===|===|=====|=====|======|======| | 4.8(7).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 4.9(12).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 4.10(5).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 5.1(5).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 5.2(3).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 5.2(3).2 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 5.4(1).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 5.6(4).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 6.1(10).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 6.2(5).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 6.2(7).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 6.2(7).2 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 6.3.2(4).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 6.4(6).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 6.4(6).2 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 8.6(1).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 9.1(6).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 9.2(2).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 9.2(2).2 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 9.3(1).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 9.3(1).2 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 9.4(13).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| 83 |----------------------------------------------------------------| | Runtime | | | Significance | | Dependency | Validity | Action |-------------------------| | | | | Efficiency| Reusability | |--------------|-----------|-----------|-----------|-------------| | Identifier | V | N | U | M | R | F | L | U | L | U | |==============|===|===|===|===|===|===|=====|=====|======|======| | 9.5(14).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 9.6(1).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 9.6(4).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 9.6(5).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 9.7.1(5).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 9.7.1(6).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 9.7.1(8).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 9.8(1).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 9.8(4).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 9.8(4).2 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 9.8(5).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 9.8(5).2 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 9.8(5).3 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 9.9(4).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 9.10(4).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 9.10(8).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 9.11(7).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 9.11(8).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 9.11(11).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 9.11(11).2 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 10.1(8).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 10.2(1).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| 84 |----------------------------------------------------------------| | Runtime | | | Significance | | Dependency | Validity | Action |-------------------------| | | | | Efficiency| Reusability | |--------------|-----------|-----------|-----------|-------------| | Identifier | V | N | U | M | R | F | L | U | L | U | |==============|===|===|===|===|===|===|=====|=====|======|======| | 10.4(1).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 10.5(5).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 10.5(5).2 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 11.1(1).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 11.1(6).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 11.1(7).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 11.1(7).2 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 11.1(9).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 11.2(3).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 11.2(6).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 11.3(3).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 11.4(1).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 11.4.1(5).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 11.4.1(20).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 11.6(5).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 11.6(11).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 11.7(18).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 11.7(18).2 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 11.7(20).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 12.2(2).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 12.3(5).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 12.3(5).2 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| 85 |----------------------------------------------------------------| | Runtime | | | Significance | | Dependency | Validity | Action |-------------------------| | | | | Efficiency| Reusability | |--------------|-----------|-----------|-----------|-------------| | Identifier | V | N | U | M | R | F | L | U | L | U | |==============|===|===|===|===|===|===|=====|=====|======|======| | 13.1(10).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 13.1(10).2 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 13.1(12).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 13.1(13).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 13.2(5).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 13.2(8).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 13.2(10).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 13.3(1).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 13.4(4).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 13.4(5).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 13.4(5).2 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 13.4(6).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 13.4(8).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 13.5(3).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 13.5(8).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 13.5.1(2).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 13.5.1(3).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 13.5.1(6).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 13.7.2(3).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 13.7.2(5).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 13.7.2(8).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 13.8(4-6).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| 86 |----------------------------------------------------------------| | Runtime | | | Significance | | Dependency | Validity | Action |-------------------------| | | | | Efficiency| Reusability | |--------------|-----------|-----------|-----------|-------------| | Identifier | V | N | U | M | R | F | L | U | L | U | |==============|===|===|===|===|===|===|=====|=====|======|======| | 13.9(4).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 13.10.1(6).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 13.10.2(2).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 14.1(1).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 14.1(7).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 14.1(7).2 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 14.1(11).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 14.1(13).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 14.2.1(3).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 14.2.1(3).2 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 14.2.1(3).3 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 14.2.1(3).4 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 14.2.1(9).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| |14.2.1(13).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| |14.2.1(21).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 14.2.2(4).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 14.2.4(4).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 14.3(7).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 14.3.4(50).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 14.3.4(8).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 14.3.5(13).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 14.3.6(1).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| 87 |----------------------------------------------------------------| | Runtime | | | Significance | | Dependency | Validity | Action |-------------------------| | | | | Efficiency| Reusability | |--------------|-----------|-----------|-----------|-------------| | Identifier | V | N | U | M | R | F | L | U | L | U | |==============|===|===|===|===|===|===|=====|=====|======|======| | 14.3.6(7).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 14.3.6(13).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | 14.3.9(7).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | A(18).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | B(4).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | B(4).2 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | B(4).3 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | B(8).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | B(9).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | B(14).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | C(6).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | C(7).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | C(9).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | C(10).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| | C(19).1 | | | | | | | | | | | |--------------|---|---|---|---|---|---|-----|-----|------|------| 88 --:::::::::: --cifo.doc --:::::::::: A Catalog of Interface Features and Options for the Ada1 Runtime Environment Release 1.1 November 23, 1986 Ada Runtime Environment Working Group Interfaces Subgroup Association for Computing Machinery Special Interest Group for Ada 1 Ada is a registered trademark of the U.S. Government (AJPO) Copyright (C) 1986 by the Association for Computing Machinery, Inc., Special Interest Group for Ada, Ada Runtime Environment Working Group. Copying without fee is permitted provided that the copies are not made or distributed for direct commercial advantage and credit to the source is given. Abstracting with credit is permitted. Photocopying and electronic data transmission of this document are permitted for private use. Preface Dear Colleague, On 6 May 1985 in Clear Lake, Texas, the principal members of the Ada Runtime Environment Working Group (ARTEWG) held their first working group meeting. The goals of the ARTEWG, which is sponsored by SIGAda, are to establish conventions, criteria, and guidelines for Ada runtime environments that facilitate the reusability and transportability of Ada program components, improve the performance of those components, and provide a framework which can be used to evaluate Ada runtime systems. The ARTEWG expects to be a mechanism for users to interface effectively with Ada implementors, thereby encouraging development of runtime environments that meet user's needs. The AJPO recognizes and encourages the objectives of the ARTEWG, and is receptive to the consolidated voice of the Ada community as represented by the ARTEWG on Ada runtime environment issues. At the first meeting, the foundation of our charter was created and three Subgroups were formed. Subgroup I was to concentrate on the runtime environment (RTE) dependencies explicitly or implicitly traceable to the Language Reference Manual (RM). Subgroup II was to focus on the needs of the various applications for Ada. Subgroup III was to follow and contribute to the work of the other two subgroups. In addition, Subgroup III initiated a parallel activity. Building upon the knowledge and experience of the subgroup members, we began to work upon features and options that were obviously prime candidates for a set of common user-RTE interfaces. The immediate goal of Subgroup III therefore is to develop a "Catalog of Interface Features and Options" (CIFO) with rationale and notes on feasibility. We have outlined the work to be done and we have a backlog of features and options under consideration. We have created a Baseline Documentation Set and we provide public progress reports at each SIGAda conference. We plan to release the catalog information in increments that are the products of three steps. First, the principal members prepare a proposed release for the ARTEWG reviewers. Your comments are considered and a revision is then released for public review. The result of the review process is then added to the incrementally growing catalog. So that you may be aware of the schedule for the next six months, we are estimating: o Release #1 to the ARTEWG Reviewers - End of October, 1986. o Reviewer's Comments Due - End of November, 1986. o Public Review of Release #1 - Mid November, 1986. o Public Review Comments requested - End of December, 1986. o Release #2 to the ARTEWG Reviewers - End of December, 1986. o Reviewer's Comments Due - End of January, 1986. o Public Review of Release #2 - Mid January, 1987. o Public Review Comments requested - End of February, 1987. Please remember that we are all part time volunteers working on what well may be the most important single deficiency in today's Ada implementations. Subgroup III needs and appreciates your review work. Thank you on behalf of Subgroup III, Charles McKay, Chair Subgroup III University of Houston-Clear Lake 2700 Bay Area Blvd. Houston, Texas 77058 (713) 488-9490 Table of Contents 1.0 Objective . . . . . . . . . . . . . . . . . . . . . . . 1 2.0 Rationale . . . . . . . . . . . . . . . . . . . . . . . 2 3.0 Catalog Entries . . . . . . . . . . . . . . . . . . . . 6 3.1 Introduction . . . . . . . . . . . . . . . . . . . 6 3.2 Nonpreemptible Sections . . . . . . . . . . . . . 7 3.3 Special Delays . . . . . . . . . . . . . . . . . . 10 3.4 Pre-elaboration of Program Units . . . . . . . . . 12 3.5 Task Identifiers . . . . . . . . . . . . . . . . . 13 3.6 Abortion via Task Identifier . . . . . . . . . . . 16 3.7 Transmitting Task Identifiers Between Tasks . . . . 18 3.8 Interrupt Management . . . . . . . . . . . . . . . 19 3.9 Dynamic Priorities . . . . . . . . . . . . . . . . 22 3.10 Time Slicing . . . . . . . . . . . . . . . . . . . 24 3.11 Fast Interrupt Pragmas . . . . . . . . . . . . . . 26 3.12 Synchronous and Asynchronous Task Scheduling . . . 31 4.0 Deferred Items . . . . . . . . . . . . . . . . . . . . . 37 5.0 Submission of Comments . . . . . . . . . . . . . . . . . 38 Appendix A . . . . . . . . . . . . . . . . . . . . . . . . . 39 1.0 Objective The Ada language intentionally (necessarily) leaves the details of many important capabilities of the Runtime System to the individual implementation, such as scheduling regime, interrupt control, storage management, and so on. In many applications, such capabilities and services are essential to the successful realization of the project, and will of necessity be provided. Since the user's interface to these capabilities is often not specified in great detail, implementations will differ as they emerge. The objective of this document is to propose and describe the first of a common set of user-RTE interfaces, with which a programmer can both request services of the RTE and tailor the RTE to meet application-specific requirements. By the word 'common', we mean that implementations are intended to provide the capabilities expressed by the language-oriented interface descriptions in such a way that programmers need not learn a new interface when using a different Ada implementation. It should be emphasized that although by no means perfect, we do not view the language (as described by the language reference manual) as being deficient in all of the areas addressed (although implementations often are). Highly application-dependent requirements are not appropriately to be found in a language reference manual. However, in keeping with the concept of 'extensibility', implementations should be expected to extend the language, in the RM-prescribed manner, to meet application-specific requirements. Thus, many 'language deficiencies' are more correctly expressed as 'procurement issues'. Those implementations which expect to succeed in a particular marketplace must expect to supply the capabilities necessary to meet the specific requirements of that marketplace. The interfaces which follow are an attempt to provide commonality at the user level for some of the initial capabilities that will often be required. Release 1.1 Page 1 of 41 2.0 Rationale As implementation-dependent features of the Ada Runtime Environment (RTE) emerge, a divergence is developing in syntactic and semantic details. Such features are to be widely used and it is desirable, in order to derive the maximum benefits from the choice of Ada as the preferred high order language, that there be conventions about the interfaces providing access to these features. Common interfaces are clearly needed to make the development of high-quality software practical for the full range of applications that Ada was intended to serve, especially the domain of embedded real-time systems. This Catalog of Interface Features and Options is being developed to promote a commonality with respect to such implementation dependencies, to promote reusability and transportability of Ada program components, and to improve the performance of those components. Major issues such as process scheduling, debugging, and distributed processing are involved. The following is a discussion of some of the major areas of concern. While this discussion is not complete, it does represent a significant number of the issues and points out the need for the common set of conventions proposed in subsequent sections of the document. Control of Memory Management Memory management functions provided by the RTE are often critical to the operation of real-time applications. The RM does not require return of deallocated storage to an available pool, potentially allowing for exhaustion of storage resources. Furthermore, any RTE function not under control of the application program that can significantly impact performance can cause constrained applications to fail. Storage reclamation is such a function. However, limitations on resources may in some cases make such capabilities necessary. Thus, conventions providing application-level control over such RTE functions are desirable. Distributed Systems Computers are increasingly used in applications which require high reliability, because they impact life and property. The failure of such an application can be disastrous. By decentralizing the system architecture, systems can be built that not only do not have single points of failure, but that are fault-tolerant. Furthermore, extensibility of performance and functionality is often vital. When the software system is designed with distribution as a design criterion, the resulting modularity provides a design that need not be radically changed for Release 1.1 Page 2 of 41 increases in processing power (for performance) or for the addition of new modules (for additional functionality). In a system intended to have a long, evolving life cycle, this is a major issue. Multiprogramming Experience has taught us that many large scale and real time systems have requirements for multiprogramming support. By "multiprogramming", we mean that multiple, independent programs may coexist in some state of execution which is supported by the underlying RTE. Multiprogramming is not at all new, and is in fact a highly typical configuration in today's systems. One example is a critical application that requires changes to the software without stopping the software first. Another example is found in those systems with requirements for fail-soft operation where emergency conditions may result in the suspension and preemption of lower priority programs so that the system resources may be devoted to servicing the higher priority programs until the emergency is past. A program represents an executable model of a solution to a problem. Because a large number of modern problems possess inherent parallelism, Ada's multitasking permits a natural model of the solution to be expressed. (By "multitasking", we mean that, within a single program, multiple threads of control may coexist in some state of execution which is supported by the underlying RTE.) Furthermore an increasing number of large scale systems contain several subsystems, some of which may be real- time and some of which may not be. Some subsystems are critical to the point of having to run at all times, without stopping. Nevertheless, changes, upgrades and fixes to such software is unavoidable. As a collection of individual programs, such requirements may be met. There is often a desire to subcontract the subsystems to different contractors, each of which will address their assignment with an appropriate Ada program. For purposes of final verification, validation, and integration of the subsystems into a working system, it is desirable to retain the independence (and the accountability) of the individual programs. Similar benefits accrue during the maintenance and operation phase. Application Access to the Machine Certain applications must access special features of the target machine in order to meet requirements for performance, accuracy, functionality, and so on.These programs have inherently non-transportable components. To minimize the impact of this lack of transportability on both software and programmer, conventions for accessing typical features are desirable. Release 1.1 Page 3 of 41 In some situations hardware interrupts will be intolerable. The ability to disable and enable interrupts is often required of real-time systems. Also, there is the issue of supporting more sophisticated operations, such as selectively controlling specific interrupts. To minimize the dangers of RTE-conflicts that an ad-hoc approach would imply, an RTE-interface is proposed. The RM suggests that interrupt handlers be implemented by associating interrupts with task entries. The overhead of scheduling and dispatching a task in response to a hardware interrupt will at times be unacceptable in highly-constrained applications. Thus, a standardized interface specifying the minimization of interrupt handler latency is desirable. Predictable Timing The need often arises in real-time systems for a task (or tasks) to execute with a very small variation between a requested time of execution and the actual time of execution. Currently there is no way to guarantee bounds on the time of execution. This can cause serious problems, particularly during overload situations. Control of Scheduling In order for some real-time applications to meet their demanding performance requirements, explicit control over the scheduling and dispatching regime is often utilized. An interface specification providing periodic scheduling of tasks that are to be executed at a fixed frequency, with very small variation, is thus a very desirable capability in many Ada-based application solutions. In real-time applications there are situations, such as load-shedding in response to failures, in which the design approach requires the ability to dynamically adjust task priorities. The predefined priority scheme in Ada is static. Thus, an interface to the RTE specifying such a capability is desirable. Along with dynamic priorities, task identifiers beyond those of the inherent lexical identifiers may play a large part in defining conventions allowing control of the scheduling and dispatching decisions. Release 1.1 Page 4 of 41 Fault Tolerance Many applications require support for fault-tolerant operation. The approach may be based on a transparent detection- response scheme below the application, an explicit handling at the application level, or a combination of both. This involves not only hardware support, but also software support via the RTE. Common interfaces which provide applications with capabilites to detect (or be informed of) failures, and respond appropriately, at the application level and below, are desirable. Pre-elaboration Many embedded systems cannot afford the time or memory for elaboration of all entities to occur at runtime. There is a need for a means of requesting that some or all of those entities that may be elaborated prior to runtime be so handled. Critical Sections Some runtime applications are required to ensure that certain sections of code be executed to completion without interruption by other application tasks. For example, there may be a timing constraint on the segment. A means of specifying this sort of control is needed. Conclusion Clearly there are a number of application domains in which common interfaces, if widely used, could promote the Ada language as a standard. This is especially evident for real-time, embedded systems, because of the inherent additional constraints on time and memory resources. Use of common interfaces established in this Catalog of Interface Features and Options can minimize the impact of non-transportability for both software and people and thus promote the building of superior software systems. However, many of the interfaces in this Catalog not only enhance reusability and transportability, but also provide essential functional capability for the application designer. By providing a common set of interfaces between the application designer and the RTE, use of the Ada language in applications for which it was designed will be significantly facilitated and enhanced. Release 1.1 Page 5 of 41 3.0 Catalog Entries 3.1 Introduction The proposals which follow are not intended to be exhaustive, nor are they intended to exclude other approaches to similar problems. Rather, they represent an initial attempt to provide a common set of interfaces to programmers who need to make use of such capabilities. It should be noted that these proposed interfaces are not changes to the language. On the contrary, they represent "legal enhancements" in the sense that the RM prescribes various means of providing additional functionality at the language level (packages, pragmas, attributes, etc.). They do not alter the semantics of existing RM-defined constructs, since such alterations would be "illegal". Instead, they represent entries in a Catalog of Interface Features and Options that may be used to tailor a set of Ada resources for differing application environments. The use of pragmas has been minimized for a number of reasons, primarily since a compiler can ignore them without informing the user if it does not support them. In contrast, packages, generics and subprograms which are not supported must be rejected. Furthermore, the proposed features, expressed as packages and subprograms, could at least conceivably be implemented entirely via RTE modules. Pragmas and attributes would absolutely require the intermediation of a cognizant compiler. However, when the semantics of pragmas are truly appropriate, they may be used. The declarations for these interfaces are intended to be available to users via an Ada program library. The implementations are logically unit entries in the Runtime Library, but may be implemented by compiler-emitted code, or by combinations of both. (See A Draft Proposal for A Canonical Definition of Ada Runtime Environments2 for a more detailed discussion of runtime system architectures and organizations.) 2 available from the Ada Run Time Environment Working Group Release 1.1 Page 6 of 41 3.2 Nonpreemptible Sections 3.2.1 Issue Certain time-critical sections of code must be guaranteed to be executed to completion without preemption. 3.2.2 Proposal An implementation-defined package: package PREEMPTION_CONTROL is procedure DISABLE_PREEMPTION; procedure ENABLE_PREEMPTION; function PREEMPTIBLE return BOOLEAN; end PREEMPTION_CONTROL; The effect of calling procedure DISABLE_PREEMPTION is to guarantee that the processor is not preempted from the calling task, until it next calls ENABLE_PREEMPTION. The intention is that the timing of execution between such calls should be predictable from examination of the intervening code. Ideally, a nonpreemptible task should not even be interruptable by hardware interrupts, but this may not always be practical. An implementation may permit a task with preemption disabled to be interrupted by hardware interrupt handlers that are absolutely essential to the correct operation of the system, but the aggregate fraction of processor time potentially lost to such interrupts should be bounded a priori, so that execution timing is still predictable. Any interrupts permitted by the RTE implementation for nonpreemptible tasks should be documented, with sufficient information to permit prediction of running times, as well as any limitations on the safe use of these procedures. It is the responsibility of a programmer using this feature to insure that all documented rules for safe use are followed. Any standard Ada operations that are documented as "synchronization points" or otherwise may require a task to wait should ordinarily be avoided within a nonpreemptible section. However, if such an operation is performed, it will have the effect of implicitly enabling preemption. The function PREEMPTIBLE returns TRUE if and only if the calling task is currently nonpreemptible on its processor. Calling ENABLE_PREEMPTION when the processor is already preemptible, or DISABLE_PREEMPTION when the processor is already nonpreemptible, is permitted, and should have no effect. 3.2.3 Discussion Release 1.1 Page 7 of 41 Developers of real-time software have expressed a need for the ability to insure that a given segment of code is executed without interruption. In particular, there may be a timing constraint on the segment. Minimal standard Ada provides no way of insuring that the processor is not preempted by the RTE from a task at any time. Moreover, it is difficult to even insure against preemption by other Ada tasks of the same priority, since the RTE is permitted to use time-slicing to interleave execution of such tasks. In some applications it could be catastrophic to switch tasks during such a section. This feature might be used as follows: declare use PREEMPTION_CONTROL; begin DISABLE_PREEMPTION; -- do time-critical work. ENABLE_PREEMPTION; exception when others => ENABLE_PREEMPTION; end; It has been suggested that all such nonpreemptible operations might be concentrated in the entries of one task, of highest priority. The worst failing of this is that it does not deal with the problem of interruptions by the RTE. It also introduces new problems. Since an implementation need not support any particular range of priorities (or any at all), any solution that depends on priorities is already implementation-dependent. This approach is also dangerous because it depends on there being no other task in the system of higher priority. That is difficult to insure, especially in a system that is evolving over time, or where there is multiprogramming. Using priorities in this way is also problematic in a multiprocessor system, since it would preclude more than one processor from being in a time-critical section at one time, forcing unnecessary waiting. This feature was originally proposed as a generic procedure, with a single procedure parameter, which could be instantiated with a time-critical procedure as parameter so that calls to the instantiation would be nonpreemptible. This was intended to provide some protection against accidental failure to re-enable preemption, such as might happen if a programmer failed to insure that all control paths (including exceptions) leading from a call to DISABLE_PREEMPTION eventually lead to a call to ENABLE_PREEMPTION. This solution was rejected because it could not be implemented entirely within the RTE, without special compiler support. One alternative to this feature is use of explicit interrupt control, as provided in a separate catalog entry. (See Interrupt Release 1.1 Page 8 of 41 Control.) This has the disadvantage of being more machine- dependent, and therefore less portable. It also is less reliable, since an RTE implementation may not provide for explicit masking of all hardware interrupts -- in order to protect against interference with interrupts used by the RTE. While some have criticized this feature as being dangerous, or inconsistent with the standard Ada semantics for priorities, it is clear that real-time programmers need this capability and will get the equivalent effect some way, reverting to machine-code to disable interrupts if necessary. Because the alternatives seem more hazardous and less transportable, the ARTEWG feels providing this feature is preferable. As for the Ada standard, the wording concerning priorities only requires that a lower priority task be preempted when a higher priority task can "sensibly" be executed using the same resources. By using this feature, the programmer is simply telling the RTE that the current task cannot be sensibly (safely) preempted. It is the responsibility of the programmer to insure that a task does not remain nonpreemptible for very long, and that use of this feature does not nullify the intent of any specified priorities. Any other use of this feature would be erroneous. Note that these procedures are expected to be implemented in-line, if possible. This procedure should not be used to attempt to guarantee mutually exclusive access to any resources other than the one processor on which the section of code is executing, and any other resources which are implied by possession of the processor (such as local I/O ports). Thus, it cannot be used to protect data against concurrent updates in a multiprocessor configuration. Note also that it implies that in such a multiprocessor configuration the section of nonpreemptible code must be executed on a single processor. If a delay is desired within a nonpreemptible section it should be programmed as an "idle delay", rather than with the standard Ada delay statement. (See the catalog item on Special Delays.) Release 1.1 Page 9 of 41 3.3 Special Delays 3.3.1 Issue There are several different possible implementations of the Ada delay, each of which has excessive inaccuracy, overhead, or unpredictability for some applications. Among other problems: (1) a delay may be required that is less than the execution-time overhead of the Ada delay implementation; (2) a delay may be required that has a known upper bound (as well as lower bound) on duration. Furthermore, the semantics of the standard Ada delay, which is a task synchronization point, may not be appropriate for some applications. 3.3.2 Proposal A package: package IDLE_DELAYS; type DURATION is delta range ; procedure IDLE_DELAY( D : in DURATION ); end IDLE_DELAYS; A call to the procedure IDLE_DELAY should take D seconds to complete. This call would not be a task synchronization point, nor would the processor be relinquished, subject to other dispatching considerations. In particular this may be called from a nonpreemptible section, if that feature is supported. (See separate CIFO proposal for nonpreemptible sections.) The local type DURATION is provided in case the predefined type duration does not have sufficient precision to represent this form of delay, and to give the lower and upper bounds on the length of delay that may be requested. If the predefined type has enough accuracy, the following declaration may be substituted: subtype DURATION is STANDARD.DURATION; The implementation should document how precisely such delays are implemented. 3.3.3 Discussion The proposed procedure allows the system to utilize whatever mechanism may be appropriate to obtain the desired result. In many cases it may be desirable to implement such a delay as a "busy wait"; that is, the processor executing the delayed task may idle until the delay has expired. We would not expect any Release 1.1 Page 10 of 41 task switching to occur during this wait. For example, the compiler may generate the exact series of instructions necessary (such as "loop 20 instructions) to get as close as possible to the given delay. Alternatively, a special call to the underlying RTE may be utilized. Where processor clock rates vary dynamically it may be necessary to use an externally triggered interrupt to implement this feature. Since predicting the accuracy of such delays is likely to depend on the implementation in ways that cannot be accurately explained by specifying a simple constant, such as DELAY'DELTA, adequate implementation documentation is essential. Note that the explicit inclusion by the programmer of "timed code" to achieve the effect of such a delay is not transportable and not guaranteed to have the desired effect, due to compiler elimination of "useless" code, variations in processor clock rates, and possible RTE interruptions. It should be emphasized that this proposal represents no violation of the LRM, in that it does not propose different semantics for the predefined delay statement, but, rather, another delay capability with its own semantics. Note also that the local type DURATION would not hide the standard type duration outside the package, where it would be known as IDLE_DELAYS.DURATION. Explicit conversions between this type and the standard type DURATION would be required, of course. For this reason it is preferable that the 'SMALL attributes of these two types be compatible, so that such conversions do not require any runtime computations. An example of the use of this package might be: with IDLE_DELAYS; use IDLE_DELAYS; procedure START_ENGINE is begin ... ACTIVATE_RELAY_1; IDLE_DELAY(0.00001); ACTIVATE_RELAY_2; ... end START_ENGINE; Release 1.1 Page 11 of 41 3.4 Pre-elaboration of Program Units 3.4.1 Issue Runtime elaboration of constant data structures and a priori known tasks is not consistent with many embedded systems' power- up and restart requirements. 3.4.2 Proposal pragma PRE_ELABORATE( ); The proposed pragma would allow the compilation system (i.e., compiler/linker) to initialize the indicated list of data structures and a priori program units. If the optional identifier list is omitted, all possible entities will be pre-elaborated, and a list of those entities that cannot be pre-elaborated will be emitted. 3.4.3 Discussion Constant data bases are currently loaded into read-only memory. Therefore runtime initialization of these entities is impossible. A warm restart is a frequent recovery technique for embedded systems. The time required to re-elaborate data structures and program units would be unacceptable under the circumstances. Real-time subsystems have a very limited amount of available time between power-up and the first required functionality. There will often not be enough time to elaborate everything. Without this pragma, the respective programs would have to be loaded onto target hardware, executed to the point where the data structures and program units are elaborated, and then a "core" image burned into EEPROM. Logistic support is in place for the pragma-based approach, but not for the elaborate-and-burn approach. Release 1.1 Page 12 of 41 3.5 Task Identifiers 3.5.1 Issue Several RTE extensions described in this catalog require a means of specifying tasks as parameters to RTE procedures, where the Ada typing rules would not permit using the name of the task. In addition, in the writing of general schedulers and resource managers (viz. Wellings et. al., in Ada Letters, Jan. 1984, pp. 112-123) there is need for a means of storing information about tasks in tables, and for a way of associating a storable identifier with each task, beyond the basic capabilities provided by the language. 3.5.2 Proposal An implementation-defined package: package TASK_IDS is type TASK_ID is private; NULL_TASK : constant TASK_ID; generic type TASK_TYPE is limited private; function ID_OF( T : TASK_TYPE ) return TASK_ID; function SELF return TASK_ID; function ENCLOSING_TASK( LEVELS_OUT : NATURAL ) return TASK_ID; function PARENT( I : TASK_ID ) return TASK_ID; function CALLER return TASK_ID; function CALLABLE( I : TASK_ID ) return BOOLEAN; function TERMINATED( I : TASK_ID ) return BOOLEAN; private type TASK_ID is ; NULL_TASK : constant TASK_ID := ; end TASK_IDS; This package provides the type TASK_ID and several functions for Release 1.1 Page 13 of 41 obtaining the identifer of a particular task and determining its status. The validity of the ID returned by any of these functions shall be limited to the calling task (like a capability). That is, a task cannot expect to pass a task ID as a parameter or via shared variable to another task and have it mean anything. This provides useful freedom to a distributed implementation, and it allows enforcement of possible security restrictions. The result of using an invalid task ID is undefined, and is likely to vary according to how it is used. For example, in a secure system it might cause the calling task to be aborted. An instantiation of the generic function ID would return a unique identifier for any task of the type for which it is instantiated. For example: task type T; function ID is new TASK_IDS.ID_OF(T); T1: T; T1_ID: TASK_IDS.TASK_ID:= ID(T1); The function SELF would return the ID of whatever task calls it. The function ENCLOSING_TASK would return the ID of the task LEVELS_OUT static (lexical) task-nesting levels from the point where the function is called. If LEVELS_OUT = 0, it returns the ID of the calling task, which is also available via the function SELF. Each statically nested task would count as one level, as would the (virtual) task which "calls" a program or elaborates a library package. If there is no such task (i.e. LEVELS_OUT is too large), the function would return NULL_TASK. The function PARENT would return the ID of the task on which the task calls the function is directly dependent. The function CALLER, if called from with an accept, would return the ID of the partner task, which made the entry call which is being accepted. In the case of nested accepts it would return the ID of the partner in the innermost enclosing accept. If called from outside an accept, it would return NULL_ID. The function CALLABLE(I) would return the value of the attribute 'CALLABLE for the task corresponding to the ID I, and the function TERMINATED(I) would return the value of the attribute 'TERMINATED for the task corresponding to the ID I. The value NULL_TASK is always TERMINATED and never CALLABLE. 3.5.3 Discussion This package provides a universal way of specifying tasks, irrespective of their types. It does potentially extend the "visibility" of tasks via the function CALLER in a way that might be dangerous. Therefore, an implementation may choose not to Release 1.1 Page 14 of 41 implement this function, or to raise TASKING_ERROR if for some reason (security, or danger of dangling reference) the implementation does not wish to return the ID of the caller task. By itself, this package is not very useful. Its chief purpose is to support other RTE interface features described in this catalog. However, one can imagine a key-server which verifies that at most one key is allocated to each task, as sketched below: task KEY_SERVER is entry REQUEST( K: out KEY ); ... end KEY_SERVER; task BODY KEY_SERVER is use TASK_IDS; TK: KEY; ... begin loop ... accept REQUEST( K: out KEY) do LOOKUP(CALLER,TK); if TK=NULL_KEY then ASSIGN_KEY(CALLER,TK); end if; K:= TK; end REQUEST; ... end loop; end KEY_SERVER: Here we assume that LOOKUP(CALLER,TK) returns the key of CALLER in TK, if one has been assigned, and returns NULL_KEY otherwise. We also assume that ASSIGN_KEY(CALLER,TK) allocates a new key for caller, records the assignment in a table, and returns the key in TK. Release 1.1 Page 15 of 41 3.6 Abortion via Task Identifier 3.6.1 Issue It is sometimes necessary to abort a task that is not visible. 3.6.2 Proposal with TASK_IDS; use TASK_IDS; procedure ABORT_TASK( I: TASK_ID); Calling this procedure would request the RTE to abort the task corresponding to identifier I. 3.6.3 Discussion This capability partially addresses the problem of writing reusable executives and failure-recovery tasks. If such a component is reusable, it cannot have visibility of those other tasks which it manages, since these are different for each application. For example, consider a general "watchdog" task. Each watched task could provide its ID to the watchdog, by calling an entry of the watchdog when the task starts up. The watchdog would return the task an access value to a variable which the task would be required to update periodically. If the task did not update the variable between checks, the watchdog would abort it. generic N : in INTEGER; package WATCHDOG is ACTIVE : array (1..N) of BOOLEAN; procedure REGISTER( I : out INTEGER ); end WATCHDOG; (Continued on next page.) Release 1.1 Page 16 of 41 package body WATCHDOG is TIMED_TASK: array (1..N) of TASK_ID; L: INTEGER range 0..N:= 0; pragma SHARED(L); task REGISTRAR is entry REGISTER( I : out INTEGER ); end REGISTRAR; task TIMER; procedure REGISTER( I: out INTEGER) renames REGISTRAR.REGISTER; task body REGISTRAR is begin loop begin accept REGISTER( I: out INTEGER ) do L:= L+1; I:=L; TIMED_TASK(L):=CALLER; -- raises constraint_error if all slots in -- array ACTIVE are in use. end REGISTER; exception when others => null; end; end loop; end REGISTRAR; task body TIMER is I: INTEGER; begin loop delay 1.0; for I in 1..L loop if not ACTIVE(I) then ABORT_TASK(TIMED_TASK(I)); end if; end loop; end loop; end TIMER; end WATCHDOG; Release 1.1 Page 17 of 41 3.7 Transmitting Task Identifiers Between Tasks 3.7.1 Issue Task identifiers are only valid for the task which obtains them directly from the runtime system. This limits their utility. 3.7.2 Proposal function TRANSLATE( SUBJECT: TASK_ID; RECIPIENT: TASK_ID ) return TASK_ID; If one task wishes to transmit a task ID, SUBJECT, to another task, RECIPIENT, in a form that is usable by the recipient, it would need to explicitly translate it, via this function. If SUBJECT or RECIPIENT are not valid, or if it is contrary to implementation or security restrictions to transmit the ID to the intended recipient, the result is undefined. 3.7.3 Discussion This function could be used to allow task IDs to be passed between tasks as entry parameters or via shared variables. Release 1.1 Page 18 of 41 3.8 Interrupt Management 3.8.1 Issue The RM (13.5.1) does not define the manner of managing interrupts on the target, since they are highly implementation- dependent. Typical architectures incorporate either a level- oriented mechanism, in which interrupts are specified by number, or a named mechanism, in which interrupts are individually named. A common format for controlling and interrogating either individually-named or level-oriented interrupts is thus desirable. 3.8.2 Proposal A generic package, to be instantiated by the implementation (not the applications developer) presumably within or in conjunction with package System : generic type INTERRUPT_ID is (<>); package INTERRUPT_MANAGEMENT is type INTERRUPT_LIST is array( INTERRUPT_ID ) of BOOLEAN; procedure ENABLE( INTERRUPT : in INTERRUPT_ID ); procedure DISABLE( INTERRUPT : in INTERRUPT_ID ); function ENABLED return INTERRUPT_LIST; end INTERRUPT_MANAGEMENT; Upon instantiation, the generic formal parameter INTERRUPT_ID is to be passed a type representing the maskable interrupts supported by the implementation. 3.8.3 Discussion The manipulation of interrupts by the application developer is inherently a complex and dangerous activity. The potential for corrupting the integrity of the runtime system is great. However, it is an activity that is commonly considered an absolute requirement in highly-constrained applications. Therefore, this package is provided, but the use of this package is to be left to highly experienced personnel. Since the generic formal parameter must be a discrete type, either integers or enumerations may be used as the actual parameter. If the proposed package is instantiated with an actual parameter that is an integer (sub)type, then control is to be by Release 1.1 Page 19 of 41 'interrupt levels'. In this case, the declaration would look something like the following (again, assuming use of package System): package SYSTEM is ... type INTERRUPTS is range ... ... package INTERRUPT_CONTROL is new INTERRUPT_MANAGEMENT( INTERRUPTS ); ... end SYSTEM; Then, to enable, for instance, level 6 interrupts (assuming the range contained that value), the call could be: ENABLE( 6 ); If instantiated with an enumeration type as the generic actual parameter, then control is to be by individual, named interrupts rather than by numbered levels. In this case, the declaration would look like the following: package SYSTEM is ... type INTERRUPTS is ( QV1, CLK, TIMER1, TIMER2, ... ); ... package INTERRUPT_CONTROL is new INTERRUPT_MANAGEMENT( INTERRUPTS ); ... end SYSTEM; Then, to enable a clock interrupt named CLK, the call would be: ENABLE( CLK ); The procedure DISABLE is called in the same manner as procedure ENABLE. It will disable the interrupt specified. However, procedures ENABLE and DISABLE have an effect that is implementation-dependent with respect to their effect on any interrupts other that those specified in the call. For example, the hardware may be such that a call to DISABLE will disable the specified interrupt and all "lower-level" interrupts as well. The implementation is expected to document this kind of effect. The package defines a type INTERRUPT_LIST, which is an array of Boolean status flags. Each flag indicates the state of a particular interrupt. An individual interrupt may be accessed via the array index, which is based on the names of the interrupts implemented. (The array is constrained for the sake of efficient implementation.) Release 1.1 Page 20 of 41 Function ENABLED returns a value of the type INTERRUPT_LIST. The function will return values of true for those levels that are enabled. Since the function returns an array indicating the status of all interrupts, a snapshot can be taken, as follows: declare SNAPSHOT : INTERRUPT_LIST; begin ... SNAPSHOT := ENABLED; ... end; The status of several interrupts, at the time the snapshot was taken, can be assessed by indexing the array object: if SNAPSHOT( CLK ) and SNAPSHOT( TIMER1 ) then ... To access the current state of an individual interrupt, the identifier for the interrupt could be used as an index into the result of the function call, as follows: if ENABLED( CLK ) then ... Use of this package is highly dependent upon proper documentation of the requirements of the RTE regarding interrupts, and a thorough knowledge of the supporting interrupt hardware mechanism. Great care must be taken not to interfere with the internals of the RTE. Release 1.1 Page 21 of 41 3.9 Dynamic Priorities 3.9.1 Issue The minimal priority scheme defined by the RM provides static priorities only. Many applications require a more dynamic priority assignment capability. For instance, degraded operation implies that some functionality may be much less important than in normal operation, and should be assigned a less urgent priority (if retained at all). 3.9.2 Proposal with TASK_IDs; package DYNAMIC_PRIORITIES is type PRIORITY is range ; procedure SET_PRIORITY( OF_TASK : in TASK_IDS.TASK_ID; TO : in PRIORITY ); end DYNAMIC_PRIORITIES; 3.9.3 Discussion This package provides a capability to assign priorities to tasks. It requires the presence of the Task_IDs package. A task can set its own priority as follows: task body SOME_TASK is begin ... SET_PRIORITY( TASK_IDS.SELF, TO => SOME_PRIORITY ); ... end SOME_TASK; A task can also set priorities of other tasks if it has their IDS. Note that priorities set via this package would not conflict with any declared Ada priorities, but only serve to provide finer-grained distinctions between tasks of equal or undefined Ada priority. However, it is recommended that if this package is supported, the standard type SYSTEM.PRIORITY be defined to have a null range (for example, 0 .. -1), to avoid confusion. Release 1.1 Page 22 of 41 If task IDs are not supported, an alternative version of this package could be provided: package DYNAMIC_PRIORITIES is type PRIORITY is range ; generic type TASK_TYPE is limited private; procedure SET_PRIORITY( OF_TASK : in TASK_TYPE; TO : in PRIORITY ); end DYNAMIC_PRIORITIES; Using this version we could do the following: task type T; TASK_OBJECT : T; procedure SET_PRIORITY is new DYNAMIC_PRIORITIES.SET_PRIORITY( TASK_TYPE => T ); task body T is begin ... SET_PRIORITY( OF_TASK => T, TO => SOME_PRIORITY ); ... end T; With this package, the task passes the name of the task unit (i.e., the type name), which refers to the task object executing the body (i.e., itself). The second package has the advantage of being "standard" Ada in that it depends only on predefined constructs. The disadvantages are that there is no guarantee that a task type will be passed as the actual parameter to the instantiation of the generic, and that there is no simple way to set the priority of a task without a priori knowledge of its (task) type. Release 1.1 Page 23 of 41 3.10 Time Slicing 3.10.1 Issue The minimal scheduling rules defined in the RM do not provide for setting time slices, nor do they provide a way to dynamically assign or change slices for tasks. 3.10.2 Proposal with TASK_IDS; use TASK_IDS; package TIME_SLICING is subtype SLICE is DURATION ; procedure SET_TIME_SLICE( OF_TASK : in TASK_ID; TO : in SLICE ); end TIME_SLICING; By time slicing, we mean preemptive round-robin dispatching with time allocated to a task in quanta of some fixed size per task. If this package is supported, the default would be for tasks of equal (or mutually undefined) priority to be dispatched with an unlimited time-slice. Such a task, once it began executing would continue until it blocked itself (e.g. for a delay or rendezvous), or until it was preempted by a higher priority task. In contrast, once SET_TIME_SLICE(T,D) has been called, task T would be dispatched preemptively, with time-slice D. Once it began executing it would execute for at most D seconds (or until blocked), before yielding its place to any other tasks of equal priority. The time-slice of a task could be changed by calling SET_TIME_SLICE dynamically. This would permit adjusting the relative proportion of processor time allocated to several ongoing ("background") tasks in a way that cannot be accomplished by means of priorities. If this package is supported, dispatching of equal (or mutually undefined) priority tasks would be on a round-robin basis. 3.10.3 Discussion Implementations exist which allow for setting time slices via a pragma, but these require the slice size to be statically set. Release 1.1 Page 24 of 41 If task ids are not supported, an alternative but less powerful form can be provided: package TIME_SLICING is subtype SLICE is DURATION ... ; generic type TASK_TYPE is limited private; procedure SET_TIME_SLICE( OF_TASK : in TASK_TYPE; TO : in SLICE ); end TIME_SLICING; Release 1.1 Page 25 of 41 3.11 Fast Interrupt Pragmas 3.11.1 Issue Transfer of control to an accept statement for an interrupt entry is slower than transfer of control to a traditional interrupt routine (whose address has been loaded into a hardware interrupt vector). This is because in the case of the Ada interrupt rendezvous, various tasking data structures in the runtime environment have to be read and updated. The difference in speed is likely to prohibit the use of Ada for many real time applications. 3.11.2 Proposal A set of implementation-defined pragmas: pragma INTERRUPT_TASK, pragma TRIVIAL_ENTRY, pragma MEDIUM_FAST_INTERRUPT_ENTRY. The pragma INTERRUPT_TASK( KIND : ) is only allowed within a task specification for a single task (c.f. RM 9.1 (2)). It must precede any entry declaration. This pragma conveys to the implementation the information that the task at hand satisfies a set of restrictions, and that the Ada program to which this task belongs satisfies certain restrictions as well. If any of the restrictions are violated, the Ada program is erroneous. The parameter KIND indicates the exact set of restrictions that are satisfied. The possible values include SIMPLE and SIGNALLING. A particular implementation may support additional values for KIND. The following restrictions apply to all interrupt tasks: 1. An interrupt task has exactly one entry, and that entry is an interrupt entry. An interrupt task body has no declarative part. Its sequence of statements consists of a single loop statement that has no iteration scheme. The sequence of statements of this loop statement, in turn consists of a single accept statement for the entry of the task. (Note that there is no restriction, however, on how many statements there may be in the "sequence of statements" of this accept statement.) Release 1.1 Page 26 of 41 2. The Ada program to which this task belongs does not contain any entry calls to the interrupt task. 3. The sequence of statements inside the accept statement does not contain or invoke code that changes the interrupt masking state of the hardware. In particular, interrupts are not re-enabled during the interrupt rendezvous. 4. The execution of the interrupt rendezvous does not, at any one time, occupy more than a given, implementation-dependent amount of stack space. If the interrupt rendezvous invokes subprograms, the stack space occupied by those subprograms is included in the count. If the interrupt rendezvous causes interrupts, the stack space required for the handling of these interrupts is also included in the count. 5. The sequence of statements inside the accept statement, as well as all the code that is invoked by this sequence of statements, is restricted to what might intuitively be described as "straightforward code". The definition of "straightforward code" varies with the KIND of the interrupt task. "Straightforward code" for a SIMPLE INTERRUPT TASK does not contain: i. Delay statements, entry calls, accept statements, declarations of tasks, allocators on access types for task types, program-asynchronous I/O operations, abort statements. ii. References to task attributes of the interrupt task at hand, or references to the attribute COUNT of the interrupt entry at hand. iii. Any checks for the exception STORAGE_ERROR in the generated code. iv. Any code that leads to the raising of Ada exceptions. (This means, e.g. that it is the responsibility of the Ada programmer to ensure that no CONSTRAINT_ERROR exception will be raised during an interrupt rendezvous.) v. References to types or objects that are declared in scopes that enclose the interrupt task, except for types and objects that are declared in library packages. The definition of "straightforward code" for SIGNALLING INTERRUPT TASKS is identical to that for simple interrupt tasks, with one exception: the sequence of statements inside the accept statement, as well as the code that is invoked by this sequence of statements, may include a conditional entry call to a "trivial entry" (see below) in a different task. Release 1.1 Page 27 of 41 The pragma TRIVIAL_ENTRY( NAME : ) may appear within a task specification after an entry declaration. Its argument must be the simple name of an entry. This pragma conveys to the implementation the information that the entry at hand has only "trivial" accept statements. A trivial accept statement is one that does not have a sequence of statements. If the information conveyed by the pragma is not correct, the Ada program is erroneous. The pragma MEDIUM_FAST_INTERRUPT_ENTRY( NAME : ) may appear within a task specification after an entry declaration. Its argument must be the simple name of an entry. This pragma conveys to the implementation the information that the entry at hand satisfies all those restrictions that are satisfied by the entry in a signalling interrupt task, except for the restriction concerning references to non-local types and objects. The accept statement of a medium fast interrupt entry, as well as the code invoked by it, are permitted to reference all those types and objects that they may reference according to the scope and visibility rules of the Ada language. The runtime environment does not change the interrupt masking state of the hardware between the occurrence of the interrupt and the end of the interrupt rendezvous. In particular, it does not re-enable interrupts before the end of the interrupt rendezvous. At the end of the interrupt rendezvous, the runtime environment resets the interrupt masking state of the hardware to what it was before the interrupt occurred. In other words, the runtime environment cancels the changes that were effected by the hardware when the interrupt occurred. The time needed to transfer control to the accept statement in an interrupt task or in a signalling interrupt task is of the same order of magnitude as the time required by the state saving portion of a traditional interrupt routine. The exact time is implementation-dependent. The time needed to transfer control to the accept statement for a medium fast interrupt entry lies between the time required in the case of an interrupt task, and the time needed for an ordinary interrupt entry. The exact time is implementation-dependent. Release 1.1 Page 28 of 41 3.11.3 Discussion An interrupt task can be implemented in the following way: First, augment the sequence of statements of the accept statement, by adding code to save and restore the state of the interrupted computation before and after the interrupt rendezvous. Then, load the starting address of the thus augmented sequence of statements into the hardware interrupt vector for the interrupt at hand. Depending on the hardware architecture, this operation may be part of a more comprehensive interrupt setup operation, through which an interrupt mask is specified along with the address. It is assumed that whatever needs to be loaded along with the address is known, either by convention in the runtime environment, or because it has been specified by the user in some implementation-dependent fashion. The fact that the runtime environment does not re-enable any interrupts before the end of the interrupt rendezvous, along with the restrictions 1. through 3. above, makes this implementation equivalent to the loop in the source text of the interrupt task. In the runtime model for Ada, the execution of all Ada code is viewed as taking place under the control of tasks. If a program segment is not invoked by an inner task, it is viewed as executing under the control of "some environment task" (c.f. RM 10.1 (8)). The runtime environment therefore maintains information on: 1. which task is currently executing 2. which tasks are currently eligible to execute Whenever control passes from one task to another, this information has to be updated. The restrictions for interrupt tasks are such that this information can be allowed to be out of date for the duration of an interrupt rendezvous. In the case of a simple interrupt task, the information will automatically be correct again after the interrupt rendezvous is over. In the case of a signalling interrupt task, the information may have to be updated, but the update can be postponed until the end of the interrupt rendezvous. The significance of the individual restrictions is this: 1 through 3: Make it possible to load the address of the (augmented) sequence of statements for the interrupt rendezvous directly into the interrupt vector. Release 1.1 Page 29 of 41 4: The runtime environment allocates (statically) stack space for interrupt rendezvous. This space must not be exceeded. i: The implementation of the abort statement may or may not involve task switches. Since it is unlikely that there will be a strong requirement for an abort statement in an interrupt rendezvous, it is prohibited. All other constructs listed here will lead, at least potentially, to task switches. This must be prohibited if the lists used by the task switching mechanism are out of date. The weaker version of restriction (i) that is postulated for signalling interrupt tasks is still sufficient to avoid task switches during the interrupt rendezvous: the updating of the appropriate lists can be postponed until after the interrupt rendezvous. ii: These operations make use of a variable indicating which task is currently executing. iii: Depending on the particular implementation, these operations may make use of a variable indicating which task is currently executing. This is most likely the case if there is no hardware mechanism for detecting stack overflow, or if the initialization of that mechanism is too slow. iv: An Ada exception can be re-raised from within an exception handler, and this can be done without specifying the exception again. It is therefore likely that implementations will save the exception in a task-specific location when the exception is raised for the first time. The pointer to this location may be out of date, and moreover, an implementation may not provide such a location for an interrupt task. v: Non-local variables will be accessed through task specific pointers. For interrupt tasks, these pointers may either not be implemented or not be up to date. Note that this restriction does not exist for medium fast interrupt rendezvous. The updating of these pointers is the reason why a medium fast interrupt rendezvous is slower than both simple and signalling interrupt tasks. With the possible exception of (iv), the above restrictions are met naturally in many real time applications. The proposed pragmas can therefore be viewed as a mechanism informing the runtime environments of the application. Once the runtime environment has knowledge of these circumstances, it can take advantage of them and provide a more efficient implementation. Release 1.1 Page 30 of 41 3.12 Synchronous and Asynchronous Task Scheduling 3.12.1 Issue The common mode of task execution in real time systems is via explicit synchronous (cyclic) and asynchronous scheduling. The Ada language definition does not support explicit task scheduling. Rather, it defines only the most rudimentary level of task control, leaving it up to the user to devise his own methodology for implementing higher abstractions of task scheduling. This proposal defines a scheduling package to implement a synchronous and asynchronous scheduling capability. The proposal is based to the process scheduling paradigm of the HAL/S language currently in use in the Shuttle avionics software. 3.12.2 Proposal The package defined here allows for the explicit assertion of scheduling requirements for each task via a procedure call to the runtime environment. The procedure calls would be legal from within the task to be scheduled and from outside the task from anywhere that the task id could be obtained through the TASK_IDS package defined elsewhere. The schedule package would be defined as follows: with TASK_IDS, DYNAMIC_PRIORITIES, CALENDAR; use TASK_IDS, DYNAMIC_PRIORITIES, CALENDAR; package SCHEDULER is TASK_OVERRUN : exception; type EVENT is private; type TASK_INITIATIONS is (IMMEDIATELY, AT_TIME, AFTER_DELAY, ON_EVENT); type TASK_REPETITIONS is (NONE, REPEAT_EVERY, REPEAT_AFTER); type TASK_COMPLETIONS is (NONE, UNTIL_TIME, WHILE_EVENT, UNTIL_EVENT); type INITIATION_INFO(INITIATION : TASK_INITIATIONS := IMMEDIATELY) is record case INITIATION is when IMMEDIATELY => null; when AT_TIME => T : CALENDAR.TIME; when AFTER_DELAY => D : DURATION; when ON_EVENT => E : EVENT; end case; end record; Release 1.1 Page 31 of 41 type REPETITION_INFO( REPETITION : TASK_REPETITIONS := NONE ) is record case REPETITION is when NONE => null; when REPEAT_EVERY | REPEAT_AFTER => D : DURATION; end case; end record; type COMPLETION_INFO( COMPLETION : TASK_COMPLETIONS := NONE ) is record case COMPLETION is when NONE => null; when UNTIL_TIME => T : CALENDAR.TIME; when WHILE_EVENT | UNTIL_EVENT => E : EVENT; end case; end record; procedure SCHEDULE( SCHEDULED_TASK : in TASK_ID; REPORT_OVERRUN : in BOOLEAN := false; PRIORITY : in DYNAMIC_PRIORITIES.PRIORITY; INITIATION : in INITIATION_INFO; REPETITION : in REPETITION_INFO; COMPLETION : in COMPLETION_INFO ); procedure WAIT_FOR_SCHEDULE; procedure DESCHEDULE (SCHEDULED_TASK : in TASK_ID); procedure TOGGLE (TARGET_EVENT : EVENT); procedure SET (TARGET_EVENT : EVENT); procedure RESET (TARGET_EVENT : EVENT); function "or" (LEFT,RIGHT : EVENT) return EVENT; function "and" (LEFT,RIGHT : EVENT) return EVENT; private type EVENT is ; end SCHEDULER; Release 1.1 Page 32 of 41 3.12.3 Discussion The above definition requires some specific semantic rules to fully explain the capabilities and limitations of the package. 1. The SCHEDULE procedure causes the RTSE to permit the task referenced by the call to return from a call to WAIT_FOR_SCHEDULE whenever the conditions expressed by the parameters are met. That is, whenever a task calls WAIT_FOR_SCHEDULE, it will begin to wait; it will be released, so that it is eligible for execution and can return from the call, as soon as the conditions expressed by the last call to SCHEDULE for that task have been met. In the following discussion then, we use the terms "wait" and "release" in precisely this sense, only to refer to waiting for permission to return from a call to WAIT_FOR_SCHEDULE and for the granting of permission to return from such a call. The procedure SCHEDULE with a TASK_ID of "T" as an argument may be called from anywhere that TASK_ID is legal. In particular, a call to SCHEDULE for a task T can be made from within the task T, or from any enclosing scope of task T. In addition, any number of calls to SCHEDULE for task T may be made and the RTSE shall determine, based on the scheduling conditions in the calling arguments, which scheduling assertion to make active at any appropriate time. The example given below shows an example of this capability. 2. The argument SCHEDULED_TASK identifies the task to which this scheduling assertion applies. 3. If true, the argument REPORT_OVERRUN specifies that the RTSE raise the exception TASK_OVERRUN in the scheduled task identified by TASK_ID whenever there comes an opportunity to release the task according to the specified scheduling conditions, but the task cannot be released because it is not waiting on a call to WAIT_FOR_SCHEDULE. By an opportunity to release this task, we mean a time T such that if the task was waiting immediately before T it would have been released at time T. If REPORT_OVERRUN is false, no exception is raised and missed opportunities to release are simply ignored. 4. The argument SCHEDULE_PRIORITY specifies a value of type PRIORITY as defined in the package DYNAMIC_PRIORITIES and performs the equivalent function of SET_PRIORITY. 5. The argument INITIATION specifies a condition for initiation, i.e. first execution, of the task. The possible initiations conditions are specified in the enumerated type TASK_INITIATIONS. Their results are given below: Release 1.1 Page 33 of 41 IMMEDIATELY - The task is released immediately if it is already waiting at a WAIT_FOR_SCHEDULE call, or is immediately released when the call to WAIT_FOR_SCHEDULE occurs. AT_TIME - The argument specifies a clock time at which the task should be next released. If REPEAT_EVERY is not specified, the task is released as soon as CLOCK >= AT_TIME. If REPEAT_EVERY is specified, and WAIT_FOR_SCHEDULE is called at time T, the task is released as soon as CLOCK >= AT_TIME + K*REPEAT_EVERY, for the smallest K such that AT_TIME + (k-1)*REPEAT_EVERY < T < AT_TIME + K*REPEAT_EVERY. AFTER_DELAY - The argument AFTER_DELAY specifies a delay which is to be imposed on the task between the time of this call to SCHEDULE and the time the task is next released. The effect is similar to as if a DELAY statement were inserted at the point of the WAIT_FOR_SCHEDULE, and removed from the code as soon as the task returns. The accuracy of the delay is the same as for a normal delay statement. Note that even if the other arguments to SCHEDULE specify repeated scheduling, AFTER_DELAY applies only to the first release after this call to SCHEDULE. ON_EVENT - The argument ON_EVENT specifies that the task should be released as soon as the expression given for ON_EVENT becomes true. If it is already true at the time the task begins to wait following a call to WAIT_FOR_SCHEDULE, it is released immediately. The expression ON_EVENT is first evaluated when SCHEDULE is called and is reevaluated by the RTSE every time an event occurs that might change its value. 6. The argument REPETITION specifies a condition for repetition of release of the task. The possible repetition conditions are specified in the enumerated type TASK_REPETITIONS. Their results are given below: NONE - The task is never released a second time following its first release. IF the task calls WAIT_FOR_SCHEDULE, then it will not return from that wait until another call to SCHEDULE is made for the task. REPEAT_EVERY - The argument REPEAT_EVERY specifies a delay to be imposed between the time a task may be released, in absolute terms. The effect begins the next time the task is released and continues thereafter until the next call to SCHEDULE for this task. Thus if the task is next released at time T1, and calls WAIT_FOR_SCHEDULE later at time T2, it will be released at the earliest time T1+K*(REPEAT_EVERY) >= T2. Note that this differs from REPEAT_AFTER in that the interval between successive release Release 1.1 Page 34 of 41 points is absolute, rather than relative to the points at which the task begins to wait. REPEAT_AFTER - The argument REPEAT_AFTER specifies a delay to be imposed between one time a task is released and the next. That is, it applies to the second and subsequent occasions when the task is released after this call to SCHEDULE. (Any delay for the first release is specified by AFTER_DELAY.) The effect is similar to inserting a delay statement at the places of the relevant calls to WAIT_FOR_SCHEDULE. Thus, if the task is released, and starts to wait again at time T, it will be released at time T+REPEAT_AFTER. To repeatedly release a task with out any delay, a value of 0 for REPEAT_AFTER is specified. 7. The argument COMPLETION specfies the condition under which the execution of the task will be completed, i.e. after which the task will no longer be released. The possible conditions are specified in the enumerated type TASK_COMPLETIONS. Their results are given below: NONE - Under no conditions will the task be inhibited from being released except as specified in the initiation and repetition conditions. UNTIL_TIME - The argument UNTIL_TIME specifies a time after which the task is not to be released. UNTIL_EVENT - The argument specifies an event condition after which the task is not to be released. Once it becomes true, the task will not be released again (even if the event condition subsequently becomes false again), unless the task is rescheduled by another call to SCHEDULE. As with all other event conditions, the argument UNTIL_EVENT is evaluated once when SCHEDULE is called, and is reevaluated whenever an event occurs that may change the value. WHILE_EVENT - The argument WHILE_EVENT specifies an event condition which must be true for the task to be released. Once it becomes false, the task will not be released again unless the task is rescheduled by another call to SCHEDULE. 8. The implementation-defined type EVENT and its overloaded infix operators "or" and "and" must be defined so that when an expression of the type: EVENT1 or EVENT2 and (EVENT3 or EVENT4) is encountered, the returned value is a structure that may be picked up by the SCHEDULE package and passed to the user. The variables of type EVENT appear to have Boolean (i.e. two state) values of true, false; up, down; on, off; and so on. Release 1.1 Page 35 of 41 9. When called, WAIT_FOR_SCHEDULE causes the RTSE to hold the execution of the calling task until the conditions, as specified in any previous procedure SCHEDULE call(s), allow the task to be released. Each task that is scheduled for execution by the RTSE through a SCHEDULE call must have at least one instance of a call to WAIT_FOR_SCHEDULE. Normally it will appear immediately at the top of the task or immediately after a call to SCHEDULE; however, it can appear anywhere within the task. 10. When called, DESCHEDULE removes all scheduling conditions for the task and the task is executed as if no SCHEDULE had been called. If it is waiting for release, it is immediately released. 11. When called, TOGGLE changes the state of the TARGET_EVENT. 12. When called, SET changes the state of the TARGET_EVENT to the value associated with SET. 13. When called, RESET changes the state of the TARGET_EVENT to the value associated with RESET. 14. The functions "or" and "and" perform a logical operation on two events as defined in the table below: EVENT1 EVENT2 "or" "and" SET SET SET SET SET RESET SET RESET RESET SET SET RESET RESET RESET RESET RESET 3.12.4 Example of Use Appendix A contains an example procedure utilizing this proposed package. Release 1.1 Page 36 of 41 4.0 Deferred Items The following is a partial list of those subjects not addressed by this document. They are either now under consideration but were not yet in condition for inclusion, or are topics for future work. This is a "partial" list in the sense that other topics will emerge as work continues, especially as a result of the efforts of the advisory members. Storage Management Multiprogramming Distributed Processing Multilevel Security Rollback-checkpoint Recovery Performance Monitoring Garbage Collection Release 1.1 Page 37 of 41 5.0 Submission of Comments For submission of comments on this proposed Catalog of Interface Features and Options, we would appreciate them being sent via ARPANET/MILNET to the following address: ISI-ARTEWG-INTERFACE@Ada20.ISI.EDU If you do not have network access, please send the comments by mail to Dr. Charles W. McKay University of Houston at Clear Lake 2700 Bay Area Blvd. Box 447 Houston, TX 77058 Attn : ARTEWG comments For mail comments, it will assist us if you are able to send them on a 360K, 5-1/4 inch floppy diskette, under DOS (or MS-DOS) compatible format. But even if you are able to manage this, please do send us a paper copy to ensure their evaluation, in case of problems in reading the diskette. All comments will be sorted and processed electronically (of course) in order to speed their analysis. To aid this process you are requested to precede each comment with a three-line header, as follows: !section ... !version Release 1.1 !topic ... The section line includes the section and paragraph number, your name or affiliation (or both), and the date in ISO standard format (yy-mm-dd). The version line should contain the current release identifier (for example, "Release 1.1") in order to distinguish comments from future releases. The topic line should contain a one-line summary of the comment. This line is essential, and you are kindly asked to avoid such topics as "Typo" or "Editorial comment" which will not convey any information when viewed individually (such as in a table of contents). Thank you for your work and support. Release 1.1 Page 38 of 41 Appendix A The example program below closely implements the conditions for Shuttle second stage guidance to begin execution. Second stage occurs when the solid rocket boosters (SRB's) separate from the Orbiter and continues until main engine shutdown or a return to launch site (RTLS) abort is requested. At some point within the execution of the second stage guidance equations, the rate of calculation must change from once every two seconds to once every 3.125 seconds. To set up these conditions, two SCHEDULE calls are made within the second stage guidance routine (AS_2STG_GUID). Both request the RTSE to schedule the task to execute under different conditions and at different rates. This example demonstrates the need for the RTSE to be able to change the scheduling conditions based on differing conditions. with TASK_IDS, DYNAMIC_PRIORITIES, SCHEDULER, CALENDAR; use TASK_IDS, DYNAMIC_PRIORITIES, SCHEDULER, CALENDAR; procedure GUIDANCE_NAVIGATION_and_CONTROL is SRB_SEP_COMMAND : EVENT; TWO_MAIN_ENGINES_OUT : EVENT; MECO_CONFIRMED : EVENT; GUID_FINE_COUNTDOWN_INITIATE : EVENT; ABORT_REQUEST_IS_RTLS : EVENT; Hz_p5 : constant DURATION := 2.0; -- 0.5 Hz Hz_3p125 : constant DURATION := 0.32; -- 3.125 Hz AS_2STG_GUID_PRIO : PRIORITY := 2; -- Priority is 1 to 2 task AS_2STG_GUID; Release 1.1 Page 39 of 41 task body AS_2STG_GUID is begin -- initialize the events RESET( SRB_SEP_COMMAND ); RESET( TWO_MAIN_ENGINES_OUT ); RESET( MECO_CONFIRMED ); RESET( GUID_FINE_COUNTDOWN_INITIATE ); RESET( ABORT_REQUEST_IS_RTLS ); -- schedule statement for normal 2 second execution SCHEDULE( TASK_IDS.SELF, REPORT_OVERRUN => false, SCHEDULE_PRIORITY => AS_2STG_GUID_PRIO, INITIATION => (ON_EVENT, SRB_SEP_COMMAND), REPETITION => (REPEAT_EVERY, Hz_p5), COMPLETION => (UNTIL_EVENT, TWO_MAIN_ENGINES_OUT or MECO_CONFIRMED or ABORT_REQUEST_IS_RTLS) ); -- schedule statement for higher speed execution SCHEDULE( TASK_IDS.SELF, REPORT_OVERRUN => false, SCHEDULE_PRIORITY => AS_2STG_GUID_PRIO, INITIATION => (ON_EVENT, GUID_FINE_COUNTDOWN_INITIATE), REPETITION => (REPEAT_EVERY, Hz_p5), COMPLETION => (UNTIL_EVENT, TWO_MAIN_ENGINES_OUT or MECO_CONFIRMED or ABORT_REQUEST_IS_RTLS) ); -- the task now calls for a wait until the scheduling -- conditions are satisfied. WAIT_FOR_SCHEDULE; -- when one of the conditions for task release occur, -- then the task begins executing here. loop ... ... WAIT_FOR_SCHEDULE; -- this call is made here because we have a repetition -- request. ... end loop; end AS_2STG_GUID; Release 1.1 Page 40 of 41 begin -- the event SRB_SEP_COMMAND is set to indicate staging. SET( SRB_SEP_COMMAND ); -- this causes the AS_2STG_GUID task to be released at the -- first WAIT_FOR_SCHEDULE call outside the loop. -- at some point, the adaptive guidance logic determines the -- need for a higher rate guidance calculation and sets the -- appropriate event. SET( GUID_FINE_COUNTDOWN_INITIATE ); -- this causes the task AS_2STG_GUID to begin execution under -- control of the second SCHEDULE call. -- as the guidance continues, the end of second stage is -- detected and the terminating condition for AS_2STG_GUID -- is set. SET( TWO_MAIN_ENGINES_OUT ); -- or SET( MECO_CONFIRMED ); -- or the RTLS abort case is set SET( ABORT_REQUEST_IS_RTLS ); end GUIDANCE_NAVIGATION_and_CONTROL; Release 1.1 Page 41 of 41