Commit e442b9c1 authored by bouazizrahma's avatar bouazizrahma Committed by Jerome Hugues
Browse files

extend c_common-ba to implement the generation of impl|spec of functions in...

extend c_common-ba to implement the generation of impl|spec of functions in subprograms.c|h related to the BA dispatch pattern for sporadic threads
parent bb0664dc
......@@ -90,15 +90,44 @@ package body Ocarina.Backends.C_Common.BA is
Declarations : List_Id;
Statements : List_Id);
function Compute_Nb_States
(S : Node_Id) return Unsigned_Long_Long;
procedure Map_BA_States_To_C_Types
(S : Node_Id);
function Is_State_Kind_Type_Declaration_Exist
return Boolean;
function Compute_Nb_Trans_Stemmed_From_A_Specific_Complete_Stat
(BA : Node_Id;
Complete_State : Node_Id) return Unsigned_Long_Long;
procedure Fill_Nb_Dispatch_Triggers_Of_Each_Transition_Array
(S : Node_Id;
BA : Node_Id;
Complete_State : Node_Id;
Index_Comp_Stat : Unsigned_Long_Long;
WStatements : List_Id);
procedure Fill_Dispatch_Triggers_Of_All_Transitions_Array
(S : Node_Id;
BA : Node_Id;
Complete_State : Node_Id;
Index_Comp_Stat : Unsigned_Long_Long;
WStatements : List_Id);
function Nb_All_Dispatch_Triggers_From_A_Specific_Complete_Stat
(BA : Node_Id;
Complete_State : Node_Id) return Unsigned_Long_Long;
function Max_Dispatch_Triggers_Per_Trans_From_A_Specific_Complete_Stat
(BA : Node_Id;
Complete_State : Node_Id) return Unsigned_Long_Long;
procedure Make_States_Initialization_Function
(S : Node_Id);
procedure Make_Update_Next_Complete_State_Function
(S : Node_Id);
function Search_State_Kind
(BA : Node_Id;
State_Idt : Node_Id) return Ocarina.Types.Byte;
......@@ -125,7 +154,7 @@ package body Ocarina.Backends.C_Common.BA is
S : Node_Id;
Declarations : List_Id;
Statements : List_Id;
Else_St : List_Id) return List_Id;
Index_Transition : in out Unsigned_Long_Long) return List_Id;
procedure Map_C_A_List_Of_Transitions
(S : Node_Id;
......@@ -136,11 +165,11 @@ package body Ocarina.Backends.C_Common.BA is
WStatements : List_Id);
procedure Map_C_A_List_Of_On_Dispatch_Transitions
(S : Node_Id;
BA : Node_Id;
Sub_Transition_List : List_Id;
WDeclarations : List_Id;
WStatements : List_Id);
(S : Node_Id;
BA : Node_Id;
Sub_Transition_List : List_Id;
WDeclarations : List_Id;
WStatements : List_Id);
procedure Examine_Current_State_Until_Reaching_Complete_State
(S : Node_Id;
......@@ -632,52 +661,246 @@ package body Ocarina.Backends.C_Common.BA is
end Map_C_Behavior_Transitions;
------------------------------------------
-- Is_State_Kind_Type_Declaration_Exist --
------------------------------------------
----------------------------------------
-- Compute_Nb_On_Dispatch_Transitions --
-----------------------------------------
function Is_State_Kind_Type_Declaration_Exist
return Boolean
function Compute_Nb_On_Dispatch_Transitions
(S : Node_Id) return Unsigned_Long_Long
is
Result : Boolean := False;
decl : Node_Id;
BA : Node_Id;
behav_transition : Node_Id;
Transition_Node : Node_Id;
Nb_Dispatch_Transitions : Unsigned_Long_Long;
begin
decl := CTN.First_Node (CTN.Declarations (Current_File));
while Present (decl) loop
BA := Get_Behavior_Specification (S);
if Kind (decl) = CTN.K_Enumeration_Literals
and then
Standard.Utils.To_Lower
(CTN.Name (CTN.Defining_Identifier
(decl)))
= Standard.Utils.To_Lower
(Get_String_Name ("__po_hi_state_kind_t"))
Nb_Dispatch_Transitions := 0;
-- /** compute the number of all on dispatch transitions
-- that stems from the state "List_Node"
-- i.e. have BATN.Display_Name (List_Node) as source state.
--
if not BANu.Is_Empty (BATN.Transitions (BA)) then
Behav_Transition := BATN.First_Node (BATN.Transitions (BA));
while Present (Behav_Transition) loop
Transition_Node := BATN.Transition (Behav_Transition);
if BATN.Kind (Transition_Node) =
BATN.K_Execution_Behavior_Transition
and then
Present (BATN.Behavior_Condition (Transition_Node))
and then
Present (BATN.Condition
(BATN.Behavior_Condition
(Transition_Node)))
and then
BATN.Kind
(BATN.Condition
(Behavior_Condition (Transition_Node)))
= BATN.K_Dispatch_Condition_Thread
then
Nb_Dispatch_Transitions := Nb_Dispatch_Transitions + 1;
end if;
Behav_Transition := BATN.Next_Node (Behav_Transition);
end loop;
end if;
return Nb_Dispatch_Transitions;
end Compute_Nb_On_Dispatch_Transitions;
---------------------------------------------------------
-- Compute_Max_Dispatch_Transitions_Per_Complete_State --
---------------------------------------------------------
function Compute_Max_Dispatch_Transitions_Per_Complete_State
(S : Node_Id) return Unsigned_Long_Long
is
BA : Node_Id;
State : Node_Id;
List_Node : Node_Id;
behav_transition : Node_Id;
Transition_Node : Node_Id;
Source : Node_Id;
Max_Dispatch_Transitions : Unsigned_Long_Long := 0;
Nb_Dispatch_Transitions : Unsigned_Long_Long;
begin
BA := Get_Behavior_Specification (S);
State := BATN.First_Node (BATN.States (BA));
while Present (State) loop
if Behavior_State_Kind'Val (BATN.State_Kind (State))
= BSK_Initial_Complete
or else Behavior_State_Kind'Val (BATN.State_Kind (State))
= BSK_Initial_Complete_Final
or else Behavior_State_Kind'Val (BATN.State_Kind (State))
= BSK_Complete
or else Behavior_State_Kind'Val (BATN.State_Kind (State))
= BSK_Complete_Final
then
Result := True;
List_Node := BATN.First_Node (BATN.Identifiers (State));
while Present (List_Node) loop
Nb_Dispatch_Transitions := 0;
-- /** compute the number of all on dispatch transitions
-- that stems from the state "List_Node"
-- i.e. have BATN.Display_Name (List_Node) as source state.
--
if not BANu.Is_Empty (BATN.Transitions (BA)) then
Behav_Transition := BATN.First_Node (BATN.Transitions (BA));
while Present (Behav_Transition) loop
Transition_Node := BATN.Transition (Behav_Transition);
if BATN.Kind (Transition_Node) =
BATN.K_Execution_Behavior_Transition
and then
Present (BATN.Behavior_Condition (Transition_Node))
and then
Present (BATN.Condition
(BATN.Behavior_Condition
(Transition_Node)))
and then
BATN.Kind
(BATN.Condition
(Behavior_Condition (Transition_Node)))
= BATN.K_Dispatch_Condition_Thread
then
if BANu.Length (BATN.Sources (Transition_Node)) = 1
then
Source := BATN.First_Node
(BATN.Sources (Transition_Node));
if (Standard.Utils.To_Upper
(BATN.Display_Name (List_Node)) =
Standard.Utils.To_Upper
(BATN.Display_Name (Source)))
then
Nb_Dispatch_Transitions :=
Nb_Dispatch_Transitions + 1;
end if;
end if;
end if;
Behav_Transition := BATN.Next_Node (Behav_Transition);
end loop;
end if;
if Nb_Dispatch_Transitions > Max_Dispatch_Transitions then
Max_Dispatch_Transitions := Nb_Dispatch_Transitions;
end if;
List_Node := BATN.Next_Node (List_Node);
end loop;
end if;
exit when Result;
decl := CTN.Next_Node (decl);
State := BATN.Next_Node (State);
end loop;
return Result;
end Is_State_Kind_Type_Declaration_Exist;
------------------------------
-- Map_BA_States_To_C_Types --
------------------------------
return Max_Dispatch_Transitions;
procedure Map_BA_States_To_C_Types
(S : Node_Id)
end Compute_Max_Dispatch_Transitions_Per_Complete_State;
-----------------------------------------------------------
-- Compute_Max_Dispatch_Triggers_Per_Dispatch_Transition --
-----------------------------------------------------------
function Compute_Max_Dispatch_Triggers_Per_Dispatch_Transition
(S : Node_Id) return Unsigned_Long_Long
is
BA : Node_Id;
behav_transition : Node_Id;
Node : Node_Id;
Dispatch_Conjunction_Node : Node_Id;
Dipatch_Trigger_Event : Node_Id;
Max_Dispatch_Triggers : Unsigned_Long_Long := 0;
Nb_Dispatch_Triggers : Unsigned_Long_Long;
begin
BA := Get_Behavior_Specification (S);
if not BANu.Is_Empty (BATN.Transitions (BA)) then
behav_transition := BATN.First_Node (BATN.Transitions (BA));
while Present (Behav_Transition) loop
Node := BATN.Transition (Behav_Transition);
if BATN.Kind (Node) = BATN.K_Execution_Behavior_Transition
and then Present (BATN.Behavior_Condition (Node))
and then Present (BATN.Condition
(BATN.Behavior_Condition (Node)))
and then
BATN.Kind (BATN.Condition (Behavior_Condition (Node)))
= BATN.K_Dispatch_Condition_Thread
and then Present
(BATN.Dispatch_Trigger_Condition
(BATN.Condition
(BATN.Behavior_Condition (Node))))
and then not BANu.Is_Empty
(BATN.Dispatch_Conjunction
(BATN.Dispatch_Trigger_Condition
(BATN.Condition
(BATN.Behavior_Condition (Node)))))
then
Dispatch_Conjunction_Node :=
BATN.First_Node
(Dispatch_Conjunction
(Dispatch_Trigger_Condition (BATN.Condition
(BATN.Behavior_Condition (Node)))));
while Present (Dispatch_Conjunction_Node) loop
if not BANu.Is_Empty
(Dispatch_Triggers (Dispatch_Conjunction_Node))
then
Dipatch_Trigger_Event := BATN.First_Node
(Dispatch_Triggers (Dispatch_Conjunction_Node));
Nb_Dispatch_Triggers := 0;
while Present (Dipatch_Trigger_Event) loop
Nb_Dispatch_Triggers := Nb_Dispatch_Triggers + 1;
Dipatch_Trigger_Event := BATN.Next_Node
(Dipatch_Trigger_Event);
end loop;
if Nb_Dispatch_Triggers > Max_Dispatch_Triggers then
Max_Dispatch_Triggers := Nb_Dispatch_Triggers;
end if;
end if;
Dispatch_Conjunction_Node := BATN.Next_Node
(Dispatch_Conjunction_Node);
end loop;
end if;
behav_transition := BATN.Next_Node (behav_transition);
end loop;
end if;
return Max_Dispatch_Triggers;
end Compute_Max_Dispatch_Triggers_Per_Dispatch_Transition;
--------------------------------------
-- Create_Enum_Type_Of_States_Names --
--------------------------------------
procedure Create_Enum_Type_Of_States_Names (S : Node_Id)
is
BA : Node_Id;
State, List_Node : Node_Id;
N : Node_Id;
State_Enumerator_List : List_Id;
State_Kind_Enumerator_List : List_Id;
State_Struct : List_Id;
State_Identifier : Unsigned_Long_Long;
Nb_States : Unsigned_Long_Long;
Q : Name_Id;
Thread_Instance_Name : Name_Id;
E : constant Node_Id :=
AIN.Parent_Subcomponent (S);
......@@ -691,13 +914,12 @@ package body Ocarina.Backends.C_Common.BA is
-- typedef enum
-- {
-- s0, s1, s2, s3
-- } __po_hi_producer_state_name_t;
-- } __po_hi__<<thread_instance_name>>__state_name_t;
State_Enumerator_List := New_List (CTN.K_Enumeration_Literals);
State := BATN.First_Node (BATN.States (BA));
State_Identifier := 0;
Nb_States := 0;
while Present (State) loop
......@@ -718,7 +940,6 @@ package body Ocarina.Backends.C_Common.BA is
Append_Node_To_List (N, State_Enumerator_List);
State_Identifier := State_Identifier + 1;
Nb_States := Nb_States + 1;
List_Node := BATN.Next_Node (List_Node);
end loop;
......@@ -742,52 +963,19 @@ package body Ocarina.Backends.C_Common.BA is
Type_Definition => Make_Enum_Aggregate (State_Enumerator_List));
Append_Node_To_List (N, CTN.Declarations (Current_File));
-- 2) Create an enumeration type declaration
-- called state_kind
-- that enumerates all possible kinds of state
--
-- typedef enum
-- {
-- __po_hi_initial,
-- __po_hi_initial_complete,
-- __po_hi_initial_complete_final,
-- __po_hi_initial_final,
-- __po_hi_complete,
-- __po_hi_complete_final,
-- __po_hi_final,
-- __po_hi_execution
-- } __po_hi_state_kind_t;
--
if not Is_State_Kind_Type_Declaration_Exist then
State_Kind_Enumerator_List := New_List (CTN.K_Enumeration_Literals);
Append_Node_To_List (RE (RE_Initial), State_Kind_Enumerator_List);
Append_Node_To_List (RE (RE_Initial_Complete),
State_Kind_Enumerator_List);
Append_Node_To_List (RE (RE_Initial_Complete_Final),
State_Kind_Enumerator_List);
Append_Node_To_List (RE (RE_Initial_Final),
State_Kind_Enumerator_List);
Append_Node_To_List (RE (RE_Complete), State_Kind_Enumerator_List);
Append_Node_To_List (RE (RE_Complete_Final),
State_Kind_Enumerator_List);
Append_Node_To_List (RE (RE_Final), State_Kind_Enumerator_List);
end Create_Enum_Type_Of_States_Names;
Append_Node_To_List (RE (RE_Execution), State_Kind_Enumerator_List);
-----------------------
-- Create_State_Type --
-----------------------
N :=
Make_Full_Type_Declaration
(Defining_Identifier => RE (RE_State_Kind_T),
Type_Definition => Make_Enum_Aggregate
(State_Kind_Enumerator_List));
Append_Node_To_List (N, CTN.Declarations (Current_File));
end if;
procedure Create_State_Type (S : Node_Id)
is
N : Node_Id;
State_Struct : List_Id;
E : constant Node_Id :=
AIN.Parent_Subcomponent (S);
begin
-- 3)
-- typedef struct
......@@ -798,25 +986,32 @@ package body Ocarina.Backends.C_Common.BA is
State_Struct := New_List (CTN.K_Enumeration_Literals);
Set_Str_To_Name_Buffer ("name");
Q := Name_Find;
N :=
Make_Member_Declaration
(Defining_Identifier => Make_Defining_Identifier (Q),
(Defining_Identifier => Make_Defining_Identifier
(MN (M_Name)),
Used_Type => Make_Defining_Identifier
(Map_C_Variable_Name (E, State_Name_T => True)));
Append_Node_To_List (N, State_Struct);
Set_Str_To_Name_Buffer ("kind");
Q := Name_Find;
N :=
Make_Member_Declaration
(Defining_Identifier => Make_Defining_Identifier (Q),
(Defining_Identifier => Make_Defining_Identifier
(MN (M_kind)),
Used_Type => RE (RE_State_Kind_T));
Append_Node_To_List (N, State_Struct);
if Get_Thread_Dispatch_Protocol (S) = Thread_Sporadic
and then Compute_Nb_On_Dispatch_Transitions (S) > 1
then
N :=
Make_Member_Declaration
(Defining_Identifier => Make_Defining_Identifier
(MN (M_States_Attributes)),
Used_Type => RE (RE_Ba_Automata_State_T));
Append_Node_To_List (N, State_Struct);
end if;
N :=
Make_Full_Type_Declaration
(Defining_Identifier => Make_Defining_Identifier
......@@ -825,6 +1020,58 @@ package body Ocarina.Backends.C_Common.BA is
Make_Struct_Aggregate (Members => State_Struct));
Append_Node_To_List (N, CTN.Declarations (Current_File));
end Create_State_Type;
-----------------------
-- Compute_Nb_States --
-----------------------
function Compute_Nb_States
(S : Node_Id) return Unsigned_Long_Long
is
BA : Node_Id;
State, List_Node : Node_Id;
Nb_States : Unsigned_Long_Long;
begin
BA := Get_Behavior_Specification (S);
State := BATN.First_Node (BATN.States (BA));
Nb_States := 0;
while Present (State) loop
if not BANu.Is_Empty (BATN.Identifiers (State)) then
List_Node := BATN.First_Node (BATN.Identifiers (State));
while Present (List_Node) loop
Nb_States := Nb_States + 1;
List_Node := BATN.Next_Node (List_Node);
end loop;
end if;
State := BATN.Next_Node (State);
end loop;
return Nb_States;
end Compute_Nb_States;
------------------------------
-- Map_BA_States_To_C_Types --
------------------------------
procedure Map_BA_States_To_C_Types
(S : Node_Id)
is
N : Node_Id;
Nb_States : constant Unsigned_Long_Long :=
Compute_Nb_States (S);
E : constant Node_Id :=
AIN.Parent_Subcomponent (S);
begin
-- 4)
-- #define __po_hi_<<thread_instance_name>>_nb_states <<Nb_States>>
......@@ -899,6 +1146,710 @@ package body Ocarina.Backends.C_Common.BA is
return Result;
end Map_C_State_Kind_Name;
-------------------------------------------------------------------
-- Max_Dispatch_Triggers_Per_Trans_From_A_Specific_Complete_Stat --
-------------------------------------------------------------------
function Max_Dispatch_Triggers_Per_Trans_From_A_Specific_Complete_Stat
(BA : Node_Id;
Complete_State : Node_Id) return Unsigned_Long_Long
is
Nb_Dispatch_Triggers_Per_Trans : Unsigned_Long_Long := 0;
Max_Dispatch_Triggers_Per_Trans : Unsigned_Long_Long := 0;
behav_transition : Node_Id;
Node : Node_Id;
Source : Node_Id;
Dispatch_Conjunction_Node : Node_Id;
Dispatch_Trigger_Event : Node_Id;
begin
-- /** compute the number of all dispatch triggers of all
-- on dispatch transitions transitions that stem from the state
-- "Complete_State"
-- i.e. have BATN.Display_Name (Complete_State) as source state.
--
if not BANu.Is_Empty (BATN.Transitions (BA)) then
Behav_Transition := BATN.First_Node (BATN.Transitions (BA));
while Present (Behav_Transition) loop
Node := BATN.Transition (Behav_Transition);
if BATN.Kind (Node) =
BATN.K_Execution_Behavior_Transition
and then
Present (BATN.Behavior_Condition (Node))
and then
Present (BATN.Condition
(BATN.Behavior_Condition
(Node)))
and then
BATN.Kind
(BATN.Condition
(Behavior_Condition (Node)))
= BATN.K_Dispatch_Condition_Thread
then
if BANu.Length (BATN.Sources (Node)) = 1
then
Source := BATN.First_Node
(BATN.Sources (Node));
if (Standard.Utils.To_Upper
(BATN.Display_Name (Complete_State)) =
Standard.Utils.To_Upper
(BATN.Display_Name (Source)))
then
Nb_Dispatch_Triggers_Per_Trans := 0;
if Present (BATN.Dispatch_Trigger_Condition
(BATN.Condition
(BATN.Behavior_Condition (Node))))
and then not BANu.Is_Empty
(BATN.Dispatch_Conjunction
(BATN.Dispatch_Trigger_Condition
(BATN.Condition
(BATN.Behavior_Condition (Node)))))
then
if BANu.Length
(Dispatch_Conjunction
(Dispatch_Trigger_Condition (BATN.Condition
(BATN.Behavior_Condition (Node))))) = 1
then
Dispatch_Conjunction_Node :=
BATN.First_Node
(Dispatch_Conjunction