Next: , Up: Components mapping rules


7.1.1 Data components mapping

7.1.1.1 Base type mapping

A subcomponent-free data component should contain a ARAO::data_type property in order to generate the corresponding Ada type. ARAO predefined types are : integer, float, null, string and boolean. Normal data components are mapped to the related Ada type, as seen in the following AADL example :

     
     data message
     properties
       ARAO::data_type => integer;
     end message;
     

is mapped to the following Ada95 code:

     
     type message is new Integer;
     
7.1.1.2 Composed type mapping

AADL data component implementations may contain others data subcomponents. In this case, the data component is mapped to an Ada record type.

As an example, the following AADL component implementation:

     
     data integer_type
     properties
       ARAO::data_type => integer;
     end integer_type;
     
     data structure
     end structure;
     
     data implementation structure.impl
     subcomponents
       d1 : data integer_type;
       d2 : data integer_type;
     end structure.impl;
     

is mapped to the following Ada code :

     
     type Integer_Type is new Integer;
     
     type Structure_Impl is
        record
       D1 : Integer_Type;
       D2 : Integer_Type;
        end record;
     
7.1.1.3 Protected type mapping

AADL protected data components must be declared in the same way composed types are, i.e. by encapsulating them within another AADL type declaration.

For each protected data components, a new type is declared which contains all data components (i.e. fields of the related composed type) plus a mutex object within a Ada record. As for composed types, all fields must be either a previously user-declared type or a ARAO base type. Accessors and building features for the type will be declared too, as for the data-owned procedures (“methods”) designated in the features part of the data component.

The generated code enforces access protection, and declare type's object-oriented procedures (“methods”, as defined by user), using the middleware mutexes. A “method” of a type must always has as features a requires data access on this data.

For example, the following AADL declaration :

     
     data internal_message
     properties
       ARAO::data_type => integer;
     end internal_message;
     
     data message
     subcomponents
       Field : data internal_message;
     features
       method : subprogram update;
     properties
       ARAO::Access_Control_Protocol => Protected_Access;
     end message;
     

would generate a code like this :

     
     package Partition is
     
        type Message is private;
     
        procedure Build
          (This : out Message);
     
        procedure Get_Data
          (This  : in Message;
           Value : out Internal_Message);
     
        procedure Set_Data
          (This  : in out Message;
           Value : in Internal_Message);
     
     private
     
        type Message is
           record
              Data  : Partition.Internal_Message;
              Mutex : PolyORB.Tasking.Mutexes.Mutex_Access;
           end record;
     
     end Partition;
     

and the update method which will be call by generated code is like this :

     
     procedure Update
       (This  : in out Message;
        Value : in Partition.Internal_Message) is
     begin
        PolyORB.Tasking.Mutexes.Enter (This.Mutex);
        Repository.Update (This, Value);
        PolyORB.Tasking.Mutexes.Leave (This.Mutex);
     end Update;
     

Where the procedures Enter and Leave are middleware mutexes' take and release procedures.

We define protected data type internal type as the components (usually only one) , excluding the mutex, which are embedded in a protected type as a subcomponent. The protected data type internal type could be either a protected type or a “normal” (non-protected) type. Eventually, all protected types can be decomposed in a set of basic types.

7.1.1.4 Accessor usage

Data accessors can be used by the user exactly as data-owned procedure are. In the current version, they are the only ones actually called by the PolyORB AADL runtime, contrary to the generated interfaces which are not called at all.

Protected type accessors include Set_X and Get_X Ada procedures, where X is the name of the Field which contains the real (internal) data type. Those procedures are access-protected, using the protected object's middleware mutex to ensure mutual exclusion. The Build procedure will ensure mutex initialization.

An example of safe usage of accessors is :

     
     -----------------------
     -- Concurrent_Update --
     -----------------------
     
     procedure Concurrent_Update (arg : in out Partition.Counter_Type)
     is
        Sum  : Partition.Integer_Type;
     begin
        --  data initialization
        Partition.Set_Field (Data, 0);
     
        for I in 0 .. 100 loop
           Partition.Increment (Data);
           Partition.Get_Field (Data, Sum);
           if Integer (Sum) = 100 then
              exit;
           end if;
        end loop;
     end Concurrent_Update;
     

