Next: Process components mapping, Previous: Subprogram components mapping, Up: Components mapping rules
The mapping of thread components is a little bit more complicated than the mapping of data components. Threads are mapped to an Ada95 parameter-less procedure which executes the thread work (periodically or aperiodically depending on the thread nature). For each periodic thread, a middleware thread is created using the API described in Description of the ARAO API. For example~:
thread sender features msg_out : out event data port message; properties Dispatch_Protocol => Periodic; Period => 1000 Ms; end sender;
If this thread belongs to a process proc
, and if th1
is the
name of the thread subcomponent of proc
having the type
sender
, then a package proc_Servants
is created:
package proc_Servants is ... procedure th1_Ctrler; ... end proc_Servants;
In the main subprogram proc
we find:
Aadl_Periodic_Threads.Create_Periodic_Thread (TP => sn_Servants.th1_Ctrler'Access);
The thread “in” or “in out” ports are mapped in an Ada protected object which allows a protected access to these ports. For each port, a buffer having the port stack size is created, implemented with a cyclic array. Since these ports are the destination of other components requests, for each in port, a PolyORB Reference is created and for each thread containing in ports, a servant is created to handle the incoming requests; Example:
thread receiver features msg_in : in event data port message; end receiver;
If this thread belongs to a process proc
, and if th2
is the
name of the thread subcomponent of proc
having the type
receiver
, then the following declarations will be generated in the
proc_Servants
package spec:
with Partition; with PolyORB.Components; with PolyORB.Servants; with PolyORB.References; package proc_Servants is ... procedure th2_Ctrler; type th2_Object is new Servant with null record; th2_Ref : PolyORB.References.Ref; function Execute_Servant (Obj : access th2_Object; Msg : PolyORB.Components.Message'Class) return PolyORB.Components.Message'Class; type th2_msg_in_buf_type is array (1 .. 1) of Partition.message; protected th2_Ports is procedure Put_msg_in (msg_in : Partition.message); procedure Get_msg_in (msg_in : out Partition.message); procedure Push_Back_msg_in (msg_in : out Partition.message); private msg_in_Buf : Th2_Msg_In_Buf_Type.Table; end th2_Ports; ... end proc_Servants;
For each “out” or “in out” port, we declare reference variable for each “in” or “in out” port connected to this port.
In order to comply to the AADL input-processing-output algorithm, shared data (either access-protected or not) are not read or written directly, but through temporary variables.
As seen in Process components mapping, any thread can access
shared variables. In order to ensure protected access when needed,
Ocarina will declare a local variable in the thread_controler
function, whose type is the variable internal type (if the variable
has the protected access property) or the variable real type.
Each time the thread controller is activated (i.e. each time the
related servant is called), the local variable is put to shared
variable value by its Setter
procedure, then processing is done
using the proper user-defined procedure. Then the Getter
is
used to update the shared variable.
Note that both Setter
and Getter
procedures are
generated by Ocarina and ensure access protection, as described in
Data components mapping.
Here is an example of generated code of the thread_controler
procedure which manage a mem_sh
variable.
procedure Th1_Controller is Msg_In : Partition.Message; Msg_In_Present : Standard.Boolean; Msg_Out : Partition.Message; -- local temporary variable definition Mem : Partition.Internal_Data; begin -- Read shared data and store it in local variable Partition.Get_Field (Sh_Mem, Mem); -- Read in IN ports Tr_Servants.Th1_IN_Ports.Get_Msg_In (Msg_In, Msg_In_Present); if (True and then Msg_In_Present) then -- Processing local variable Repository.Transmit_Message (Msg_In => Msg_In, Msg_Out => Msg_Out, Mem => Mem); -- Write in OUT ports ARAO.Requests.Emit_Msg (Tr_Helpers.To_Any (Msg_Out), Tr_Th2_Ref, "msg_in"); else if Msg_In_Present then Tr_Servants.Th1_IN_Ports.Push_Back_Msg_In (Msg_In); end if; end if; -- Write back local variable into shared data Partition.Set_Field (Sh_Mem, Mem); end Th1_Controller;
Available properties for thread components can be found in SAE AS5506, in 5.3 page 61 and in Appendix A, pages 197-218.
Activate_Deadline | Not Supported
|
Activate_Execution_Time | Not Supported
|
Activate_Entrypoint | Not Supported
|
Active_Thread_Handling_Protocol | Not Supported
|
Active_Thread_Queue_Handling_Protocol | Not Supported
|
Actual_Connection_Binding | Not Supported
|
Actual_Memory_Binding | Not Supported
|
Actual_Processor_Binding | Not Supported
|
Allowed_Connection_Protocol | Not Supported
|
Client_Subprogram_Execution_Time | Not Supported
|
Compute_Deadline | Not Supported
|
Compute_Execution_Time | Not Supported
|
Concurrency_Control_Protocol | Not Supported
|
Deactivate_Deadline | Not Supported
|
Deactivate_Execution_Time | Not Supported
|
Deactivate_Entrypoint | Not Supported
|
Deadline | Not Supported
|
Dispatch_Protocol | Supported (Periodic, Aperiodic)
|
Finalize_Deadline | Not Supported
|
Finalize_Execution_Time | Not Supported
|
Finalize_Entrypoint | Not Supported
|
Initialize_Deadline | Not Supported
|
Initialize_Execution_Time | Not Supported
|
Initialize_Entrypoint | Not Supported
|
Not_Collocated | Not Supported
|
Period | 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 | Supported
|
Source_Name | Not Supported
|
Source_Text | Not Supported
|
Source_Language | Not Supported
|
Synchronized_Component | Not Supported
|