Next: , Previous: Data components mapping, Up: Components mapping rules


7.1.2 Subprogram components mapping

AADL subprograms are mapped to Ada procedures. In case of data-owned subprograms, they are managed in the related generated package, as seen in Data components mapping. The parameters of the procedure are mapped from the subprogram features with respect to the following rules:

The body of the mapped procedure depend on the nature of the subprogram component. Subprogram components can be classified in many kind depending on the value of the Source_Language, Source_Name and Source_Text standard AADL properties and the existence or not of call sequences in the subprogram implementation. There are four kinds of subprogram components:

  1. The empty subprograms.
  2. The opaque subprograms.
  3. The pure call sequence subprograms.
  4. The hybrid subprograms.
7.1.2.1 Mapping of empty subprograms

Empty subprograms correspond to subprograms for which there is neither Source_Language nor Source_Name nor Source_Text values nor call sequences. Such kind of subprogram components has no particular utility. For example:

     
     subprogram sp
     features
       e : in parameter message;
       s : out parameter message;
     end sp;
     

is en empty subprogram. A possible Ada implementation for this subprogram could be:

     
     procedure sp (e : in message; s : out message) is
       NYI : exception;
     begin
       raise NYI;
     end sp;
     
7.1.2.2 Mapping of opaque subprograms

Opaque subprograms are the simplest “useful” subprogram components (in code generation point of view). For these subprograms, the Source_Language property indicates the programming language of the implementation (C or Ada95). The Source_Name property indicates the name of the subprogram implementing the subprogram:

In this case, the code generation consist of creating a shell for the implementation code. In the case of Ada subprograms, the generated subprogram renames the implementation subprogram (using the Ada95 renaming facility). Example:

     
     subprogram sp
     features
       e : in  parameter message;
       s : out parameter message;
     end sp;
     
     subprogram implementation sp.impl
     properties
       Source_Language => Ada95;
       Source_Name     => "Repository.Sp_Impl";
     end sp.impl;
     

The generated code for the sp.impl component is:

     
     with Repository;
     ...
     procedure sp_impl (e : in message; s : out message)
       renames Repository.Sp_Impl;
     

The code of the Repository.sp_impl procedure is provided by the architecture and must be conform with the sp.impl signature. The coherence between the two subprograms will be verified by the Ada95 compiler.

The fact that the hand-written code is not inserted in the generated shell allows this code to be written in a programming language other than Ada95. Thus, if the implementation code is C we have this situation:

     
     subprogram sp
     features
       e : in parameter message;
       s : out parameter message;
     end sp;
     
     subprogram implementation sp.impl
     properties
       Source_Language => C;
       Source_Name     => "implem";
     end sp.impl;
     

The Source_Name value is interpreted as the name of the C subprogram implementing the AADL subprogram. The generated code for the sp.impl component is:

     
     procedure sp_impl (e : in message; s : out message);
     pragma Import (C, sp_impl, "implem");
     

This approach will allow us to have a certain flexibility by separating the generated code and the hand-written code. We can modify the AADL description without affecting the hand-written code (the signature should not be modified of course).

7.1.2.3 Mapping of pure call sequence subprograms

In addition to the opaque approach which consist of delegating all the subprogram body writing to the user, AADL allows to model subprogram as a pure call sequence to other subprograms. Example:

     
     subprogram spA
     features
       s : out parameter message;
     end spA;
     
     subprogram spB
     features
       s : out parameter message;
     end spA;
     
     subprogram spC
     features
       e : in  parameter message;
       s : out parameter message;
     end spA;
     
     subprogram spA.impl
     calls {
       call1 : subprogram spB;
       call2 : subprogram spC;};
     connections
       cnx1 : parameter call1.s -> call2.e;
       cnx2 : parameter call2.s -> s;
     end spA.impl;
     

In this case, the subprogram connects together a number of other subprograms. In addition to the call sequence, the connections clause completes the description by specifying the connections between parameters. The pure sequence call model allows to generate complete code : the calls in the call sequence corresponds to Ada95 procedure calls and the connections between parameters correspond to eventual intermediary variables. The Ada95 code generated for the subprogram spA.impl is:

     
     procedure spA_impl (s : out message) is
        cnx1 : message;
     begin
        spB (cnx1);
        spC (cnx1, s);
     end spA_impl;
     