relying on the following AADL declarations :

     
     data Integer_Type
     properties
       ARAO::data_type => integer;
     end Integer_Type;
     
     data Counter_Type
     features
       Increment : subprogram Increment;
     subcomponents
       field : data Integer_Type;
     properties
       Concurency_Control_Protocol => Protected_Access;
     end Counter_Type;
     
     subprogram Increment
     features
       this : requires data access Counter_Type;
     properties
       source_language => Ada95;
       source_name => "Repository";
     end Increment;
     
     subprogram Concurrent_Update
     features
       arg : requires data access Counter_Type;
     properties
       source_language => Ada95;
       source_name => "Repository";
     end Concurrent_Update;
     
     thread Task
     features
       sh_data : requires data access Counter_Type;
     properties
       Dispatch_Protocol => Periodic;
       Period => 1000 Ms;
     end Task;
     
     thread implementation Task.impl
     calls {
       sp1 : subprogram Concurrent_Update;
     };
     connections
       Cnx_Th_dat : data access sh_data -> sp1.arg;
     end Task.impl;
     
     process implementation global.impl
     subcomponents
       th1 : thread Task.impl;
       th2 : thread Task.impl;
       dat : data Counter_Type;
     connections
       Cnx_1 : data access dat -> th1.sh_data;
       Cnx_2 : data access dat -> th2.sh_data;
     end global.impl;

with the following package specification and body generated :

     
     package Partition is
     
        type Integer_Type is new Integer;
        type Counter_Type is private;
     
        procedure Build
          (This : out Partition.Integer_Type);
     
        procedure Get_Field
          (This  : in Message;
           Value : out Partition.Integer_Type);
     
        procedure Set_Field
          (This  : in out Message;
           Value : in Partition.Integer_Type);
     
        procedure Increment
          (This : in out Counter_Type);
     
     private
        type Counter_Type is
           record
              Field : Partition.Integer_Type;
              Mutex : PolyORB.Tasking.Mutexes.Mutex_Access;
           end record;
     
     end Partition;
     
     
     with Repository;
     
     package body Counter_Type_PKG is
     
        -----------
        -- Build --
        -----------
     
        procedure Build
          (This : out Message)
        is
        begin
           --  Initialize the middleware's mutex
           PolyORB.Tasking.Mutexes.Create (T.Mutex);
        end Build;
     
        ---------------
        -- Get_Field --
        ---------------
     
        procedure Get_Field
          (This  : in Counter_Type;
           Value : out Partition.Integer_Type)
        is
        begin
           PolyORB.Tasking.Mutexes.Enter (T.Mutex);
           Value := This.Field;
           PolyORB.Tasking.Mutexes.Leave (T.Mutex);
        end Get_Field;
     
        ---------------
        -- Set_Field --
        ---------------
     
        procedure Set_Field
          (This  : in out Counter_Type;
           Value : in Partition.Integer_Type)
        is
        begin
           PolyORB.Tasking.Mutexes.Enter (T.Mutex);
           This.Field := Value;
           PolyORB.Tasking.Mutexes.Leave (T.Mutex);
        end Set_Field;
     
        ---------------
        -- Increment --
        ---------------
     
        procedure Increment
          (This : in out Counter_Type)
        is
        begin
           PolyORB.Tasking.Mutexes.Enter (This.Mutex);
           Repository.Increment (This.Field);
           PolyORB.Tasking.Mutexes.Leave (This.Mutex);
        end Increment;
     
     end Counter_Type_PKG;
     

Note that the Set usage could had been replaced by an Initialization method of Counter_Type, and that the Get could had been replaced by a Test_Value method.

7.1.1.5 Middleware mapping

We have seen that in the translation phase, the AADL data components are mapped to Ada95 types. Since the communication between nodes is performed using the PolyORB tools, all data sent in a request must have the neutral type PolyORB.Any.Any. So, conversion functions from and to this neutral type must be generated. For a process named proc these conversion functions will be generated in the proc_Helpers package. Example:

     
     data message
     properties
       ARAO::data_type => integer;
     end message;
     

is a definition for an integer type, the conversion routines generated in proc_Helpers are:

     
     with Partition;
     with PolyORB.Any;
     
     package proc_helpers is
        --  TypeCode variable used to characterize an Any variable
     
        TC_message : PolyORB.Any.TypeCode.Object :=
           PolyORB.Any.TypeCode.TC_Alias;
     
        function From_Any (Item : in PolyORB.Any.Any) return Partition.message;
     
        function To_Any (Item : in Partition.message) return PolyORB.Any.Any;
     
     end proc_helpers;
     

Note that we use the Namespaces package created in the translation phase.

7.1.1.6 AADL Properties support

Available properties for data components can be found in SAE AS5506, in 5.1 page 50 and in Appendix A, pages 197-218.

Concurency_control_protocol Supported : None, Access_Protected
Not_Collocated Not Supported
Provided_Access Not Supported
Required_Access Not Supported
Source_Code_Size Not Supported
Source_Language Not Supported
Source_Name Not Supported
Source_Text Not Supported
Type_Source_Name Not Supported