2015-05-12 Robert Dewar <dewar@adacore.com>
[official-gcc.git] / gcc / ada / doc / gnat_rm / implementation_of_specific_ada_features.rst
blob5788929bedca7f025d315d5690d8f8d8958ca85b
1 .. _Implementation_of_Specific_Ada_Features:
3 ***************************************
4 Implementation of Specific Ada Features
5 ***************************************
7 This chapter describes the GNAT implementation of several Ada language
8 facilities.
10 .. _Machine_Code_Insertions:
12 Machine Code Insertions
13 =======================
15 .. index:: Machine Code insertions
17 Package `Machine_Code` provides machine code support as described
18 in the Ada Reference Manual in two separate forms:
20
21   Machine code statements, consisting of qualified expressions that
22   fit the requirements of RM section 13.8.
23
24   An intrinsic callable procedure, providing an alternative mechanism of
25   including machine instructions in a subprogram.
27 The two features are similar, and both are closely related to the mechanism
28 provided by the asm instruction in the GNU C compiler.  Full understanding
29 and use of the facilities in this package requires understanding the asm
30 instruction, see the section on Extended Asm in 
31 :title:`Using_the_GNU_Compiler_Collection_(GCC)`.
33 Calls to the function `Asm` and the procedure `Asm` have identical
34 semantic restrictions and effects as described below.  Both are provided so
35 that the procedure call can be used as a statement, and the function call
36 can be used to form a code_statement.
38 Consider this C `asm` instruction:
42      asm ("fsinx %1 %0" : "=f" (result) : "f" (angle));
43   
45 The equivalent can be written for GNAT as:
47 .. code-block:: ada
49   Asm ("fsinx %1 %0",
50        My_Float'Asm_Output ("=f", result),
51        My_Float'Asm_Input  ("f",  angle));
52   
54 The first argument to `Asm` is the assembler template, and is
55 identical to what is used in GNU C.  This string must be a static
56 expression.  The second argument is the output operand list.  It is
57 either a single `Asm_Output` attribute reference, or a list of such
58 references enclosed in parentheses (technically an array aggregate of
59 such references).
61 The `Asm_Output` attribute denotes a function that takes two
62 parameters.  The first is a string, the second is the name of a variable
63 of the type designated by the attribute prefix.  The first (string)
64 argument is required to be a static expression and designates the
65 constraint (see the section on Constraints in 
66 :title:`Using_the_GNU_Compiler_Collection_(GCC)`)
67 for the parameter; e.g., what kind of register is required.  The second
68 argument is the variable to be written or updated with the
69 result.  The possible values for constraint are the same as those used in
70 the RTL, and are dependent on the configuration file used to build the
71 GCC back end.  If there are no output operands, then this argument may
72 either be omitted, or explicitly given as `No_Output_Operands`.
73 No support is provided for GNU C's symbolic names for output parameters.
75 The second argument of ``my_float'Asm_Output`` functions as
76 though it were an `out` parameter, which is a little curious, but
77 all names have the form of expressions, so there is no syntactic
78 irregularity, even though normally functions would not be permitted
79 `out` parameters.  The third argument is the list of input
80 operands.  It is either a single `Asm_Input` attribute reference, or
81 a list of such references enclosed in parentheses (technically an array
82 aggregate of such references).
84 The `Asm_Input` attribute denotes a function that takes two
85 parameters.  The first is a string, the second is an expression of the
86 type designated by the prefix.  The first (string) argument is required
87 to be a static expression, and is the constraint for the parameter,
88 (e.g., what kind of register is required).  The second argument is the
89 value to be used as the input argument.  The possible values for the
90 constraint are the same as those used in the RTL, and are dependent on
91 the configuration file used to built the GCC back end.
92 No support is provided for GNU C's symbolic names for input parameters.
94 If there are no input operands, this argument may either be omitted, or
95 explicitly given as `No_Input_Operands`.  The fourth argument, not
96 present in the above example, is a list of register names, called the
97 *clobber* argument.  This argument, if given, must be a static string
98 expression, and is a space or comma separated list of names of registers
99 that must be considered destroyed as a result of the `Asm` call.  If
100 this argument is the null string (the default value), then the code
101 generator assumes that no additional registers are destroyed.
102 In addition to registers, the special clobbers `memory` and
103 `cc` as described in the GNU C docs are both supported.
105 The fifth argument, not present in the above example, called the
106 *volatile* argument, is by default `False`.  It can be set to
107 the literal value `True` to indicate to the code generator that all
108 optimizations with respect to the instruction specified should be
109 suppressed, and in particular an instruction that has outputs
110 will still be generated, even if none of the outputs are
111 used.  See :title:`Using_the_GNU_Compiler_Collection_(GCC)`
112 for the full description.
113 Generally it is strongly advisable to use Volatile for any ASM statement
114 that is missing either input or output operands or to avoid unwanted
115 optimizations. A warning is generated if this advice is not followed.
117 No support is provided for GNU C's `asm goto` feature.
119 The `Asm` subprograms may be used in two ways.  First the procedure
120 forms can be used anywhere a procedure call would be valid, and
121 correspond to what the RM calls 'intrinsic' routines.  Such calls can
122 be used to intersperse machine instructions with other Ada statements.
123 Second, the function forms, which return a dummy value of the limited
124 private type `Asm_Insn`, can be used in code statements, and indeed
125 this is the only context where such calls are allowed.  Code statements
126 appear as aggregates of the form:
128 .. code-block:: ada
130   Asm_Insn'(Asm (...));
131   Asm_Insn'(Asm_Volatile (...));
132   
133 In accordance with RM rules, such code statements are allowed only
134 within subprograms whose entire body consists of such statements.  It is
135 not permissible to intermix such statements with other Ada statements.
137 Typically the form using intrinsic procedure calls is more convenient
138 and more flexible.  The code statement form is provided to meet the RM
139 suggestion that such a facility should be made available.  The following
140 is the exact syntax of the call to `Asm`. As usual, if named notation
141 is used, the arguments may be given in arbitrary order, following the
142 normal rules for use of positional and named arguments:
146   ASM_CALL ::= Asm (
147                    [Template =>] static_string_EXPRESSION
148                  [,[Outputs  =>] OUTPUT_OPERAND_LIST      ]
149                  [,[Inputs   =>] INPUT_OPERAND_LIST       ]
150                  [,[Clobber  =>] static_string_EXPRESSION ]
151                  [,[Volatile =>] static_boolean_EXPRESSION] )
153   OUTPUT_OPERAND_LIST ::=
154     [PREFIX.]No_Output_Operands
155   | OUTPUT_OPERAND_ATTRIBUTE
156   | (OUTPUT_OPERAND_ATTRIBUTE {,OUTPUT_OPERAND_ATTRIBUTE})
158   OUTPUT_OPERAND_ATTRIBUTE ::=
159     SUBTYPE_MARK'Asm_Output (static_string_EXPRESSION, NAME)
161   INPUT_OPERAND_LIST ::=
162     [PREFIX.]No_Input_Operands
163   | INPUT_OPERAND_ATTRIBUTE
164   | (INPUT_OPERAND_ATTRIBUTE {,INPUT_OPERAND_ATTRIBUTE})
166   INPUT_OPERAND_ATTRIBUTE ::=
167     SUBTYPE_MARK'Asm_Input (static_string_EXPRESSION, EXPRESSION)
168   
169 The identifiers `No_Input_Operands` and `No_Output_Operands`
170 are declared in the package `Machine_Code` and must be referenced
171 according to normal visibility rules. In particular if there is no
172 `use` clause for this package, then appropriate package name
173 qualification is required.
175 .. _GNAT_Implementation_of_Tasking:
177 GNAT Implementation of Tasking
178 ==============================
180 This chapter outlines the basic GNAT approach to tasking (in particular,
181 a multi-layered library for portability) and discusses issues related
182 to compliance with the Real-Time Systems Annex.
184 .. _Mapping_Ada_Tasks_onto_the_Underlying_Kernel_Threads:
186 Mapping Ada Tasks onto the Underlying Kernel Threads
187 ----------------------------------------------------
189 GNAT's run-time support comprises two layers:
191 * GNARL (GNAT Run-time Layer)
192 * GNULL (GNAT Low-level Library)
194 In GNAT, Ada's tasking services rely on a platform and OS independent
195 layer known as GNARL.  This code is responsible for implementing the
196 correct semantics of Ada's task creation, rendezvous, protected
197 operations etc.
199 GNARL decomposes Ada's tasking semantics into simpler lower level
200 operations such as create a thread, set the priority of a thread,
201 yield, create a lock, lock/unlock, etc.  The spec for these low-level
202 operations constitutes GNULLI, the GNULL Interface.  This interface is
203 directly inspired from the POSIX real-time API.
205 If the underlying executive or OS implements the POSIX standard
206 faithfully, the GNULL Interface maps as is to the services offered by
207 the underlying kernel.  Otherwise, some target dependent glue code maps
208 the services offered by the underlying kernel to the semantics expected
209 by GNARL.
211 Whatever the underlying OS (VxWorks, UNIX, Windows, etc.) the
212 key point is that each Ada task is mapped on a thread in the underlying
213 kernel.  For example, in the case of VxWorks, one Ada task = one VxWorks task.
215 In addition Ada task priorities map onto the underlying thread priorities.
216 Mapping Ada tasks onto the underlying kernel threads has several advantages:
219   The underlying scheduler is used to schedule the Ada tasks.  This
220   makes Ada tasks as efficient as kernel threads from a scheduling
221   standpoint.
224   Interaction with code written in C containing threads is eased
225   since at the lowest level Ada tasks and C threads map onto the same
226   underlying kernel concept.
229   When an Ada task is blocked during I/O the remaining Ada tasks are
230   able to proceed.
233   On multiprocessor systems Ada tasks can execute in parallel.
235 Some threads libraries offer a mechanism to fork a new process, with the
236 child process duplicating the threads from the parent.
237 GNAT does not
238 support this functionality when the parent contains more than one task.
239 .. index:: Forking a new process
241 .. _Ensuring_Compliance_with_the_Real-Time_Annex:
243 Ensuring Compliance with the Real-Time Annex
244 --------------------------------------------
246 .. index:: Real-Time Systems Annex compliance
248 Although mapping Ada tasks onto
249 the underlying threads has significant advantages, it does create some
250 complications when it comes to respecting the scheduling semantics
251 specified in the real-time annex (Annex D).
253 For instance the Annex D requirement for the `FIFO_Within_Priorities`
254 scheduling policy states:
256   *When the active priority of a ready task that is not running
257   changes, or the setting of its base priority takes effect, the
258   task is removed from the ready queue for its old active priority
259   and is added at the tail of the ready queue for its new active
260   priority, except in the case where the active priority is lowered
261   due to the loss of inherited priority, in which case the task is
262   added at the head of the ready queue for its new active priority.*
264 While most kernels do put tasks at the end of the priority queue when
265 a task changes its priority, (which respects the main
266 FIFO_Within_Priorities requirement), almost none keep a thread at the
267 beginning of its priority queue when its priority drops from the loss
268 of inherited priority.
270 As a result most vendors have provided incomplete Annex D implementations.
272 The GNAT run-time, has a nice cooperative solution to this problem
273 which ensures that accurate FIFO_Within_Priorities semantics are
274 respected.
276 The principle is as follows.  When an Ada task T is about to start
277 running, it checks whether some other Ada task R with the same
278 priority as T has been suspended due to the loss of priority
279 inheritance.  If this is the case, T yields and is placed at the end of
280 its priority queue.  When R arrives at the front of the queue it
281 executes.
283 Note that this simple scheme preserves the relative order of the tasks
284 that were ready to execute in the priority queue where R has been
285 placed at the end.
287 .. _GNAT_Implementation_of_Shared_Passive_Packages:
289 GNAT Implementation of Shared Passive Packages
290 ==============================================
292 .. index:: Shared passive packages
294 GNAT fully implements the pragma `Shared_Passive` for
295 .. index:: pragma `Shared_Passive`
297 the purpose of designating shared passive packages.
298 This allows the use of passive partitions in the
299 context described in the Ada Reference Manual; i.e., for communication
300 between separate partitions of a distributed application using the
301 features in Annex E.
302 .. index:: Annex E
304 .. index:: Distribution Systems Annex
306 However, the implementation approach used by GNAT provides for more
307 extensive usage as follows:
309 *Communication between separate programs*
310   This allows separate programs to access the data in passive
311   partitions, using protected objects for synchronization where
312   needed. The only requirement is that the two programs have a
313   common shared file system. It is even possible for programs
314   running on different machines with different architectures
315   (e.g., different endianness) to communicate via the data in
316   a passive partition.
318 *Persistence between program runs*
319   The data in a passive package can persist from one run of a
320   program to another, so that a later program sees the final
321   values stored by a previous run of the same program.
323 The implementation approach used is to store the data in files. A
324 separate stream file is created for each object in the package, and
325 an access to an object causes the corresponding file to be read or
326 written.
328 .. index:: SHARED_MEMORY_DIRECTORY environment variable
330 The environment variable `SHARED_MEMORY_DIRECTORY` should be
331 set to the directory to be used for these files.
332 The files in this directory
333 have names that correspond to their fully qualified names. For
334 example, if we have the package
336 .. code-block:: ada
338   package X is
339     pragma Shared_Passive (X);
340     Y : Integer;
341     Z : Float;
342   end X;
344 and the environment variable is set to `/stemp/`, then the files created
345 will have the names:
349   /stemp/x.y
350   /stemp/x.z
351   
353 These files are created when a value is initially written to the object, and
354 the files are retained until manually deleted. This provides the persistence
355 semantics. If no file exists, it means that no partition has assigned a value
356 to the variable; in this case the initial value declared in the package
357 will be used. This model ensures that there are no issues in synchronizing
358 the elaboration process, since elaboration of passive packages elaborates the
359 initial values, but does not create the files.
361 The files are written using normal `Stream_IO` access.
362 If you want to be able
363 to communicate between programs or partitions running on different
364 architectures, then you should use the XDR versions of the stream attribute
365 routines, since these are architecture independent.
367 If active synchronization is required for access to the variables in the
368 shared passive package, then as described in the Ada Reference Manual, the
369 package may contain protected objects used for this purpose. In this case
370 a lock file (whose name is :file:`___lock` (three underscores)
371 is created in the shared memory directory.
373 .. index:: ___lock file (for shared passive packages)
375 This is used to provide the required locking
376 semantics for proper protected object synchronization.
378 GNAT supports shared passive packages on all platforms
379 except for OpenVMS.
381 .. _Code_Generation_for_Array_Aggregates:
383 Code Generation for Array Aggregates
384 ====================================
386 Aggregates have a rich syntax and allow the user to specify the values of
387 complex data structures by means of a single construct.  As a result, the
388 code generated for aggregates can be quite complex and involve loops, case
389 statements and multiple assignments.  In the simplest cases, however, the
390 compiler will recognize aggregates whose components and constraints are
391 fully static, and in those cases the compiler will generate little or no
392 executable code.  The following is an outline of the code that GNAT generates
393 for various aggregate constructs.  For further details, you will find it
394 useful to examine the output produced by the -gnatG flag to see the expanded
395 source that is input to the code generator.  You may also want to examine
396 the assembly code generated at various levels of optimization.
398 The code generated for aggregates depends on the context, the component values,
399 and the type.  In the context of an object declaration the code generated is
400 generally simpler than in the case of an assignment.  As a general rule, static
401 component values and static subtypes also lead to simpler code.
403 .. _Static_constant_aggregates_with_static_bounds:
405 Static constant aggregates with static bounds
406 ---------------------------------------------
408 For the declarations:
410 .. code-block:: ada
412       type One_Dim is array (1..10) of integer;
413       ar0 : constant One_Dim := (1, 2, 3, 4, 5, 6, 7, 8, 9, 0);
414   
416 GNAT generates no executable code: the constant ar0 is placed in static memory.
417 The same is true for constant aggregates with named associations:
420 .. code-block:: ada
422       Cr1 : constant One_Dim := (4 => 16, 2 => 4, 3 => 9, 1 => 1, 5 .. 10 => 0);
423       Cr3 : constant One_Dim := (others => 7777);
424   
426 The same is true for multidimensional constant arrays such as:
428 .. code-block:: ada
430       type two_dim is array (1..3, 1..3) of integer;
431       Unit : constant two_dim := ( (1,0,0), (0,1,0), (0,0,1));
432   
434 The same is true for arrays of one-dimensional arrays: the following are
435 static:
438 .. code-block:: ada
440   type ar1b  is array (1..3) of boolean;
441   type ar_ar is array (1..3) of ar1b;
442   None  : constant ar1b := (others => false);     --  fully static
443   None2 : constant ar_ar := (1..3 => None);       --  fully static
444   
446 However, for multidimensional aggregates with named associations, GNAT will
447 generate assignments and loops, even if all associations are static.  The
448 following two declarations generate a loop for the first dimension, and
449 individual component assignments for the second dimension:
452 .. code-block:: ada
454   Zero1: constant two_dim := (1..3 => (1..3 => 0));
455   Zero2: constant two_dim := (others => (others => 0));
456   
458 .. _Constant_aggregates_with_unconstrained_nominal_types:
460 Constant aggregates with unconstrained nominal types
461 ----------------------------------------------------
463 In such cases the aggregate itself establishes the subtype, so that
464 associations with `others` cannot be used.  GNAT determines the
465 bounds for the actual subtype of the aggregate, and allocates the
466 aggregate statically as well.  No code is generated for the following:
469 .. code-block:: ada
471       type One_Unc is array (natural range <>) of integer;
472       Cr_Unc : constant One_Unc := (12,24,36);
473   
475 .. _Aggregates_with_static_bounds:
477 Aggregates with static bounds
478 -----------------------------
480 In all previous examples the aggregate was the initial (and immutable) value
481 of a constant.  If the aggregate initializes a variable, then code is generated
482 for it as a combination of individual assignments and loops over the target
483 object.  The declarations
486 .. code-block:: ada
488          Cr_Var1 : One_Dim := (2, 5, 7, 11, 0, 0, 0, 0, 0, 0);
489          Cr_Var2 : One_Dim := (others > -1);
490   
492 generate the equivalent of
495 .. code-block:: ada
497          Cr_Var1 (1) := 2;
498          Cr_Var1 (2) := 3;
499          Cr_Var1 (3) := 5;
500          Cr_Var1 (4) := 11;
502          for I in Cr_Var2'range loop
503             Cr_Var2 (I) := -1;
504          end loop;
505   
507 .. _Aggregates_with_non-static_bounds:
509 Aggregates with non-static bounds
510 ---------------------------------
512 If the bounds of the aggregate are not statically compatible with the bounds
513 of the nominal subtype  of the target, then constraint checks have to be
514 generated on the bounds.  For a multidimensional array, constraint checks may
515 have to be applied to sub-arrays individually, if they do not have statically
516 compatible subtypes.
518 .. _Aggregates_in_assignment_statements:
520 Aggregates in assignment statements
521 -----------------------------------
523 In general, aggregate assignment requires the construction of a temporary,
524 and a copy from the temporary to the target of the assignment.  This is because
525 it is not always possible to convert the assignment into a series of individual
526 component assignments.  For example, consider the simple case:
529 .. code-block:: ada
531           A := (A(2), A(1));
532   
534 This cannot be converted into:
537 .. code-block:: ada
539           A(1) := A(2);
540           A(2) := A(1);
541   
543 So the aggregate has to be built first in a separate location, and then
544 copied into the target.  GNAT recognizes simple cases where this intermediate
545 step is not required, and the assignments can be performed in place, directly
546 into the target.  The following sufficient criteria are applied:
549   The bounds of the aggregate are static, and the associations are static.
551   The components of the aggregate are static constants, names of
552   simple variables that are not renamings, or expressions not involving
553   indexed components whose operands obey these rules.
555 If any of these conditions are violated, the aggregate will be built in
556 a temporary (created either by the front-end or the code generator) and then
557 that temporary will be copied onto the target.
559 .. _The_Size_of_Discriminated_Records_with_Default_Discriminants:
561 The Size of Discriminated Records with Default Discriminants
562 ============================================================
564 If a discriminated type `T` has discriminants with default values, it is
565 possible to declare an object of this type without providing an explicit
566 constraint:
569 .. code-block:: ada
571   type Size is range 1..100;
573   type Rec (D : Size := 15) is record
574      Name : String (1..D);
575   end T;
577   Word : Rec;
578   
580 Such an object is said to be *unconstrained*.
581 The discriminant of the object
582 can be modified by a full assignment to the object, as long as it preserves the
583 relation between the value of the discriminant, and the value of the components
584 that depend on it:
587 .. code-block:: ada
589   Word := (3, "yes");
591   Word := (5, "maybe");
593   Word := (5, "no"); -- raises Constraint_Error
595 In order to support this behavior efficiently, an unconstrained object is
596 given the maximum size that any value of the type requires. In the case
597 above, `Word` has storage for the discriminant and for
598 a `String` of length 100.
599 It is important to note that unconstrained objects do not require dynamic
600 allocation. It would be an improper implementation to place on the heap those
601 components whose size depends on discriminants. (This improper implementation
602 was used by some Ada83 compilers, where the `Name` component above
603 would have
604 been stored as a pointer to a dynamic string). Following the principle that
605 dynamic storage management should never be introduced implicitly,
606 an Ada compiler should reserve the full size for an unconstrained declared
607 object, and place it on the stack.
609 This maximum size approach
610 has been a source of surprise to some users, who expect the default
611 values of the discriminants to determine the size reserved for an
612 unconstrained object: "If the default is 15, why should the object occupy
613 a larger size?"
614 The answer, of course, is that the discriminant may be later modified,
615 and its full range of values must be taken into account. This is why the
616 declaration:
619 .. code-block:: ada
621   type Rec (D : Positive := 15) is record
622      Name : String (1..D);
623   end record;
625   Too_Large : Rec;
627 is flagged by the compiler with a warning:
628 an attempt to create `Too_Large` will raise `Storage_Error`,
629 because the required size includes `Positive'Last`
630 bytes. As the first example indicates, the proper approach is to declare an
631 index type of 'reasonable' range so that unconstrained objects are not too
632 large.
634 One final wrinkle: if the object is declared to be `aliased`, or if it is
635 created in the heap by means of an allocator, then it is *not*
636 unconstrained:
637 it is constrained by the default values of the discriminants, and those values
638 cannot be modified by full assignment. This is because in the presence of
639 aliasing all views of the object (which may be manipulated by different tasks,
640 say) must be consistent, so it is imperative that the object, once created,
641 remain invariant.
643 .. _Strict_Conformance_to_the_Ada_Reference_Manual:
645 Strict Conformance to the Ada Reference Manual
646 ==============================================
648 The dynamic semantics defined by the Ada Reference Manual impose a set of
649 run-time checks to be generated. By default, the GNAT compiler will insert many
650 run-time checks into the compiled code, including most of those required by the
651 Ada Reference Manual. However, there are three checks that are not enabled
652 in the default mode for efficiency reasons: arithmetic overflow checking for
653 integer operations (including division by zero), checks for access before
654 elaboration on subprogram calls, and stack overflow checking (most operating
655 systems do not perform this check by default).
657 Strict conformance to the Ada Reference Manual can be achieved by adding
658 three compiler options for overflow checking for integer operations
659 (*-gnato*), dynamic checks for access-before-elaboration on subprogram
660 calls and generic instantiations (*-gnatE*), and stack overflow
661 checking (*-fstack-check*).
663 Note that the result of a floating point arithmetic operation in overflow and
664 invalid situations, when the `Machine_Overflows` attribute of the result
665 type is `False`, is to generate IEEE NaN and infinite values. This is the
666 case for machines compliant with the IEEE floating-point standard, but on
667 machines that are not fully compliant with this standard, such as Alpha, the
668 *-mieee* compiler flag must be used for achieving IEEE confirming
669 behavior (although at the cost of a significant performance penalty), so
670 infinite and NaN values are properly generated.