Note that in case of pure call sequence subprograms, the AADL subprogram must contain only one call sequence. If there are more than one call sequence, it's impossible - in this case - to determine the relation between them.

7.1.2.4 Mapping of hybrid subprograms

The two last kinds of subprogram components describe even an opaque implementation for which all the functional part is written by the user or a pure call sequence for which all the functional part is given by the AADL description. These two cases are relatively simple to implement. However, they don't offer much flexibility. In the general case we want to integrate the maximum of information within the AADL description in order to get an easy assembling of the distributed application components. However, AADL does not provide control structures (conditions, loops). The best way is to combine the opaque model and the pure call sequence model.

To illustrate the problem, let's consider the following example: A subprogram spA receives an input integer value . The subprogram behavior depends on the a value:

In all cases, the return value of spB is given to a forth subprogram spD; the return value of spD is returned by spA.

The behavior of spA is illustrated by this algorithm:

     
     if a < 4 then
       b <- spB (a)
     else
       c <- spC ()
       b <- spB (c)
     end if
     
     d <- spD (b)
     return d
     

We assume that the subprograms spB, spC and spD are correctly defined.

We have three call sequences. AADL allows only to describe the architectural aspects of the algorithm (the connections between the different subprograms). The AADL source corresponding to the last example is:

     
     data int
     properties
       GAIA::Data_Type => Integer;
     end int;
     
     subprogram spA
     features
       a : in parameter int;
       d : out parameter int;
     end spA;
     
     subprogram spB
     features
       e : in parameter int;
       s : out parameter int;
     end spB;
     
     subprogram spC
     features
       s : out parameter int;
     end spC;
     
     subprogram spD
     features
       e : in parameter int;
       s : out parameter int;
     end spD;
     
     subprogram implementation spA.impl
     properties
       Source_Language => Ada95;
       Source_Name     => "Repository.SpA_Impl"
     calls
       seq1 : {spB1 : subprogram spB;};
       seq2 : {spC2 : subprogram spC;
               spB2 : subprogram spB;};
       seq3 : {spD3 : subprogram spD;};
     connections
       cnx1 : parameter a -> apB1.e;
       cnx2 : parameter spB1.s -> spD3.e;
     
       cnx3 : parameter spC2.s -> spB2.e;
       cnx4 : parameter spB2.s -> spD3.e;
     
       cnx5 : parameter spd3.s -> d;
     end spA.impl;
     

The first remark is that the subprogram implementation contains at the same time the Source_[Language|Name] (and a possible Source_Text) properties and call sequences. The hand-written code describes the algorithm. This algorithm should be able to handle each call sequence as being a block and must be as simple as possible: the user should not know the content of the call sequence.

The generated code for each block (call sequence) is almost identical to the generated code for pure call sequence. For each block, a subprogram is generated. To make things simple for the user, these subprograms have the same signature (one parameter called Status):

     
     type SpA_Impl_Status is record
       a, b, c, d : int;
     end record;
     
     procedure SpA_Seq1 (in out Status : spA_impl_Status) is
     begin
        spB (Status.a, Status.b);
     end SpA_Seq1;
     
     procedure SpA_Seq2 (in out Status : spA_impl_Status) is
     begin
        spC (Status.c);
        spB (Status.c, Status.b);
     end SpA_Seq2;
     
     procedure SpA_Seq3 (in out Status : spA_impl_Status) is
     begin
        spD (Status.b, d);
     end SpA_Seq3;
     

The generated code for the spA.impl subprogram is very simple:

     
     procedure SpA_Impl (a : in int; d : out int) is
        Status : spA_impl_Status;
     begin
        Status.a := a;
        Repository.SpA_Impl
          (Status,
           SpA_Seq1'Access,
           SpA_Seq2'Access,
           SpA_Seq3'Access);
        d := Status.d;
     end SpA_Impl;
     

The subprogram which describes the algorithm and which should be written by the user is relatively simple, and does not require any knowledge of the call sequences contents:

     
     type SpA_Impl_Call_Sequence is access
       procedure (in out Status : spA_impl_Status);
     
     procedure SpA_Impl
       (Status : in out spA_impl_Status,
        seq1   : spA_impl_Call_Sequence,
        seq2   : spA_impl_Call_Sequence,
        seq3   : spA_impl_Call_Sequence)
     is
     begin
        if Status.a > 4 then
           seq1.all (Status);
        else
           seq2.all (Status);
        end if;
        seq3.all (Status);
     end SpA_Impl;
     
7.1.2.5 Data access

If a subprogram has a requires access feature to a data, this data is added to the parameters list, with the mode corresponding to data access rights (i.e. read-only => in, write-only => out and read-write => in out).

In the specific case of subprograms requiring protected data access, user should provides different data depending on subprograms' nature.

If the subprogram is a “method” of the protected object (i.e. if it appears in its features field), then the user should provides an implementation of the subprogram which take the subprogram access as the first parameter, with the mode chosen following the rule described above. The parameter's name must always be this. This parameter type must always be of the protected data type internal type (cf. Data components mapping).

If the subprogram is a not “method” of the protected object, user work depends of the accessed data's Actual_Lock_Implementation property, which defines shared variables update policy. This policy could be either synchronous (synchronous_lock) or asynchronous (asynchronous_lock). Default is asynchronous update policy.

The user must write a subprogram implementation complying to the following rules :

Note that accessed data (found in the subprogram component's features field) must always be parsed in the same order they are declared in the AADL specification. In any case, mode is still chosen accordingly to the rule describe above.

Note that only opaque subprograms currently support synchronous data update policy.

If synchronous policy is chosen for a data update policy, the user should be aware that access protection is ensured by the runtime code (cf. Thread components mapping).

Here is an example of data-owned specification of a protected object :

     
     data internal_data
     properties
       ARAO::data_type => integer;
     end internal_data;
     
     data shared_data
     features
       method : subprogram update;
     properties
       Concurrency_Control_Protocol => Protected_Access;
       ARAO::Actual_Lock_Implementation => Synchronous_Lock;
     end shared_data;
     
     data implementation shared_data.i
     subcomponents
       Field : data internal_data;
     end shared_data.i;
     
     --  subprograms
     
     subprogram update
     features
       this : requires data access shared_data.i;
     properties
       source_language => Ada95;
       source_name => "Repository";
     end update;
     

The user provides :

     
       procedure Update (Field : in out Partition.Internal_Data;
                         I : in Partition.message);
     
        ------------
        -- Update --
        ------------
     
        procedure Update (Field : in out Partition.Internal_Data;
                          I : in Partition.message)
        is
           use Partition;
        begin
           Field := Partition.Internal_Data (Integer (Field) + Integer (I));
        end Update;
     

And Gaia will generate the following implementation for the access-protected subprogram :

     
     ------------
     -- update --
     ------------
     
     procedure Update
       (This : in out Partition.Shared_Data_I;
        I : Partition.Message)
     is
     begin
        PolyORB.Tasking.Mutexes.Enter
          (This.Mutex);
        Repository.Update
          (Field => This.Field,
           I => I);
        PolyORB.Tasking.Mutexes.Leave
          (This.Mutex);
     end Update;
     
7.1.2.6 AADL Properties support

Available properties for subprogram components can be found in SAE AS5506, in 5.2 page 56 and in Appendix A, pages 197-218.

Actual_Memory_Binding Not Supported
Actual_Subprogram_Call Not Supported
Client_Subprogram_Execution_Time Not Supported
Compute_Deadline Not Supported
Compute_Execution_Time Not Supported
Concurrency_Control_Protocol Not Supported
Queue_Processing_Protocol Not Supported
Queue_Size Not Supported
Recover_Deadline Not Supported
Recover_Execution_Time Not Supported
Server_Subprogram_Call_Binding Not Supported
Source_Code_Size Not Supported
Source_Data_Size Not Supported
Source_Heap_Size Not Supported
Source_Stack_Size Not Supported
Source_Language Supported (Ada)
Source_Name Supported
Source_Text Supported