OpenAADL / ocarina
1
------------------------------------------------------------------------------
2
--                                                                          --
3
--                           OCARINA COMPONENTS                             --
4
--                                                                          --
5
--          O C A R I N A . B A C K E N D S . P O K _ C . M A I N           --
6
--                                                                          --
7
--                                 B o d y                                  --
8
--                                                                          --
9
--               Copyright (C) 2008-2009 Telecom ParisTech,                 --
10
--                 2010-2019 ESA & ISAE, 2019-2020 OpenAADL                 --
11
--                                                                          --
12
-- Ocarina  is free software; you can redistribute it and/or modify under   --
13
-- terms of the  GNU General Public License as published  by the Free Soft- --
14
-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
15
-- sion. Ocarina is distributed in the hope that it will be useful, but     --
16
-- WITHOUT ANY WARRANTY; without even the implied warranty of               --
17
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                     --
18
--                                                                          --
19
-- As a special exception under Section 7 of GPL version 3, you are granted --
20
-- additional permissions described in the GCC Runtime Library Exception,   --
21
-- version 3.1, as published by the Free Software Foundation.               --
22
--                                                                          --
23
-- You should have received a copy of the GNU General Public License and    --
24
-- a copy of the GCC Runtime Library Exception along with this program;     --
25
-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
26
-- <http://www.gnu.org/licenses/>.                                          --
27
--                                                                          --
28
--                    Ocarina is maintained by OpenAADL team                --
29
--                              (info@openaadl.org)                         --
30
--                                                                          --
31
------------------------------------------------------------------------------
32

33
with Ocarina.Namet;
34
with Ocarina.ME_AADL;
35
with Ocarina.ME_AADL.AADL_Instances.Nodes;
36
with Ocarina.ME_AADL.AADL_Instances.Nutils;
37
with Ocarina.ME_AADL.AADL_Instances.Entities;
38
with Ocarina.Backends.Messages;
39
with Ocarina.Backends.Utils;
40
with Ocarina.Backends.Properties;
41
with Ocarina.Backends.C_Values;
42
with Ocarina.Backends.C_Tree.Nutils;
43
with Ocarina.Backends.C_Tree.Nodes;
44
with Ocarina.Backends.POK_C.Runtime;
45
with Ocarina.Backends.C_Common.Mapping;
46

47
with Ocarina.Instances.Queries;
48

49 1
package body Ocarina.Backends.POK_C.Main is
50

51
   use Ocarina.Namet;
52
   use Ocarina.ME_AADL;
53
   use Ocarina.ME_AADL.AADL_Instances.Nodes;
54
   use Ocarina.ME_AADL.AADL_Instances.Entities;
55
   use Ocarina.Backends.Messages;
56
   use Ocarina.Backends.Properties;
57
   use Ocarina.Backends.Utils;
58
   use Ocarina.Backends.C_Values;
59
   use Ocarina.Backends.C_Tree.Nutils;
60
   use Ocarina.Backends.POK_C.Runtime;
61
   use Ocarina.Backends.C_Common.Mapping;
62

63
   use Ocarina.Instances.Queries;
64

65
   package AIN renames Ocarina.ME_AADL.AADL_Instances.Nodes;
66
   package AINU renames Ocarina.ME_AADL.AADL_Instances.Nutils;
67
   package CTN renames Ocarina.Backends.C_Tree.Nodes;
68
   package CTU renames Ocarina.Backends.C_Tree.Nutils;
69
   package CV renames Ocarina.Backends.C_Values;
70

71
   -----------------
72
   -- Source_File --
73
   -----------------
74

75
   package body Source_File is
76

77 1
      Tattr                 : Node_Id;
78 1
      Main_Function         : Node_Id;
79 1
      Statements            : List_Id;
80
      Init_Function         : Node_Id            := No_Node;
81
      Thread_Id             : Unsigned_Long_Long := 0;
82 1
      Process_Variable_Type : Node_Id;
83 1
      Process_Variable_Name : Node_Id;
84

85 1
      Error_Switch_Alternatives : List_Id;
86

87
      Use_Error_Handling : Boolean := False;
88

89
      Current_Device : Node_Id := No_Node;
90

91
      procedure Visit_Architecture_Instance (E : Node_Id);
92
      procedure Visit_Component_Instance (E : Node_Id);
93
      procedure Visit_System_Instance (E : Node_Id);
94
      procedure Visit_Process_Instance
95
        (E                       : Node_Id;
96
         Real_Process            : Boolean := True;
97
         Corresponding_Component : Node_Id := No_Node);
98
      procedure Visit_Device_Instance (E : Node_Id);
99
      procedure Visit_Processor_Instance (E : Node_Id);
100
      procedure Visit_Virtual_Processor_Instance (E : Node_Id);
101
      procedure Visit_Thread_Instance (E : Node_Id);
102

103
      procedure Setup_Thread (E : Node_Id);
104

105
      function Map_Queueing_Policy (Port : Node_Id) return Node_Id;
106

107 1
      function Map_Queueing_Policy (Port : Node_Id) return Node_Id is
108
         ARINC653_Discipline : constant ARINC653_Queuing_Discipline :=
109 1
           Get_ARINC653_Queuing_Discipline (Port);
110
      begin
111 1
         if ARINC653_Discipline /= Invalid
112 0
           and then ARINC653_Discipline = Priority_Based
113
         then
114

115 0
            if Use_ARINC653_API then
116 0
               return RE (RE_Priority);
117
            else
118 0
               return RE (RE_Pok_Port_Queueing_Discipline_Fifo);
119
            end if;
120
         end if;
121

122 1
         if Use_ARINC653_API then
123 1
            return RE (RE_Fifo);
124
         else
125 0
            return RE (RE_Pok_Port_Queueing_Discipline_Fifo);
126
         end if;
127
      end Map_Queueing_Policy;
128

129
      ------------------
130
      -- Setup_Thread --
131
      ------------------
132

133 1
      procedure Setup_Thread (E : Node_Id) is
134 1
         Parameters   : List_Id;
135 1
         N            : Node_Id;
136 1
         S            : constant Node_Id := Parent_Subcomponent (E);
137 1
         Member_Value : Node_Id;
138 1
         Stack_Size   : Unsigned_Long_Long;
139
      begin
140
         --  Initializes thread attributes.
141 1
         if Use_ARINC653_API = False then
142
            N :=
143 0
              POK_Make_Function_Call_With_Assert
144 0
                (RF (RE_Pok_Thread_Attr_Init),
145 0
                 Make_List_Id (Make_Variable_Address (Copy_Node (Tattr))));
146

147 0
            Append_Node_To_List (N, Statements);
148

149 0
            POK_Add_Return_Assertion (Statements);
150
         end if;
151

152
         --  Make strcpy(tattr.NAME, "prname")
153

154 1
         if POK_Flavor = DEOS or else POK_Flavor = VXWORKS then
155
            N :=
156 1
              Make_Call_Profile
157 1
                (Make_Defining_Identifier (Get_String_Name ("strcpy")),
158 1
                 Make_List_Id
159 1
                   (Make_Member_Designator (RE (RE_Name), Copy_Node (Tattr)),
160 1
                    Make_Literal
161 1
                      (CV.New_Pointed_Char_Value (Name (Identifier (S))))));
162 1
            Append_Node_To_List (N, Statements);
163
         end if;
164

165
         --  Make tattr.entry = entrypoint
166

167 1
         if Use_ARINC653_API then
168
            N :=
169 1
              Make_Expression
170
                (Left_Expr =>
171 1
                   Make_Member_Designator
172 1
                     (RE (RE_Entry_Point),
173 1
                      Copy_Node (Tattr)),
174
                 Operator   => Op_Equal,
175
                 Right_Expr =>
176 1
                   Copy_Node
177 1
                     (CTN.Defining_Identifier
178 1
                        (CTN.Job_Node (Backend_Node (Identifier (S))))));
179

180
         else
181
            N :=
182 0
              Make_Expression
183
                (Left_Expr =>
184 0
                   Make_Member_Designator (RE (RE_Entry), Copy_Node (Tattr)),
185
                 Operator   => Op_Equal,
186
                 Right_Expr =>
187 0
                   Copy_Node
188 0
                     (CTN.Defining_Identifier
189 0
                        (CTN.Job_Node (Backend_Node (Identifier (S))))));
190
         end if;
191

192 1
         Append_Node_To_List (N, Statements);
193

194
         --  Add priority to tattr, tattr.priority = threadpriority
195

196 1
         if Get_Thread_Priority (E) /= 0 then
197 1
            N := Make_Literal (New_Int_Value (Get_Thread_Priority (E), 1, 10));
198

199 1
            if Use_ARINC653_API then
200
               N :=
201 1
                 Make_Expression
202
                   (Left_Expr =>
203 1
                      Make_Member_Designator
204 1
                        (RE (RE_Base_Priority),
205 1
                         Copy_Node (Tattr)),
206
                    Operator   => Op_Equal,
207
                    Right_Expr => N);
208
            else
209
               N :=
210 0
                 Make_Expression
211
                   (Left_Expr =>
212 0
                      Make_Member_Designator
213 0
                        (Make_Defining_Identifier (MN (M_Priority)),
214 0
                         Copy_Node (Tattr)),
215
                    Operator   => Op_Equal,
216
                    Right_Expr => N);
217
            end if;
218

219 1
            Append_Node_To_List (N, Statements);
220
         end if;
221

222 1
         if Get_Thread_Deadline (E) /= Null_Time then
223 1
            if POK_Flavor = ARINC653 then
224
               Member_Value :=
225 0
                 Map_Time_To_Millisecond (Get_Thread_Deadline (E));
226 1
            elsif POK_Flavor = POK then
227 0
               Member_Value := Map_Time (Get_Thread_Deadline (E));
228
            else
229 1
               Member_Value := No_Node;
230
            end if;
231

232 1
            if Member_Value /= No_Node then
233
               N :=
234 0
                 Make_Expression
235
                   (Left_Expr =>
236 0
                      Make_Member_Designator
237 0
                        (RE (RE_Deadline),
238 0
                         Copy_Node (Tattr)),
239
                    Operator   => Op_Equal,
240
                    Right_Expr => Member_Value);
241 0
               Append_Node_To_List (N, Statements);
242
            end if;
243
         else
244 0
            Display_Error ("Deadline not specified", Fatal => False);
245
         end if;
246

247 1
         if Get_Thread_Period (E) /= Null_Time then
248 1
            if Use_ARINC653_API then
249 1
               if POK_Flavor = POK then
250
                  Member_Value :=
251 0
                    Map_Time_To_Millisecond (Get_Thread_Period (E));
252 1
               elsif POK_Flavor = DEOS or else POK_Flavor = VXWORKS then
253
                  Member_Value :=
254 1
                    Map_Time_To_Nanosecond (Get_Thread_Period (E));
255
               end if;
256
            else
257 0
               Member_Value := Map_Time (Get_Thread_Period (E));
258
            end if;
259

260 1
            if Member_Value /= No_Node then
261
               N :=
262 1
                 Make_Expression
263
                   (Left_Expr =>
264 1
                      Make_Member_Designator
265 1
                        (RE (RE_Period),
266 1
                         Copy_Node (Tattr)),
267
                    Operator   => Op_Equal,
268
                    Right_Expr => Member_Value);
269

270 1
               Append_Node_To_List (N, Statements);
271
            end if;
272
         else
273 0
            Display_Error ("Period not specified", Fatal => True);
274
         end if;
275

276
         --
277
         --  Set up the Stack Size
278
         --  On most system, the default is 4096. So, we set
279
         --  up 4096 if not explicitly declared. We use
280
         --  The AADL property Stack_Size if declared.
281
         --
282

283 1
         Stack_Size := 4096;
284

285 1
         if Get_Thread_Stack_Size (E) /= Null_Size then
286 1
            Stack_Size := To_Bytes (Get_Thread_Stack_Size (E));
287
         end if;
288
         N :=
289 1
           Make_Expression
290
             (Left_Expr =>
291 1
                Make_Member_Designator (RE (RE_Stack_Size), Copy_Node (Tattr)),
292
              Operator   => Op_Equal,
293 1
              Right_Expr => Make_Literal (New_Int_Value (Stack_Size, 1, 10)));
294 1
         Append_Node_To_List (N, Statements);
295

296 1
         declare
297 1
            TA       : constant Time_Array := Get_Execution_Time (E);
298 1
            Capacity : Node_Id;
299
         begin
300 1
            if TA /= Empty_Time_Array then
301 1
               if Use_ARINC653_API then
302 1
                  if POK_Flavor = ARINC653 then
303 0
                     Capacity := Map_Time_To_Millisecond (TA (1));
304 1
                  elsif POK_Flavor = DEOS then
305 1
                     Capacity := Map_Time_To_Nanosecond (TA (1));
306 1
                  elsif POK_Flavor = VXWORKS then
307 1
                     Capacity := Map_Time_To_Nanosecond (TA (1));
308
                  else
309 0
                     Capacity := No_Node;
310
                  end if;
311
               else
312 0
                  Capacity := Map_Time (TA (1));
313
               end if;
314
            else
315 0
               Display_Error
316
                 ("Compute execution time not declared",
317
                  Fatal => False);
318

319
               --  By default, we allocate 1 ms for thread execution.
320
               Capacity :=
321 0
                 CTU.Make_Literal (CV.New_Int_Value (Thread_Id, 1, 10));
322
            end if;
323

324
            N :=
325 1
              Make_Expression
326
                (Left_Expr =>
327 1
                   Make_Member_Designator
328 1
                     (RE (RE_Time_Capacity),
329 1
                      Copy_Node (Tattr)),
330
                 Operator   => Op_Equal,
331
                 Right_Expr => Capacity);
332

333 1
            Append_Node_To_List (N, Statements);
334 1
         end;
335

336
         --  Add tid and other stuff to the parameters and call
337
         --  pok_thread_create
338

339 1
         Parameters := New_List (CTN.K_Parameter_List);
340

341 1
         if Use_ARINC653_API then
342 1
            Append_Node_To_List
343 1
              (Make_Variable_Address (Copy_Node (Tattr)),
344
               Parameters);
345

346 1
            Append_Node_To_List
347 1
              (Make_Variable_Address
348 1
                 (Make_Array_Value
349 1
                    (Copy_Node (Process_Variable_Name),
350 1
                     CTU.Make_Literal (CV.New_Int_Value (Thread_Id, 1, 10)))),
351
               Parameters);
352 1
            Add_Return_Variable_In_Parameters (Parameters);
353
         else
354 0
            Append_Node_To_List
355 0
              (Make_Variable_Address
356 0
                 (Make_Array_Value
357 0
                    (Copy_Node (Process_Variable_Name),
358 0
                     CTU.Make_Literal (CV.New_Int_Value (Thread_Id, 1, 10)))),
359
               Parameters);
360

361 0
            Append_Node_To_List
362 0
              (Make_Variable_Address (Copy_Node (Tattr)),
363
               Parameters);
364

365
         end if;
366

367 1
         if Use_ARINC653_API then
368 1
            Append_Node_To_List
369 1
              (POK_Make_Function_Call_With_Assert
370 1
                 (RF (RE_Create_Process),
371
                  Parameters),
372
               Statements);
373 1
            Parameters := New_List (CTN.K_Parameter_List);
374 1
            Append_Node_To_List
375 1
              (Make_Array_Value
376 1
                 (Copy_Node (Process_Variable_Name),
377 1
                  CTU.Make_Literal (CV.New_Int_Value (Thread_Id, 1, 10))),
378
               Parameters);
379 1
            Add_Return_Variable_In_Parameters (Parameters);
380 1
            Append_Node_To_List
381 1
              (POK_Make_Function_Call_With_Assert (RF (RE_Start), Parameters),
382
               Statements);
383
         else
384 0
            Append_Node_To_List
385 0
              (POK_Make_Function_Call_With_Assert
386 0
                 (RF (RE_Pok_Thread_Create),
387
                  Parameters),
388
               Statements);
389
         end if;
390

391
         N :=
392 1
           Message_Comment
393
             ("This thread was mapped from a thread component contained" &
394
              "in this process. The function it executes is also generated" &
395
              "in the file activity.c.");
396

397 1
         POK_Add_Return_Assertion (Statements);
398

399 1
         CTU.Append_Node_To_List (N, Statements);
400 1
      end Setup_Thread;
401

402
      -----------
403
      -- Visit --
404
      -----------
405

406 1
      procedure Visit (E : Node_Id) is
407
      begin
408 1
         case Kind (E) is
409 1
            when K_Architecture_Instance =>
410 1
               Visit_Architecture_Instance (E);
411

412 1
            when K_Component_Instance =>
413 1
               Visit_Component_Instance (E);
414

415 0
            when others =>
416 0
               null;
417 1
         end case;
418 1
      end Visit;
419

420
      ---------------------------------
421
      -- Visit_Architecture_Instance --
422
      ---------------------------------
423

424 1
      procedure Visit_Architecture_Instance (E : Node_Id) is
425
      begin
426 1
         Visit (Root_System (E));
427 1
      end Visit_Architecture_Instance;
428

429
      ------------------------------
430
      -- Visit_Component_Instance --
431
      ------------------------------
432

433 1
      procedure Visit_Component_Instance (E : Node_Id) is
434
         Category : constant Component_Category :=
435 1
           Get_Category_Of_Component (E);
436
      begin
437 1
         case Category is
438 1
            when CC_System =>
439 1
               Visit_System_Instance (E);
440

441 1
            when CC_Process =>
442 1
               Visit_Process_Instance (E);
443

444 0
            when CC_Device =>
445 0
               Visit_Device_Instance (E);
446

447 1
            when CC_Processor =>
448 1
               Visit_Processor_Instance (E);
449

450 1
            when CC_Virtual_Processor =>
451 1
               Visit_Virtual_Processor_Instance (E);
452

453 1
            when CC_Thread =>
454 1
               Visit_Thread_Instance (E);
455

456 0
            when others =>
457 0
               null;
458 1
         end case;
459 1
      end Visit_Component_Instance;
460

461
      ----------------------------
462
      -- Visit_Process_Instance --
463
      ----------------------------
464

465 1
      procedure Visit_Process_Instance
466
        (E                       : Node_Id;
467
         Real_Process            : Boolean := True;
468
         Corresponding_Component : Node_Id := No_Node)
469
      is
470 1
         U                : Node_Id;
471 1
         P                : Node_Id;
472 1
         N                : Node_Id;
473 1
         S                : Node_Id;
474 1
         Spec             : Node_Id;
475 1
         Declarations     : List_Id := New_List (CTN.K_Declaration_List);
476 1
         Call_Parameters  : List_Id;
477 1
         Called_Function  : Node_Id;
478 1
         Used_Type        : Node_Id;
479 1
         Used_Member      : Node_Id;
480
         While_Statements : constant List_Id :=
481 1
           New_List (CTN.K_Statement_List);
482 1
         Shared_Data             : Node_Id;
483 1
         Function_Call           : Node_Id;
484 1
         Communicating_Component : Node_Id;
485

486
         procedure Setup_In_Ports;
487
         procedure Setup_Out_Ports;
488

489
         --------------------
490
         -- Setup_In_Ports --
491
         --------------------
492

493 1
         procedure Setup_In_Ports is
494 1
            F               : Node_Id;
495 1
            Called_Function : Node_Id;
496 1
            Added_Parameter : Node_Id;
497 1
            Variable_Type   : Node_Id;
498
         begin
499 1
            if AINU.Is_Empty (Features (Communicating_Component)) then
500 0
               return;
501
            end if;
502

503 1
            F := First_Node (Features (Communicating_Component));
504

505 1
            while Present (F) loop
506 1
               Call_Parameters := New_List (CTN.K_Parameter_List);
507

508 1
               if Kind (F) = K_Port_Spec_Instance
509 1
                 and then Is_In (F)
510 1
                 and then not Is_Out (F)
511 1
                 and then Get_Connection_Pattern (F) = Inter_Process
512 1
                 and then not Is_Virtual (Get_Port_By_Name (F, Current_Device))
513
               then
514 1
                  if AIN.Is_Data (F) and then Is_Event (F) then
515 1
                     Append_Node_To_List
516 1
                       (Make_Literal
517 1
                          (CV.New_Pointed_Char_Value (Map_Port_Name (F))),
518
                        Call_Parameters);
519

520 1
                     if POK_Flavor = POK then
521 0
                        N := Map_Queue_Size_With_Data (F);
522 0
                        Append_Node_To_List (N, Call_Parameters);
523
                     else
524

525
                        --  Map the size
526

527 1
                        N := Get_Data_Size (Corresponding_Instance (F));
528

529 1
                        Append_Node_To_List (N, Call_Parameters);
530

531
                        --  Map the queue size
532

533 1
                        N := Map_Queue_Size (F);
534 1
                        Append_Node_To_List (N, Call_Parameters);
535
                     end if;
536

537 1
                     if Use_ARINC653_API then
538 1
                        Added_Parameter := RE (RE_Destination);
539
                     else
540 0
                        Added_Parameter := RE (RE_Pok_Port_Direction_In);
541
                     end if;
542

543 1
                     Append_Node_To_List (Added_Parameter, Call_Parameters);
544

545 1
                     Added_Parameter := Map_Queueing_Policy (F);
546

547 1
                     Append_Node_To_List (Added_Parameter, Call_Parameters);
548

549 1
                     Append_Node_To_List
550 1
                       (Make_Variable_Address
551 1
                          (Make_Defining_Identifier (Map_Port_Var (F))),
552
                        Call_Parameters);
553

554 1
                     if Use_ARINC653_API then
555 1
                        Append_Node_To_List
556 1
                          (Make_Variable_Address
557 1
                             (Make_Defining_Identifier (VN (V_Ret))),
558
                           Call_Parameters);
559

560 1
                        Called_Function := RF (RE_Create_Queuing_Port);
561
                     else
562 0
                        Called_Function := RF (RE_Pok_Port_Queueing_Create);
563
                     end if;
564

565 1
                     Append_Node_To_List
566 1
                       (POK_Make_Function_Call_With_Assert
567
                          (Called_Function,
568
                           Call_Parameters),
569
                        Statements);
570

571 1
                     POK_Add_Return_Assertion (Statements);
572

573 1
                     if Use_ARINC653_API then
574 1
                        Variable_Type := RE (RE_Queuing_Port_Id_Type);
575
                     else
576 0
                        Variable_Type := RE (RE_Uint8_T);
577
                     end if;
578

579 1
                     Append_Node_To_List
580 1
                       (Make_Variable_Declaration
581
                          (Defining_Identifier =>
582 1
                             (Make_Defining_Identifier (Map_Port_Var (F))),
583
                           Used_Type => Variable_Type),
584 1
                        CTN.Declarations (Current_File));
585

586
                     N :=
587 1
                       Message_Comment
588
                         ("This queueing port was mapped from an in" &
589
                          "event data port contained in the process. It" &
590
                          "is used for inter-partition communication.");
591

592 1
                     CTU.Append_Node_To_List (N, Statements);
593 1
                  elsif AIN.Is_Data (F) and then not Is_Event (F) then
594

595
                     --
596
                     --  Here, we have a sampling port.
597
                     --
598

599 1
                     Append_Node_To_List
600 1
                       (Make_Literal
601 1
                          (CV.New_Pointed_Char_Value (Map_Port_Name (F))),
602
                        Call_Parameters);
603

604 1
                     if Current_Device = No_Node then
605 1
                        N := Get_Inter_Partition_Port_Size (F);
606

607 1
                        if Is_Using_Virtual_Bus (F) then
608 0
                           Add_Include (RH (RH_Protocols));
609 0
                           Add_Define_Deployment (RE (RE_Pok_Needs_Protocols));
610
                        end if;
611
                     else
612
                        N :=
613 0
                          Get_Inter_Partition_Port_Size
614 0
                            (Get_Port_By_Name (F, Current_Device));
615

616 0
                        if Is_Using_Virtual_Bus
617 0
                            (Get_Port_By_Name (F, Current_Device))
618
                        then
619 0
                           Add_Include (RH (RH_Protocols));
620 0
                           Add_Define_Deployment (RE (RE_Pok_Needs_Protocols));
621
                        end if;
622
                     end if;
623

624 1
                     Append_Node_To_List (N, Call_Parameters);
625

626
                     --  Map the port of the sampling port, take in
627
                     --  account potential virtual bus layers.
628

629 1
                     if Use_ARINC653_API then
630 1
                        Append_Node_To_List
631 1
                          (RE (RE_Destination),
632
                           Call_Parameters);
633
                     else
634 0
                        Append_Node_To_List
635 0
                          (RE (RE_Pok_Port_Direction_In),
636
                           Call_Parameters);
637
                     end if;
638

639 1
                     if Get_POK_Refresh_Time (F) /= Null_Time then
640 1
                        if Use_ARINC653_API then
641
                           N :=
642 1
                             Map_Time_To_Nanosecond (Get_POK_Refresh_Time (F));
643
                        else
644 0
                           N := Map_Time (Get_POK_Refresh_Time (F));
645
                        end if;
646
                     else
647 0
                        if POK_Flavor = DEOS or else POK_Flavor = VXWORKS then
648

649
                           --
650
                           --  DeOS needs a value to refresh the port.
651
                           --
652

653 0
                           N :=
654 0
                             CTU.Make_Literal
655 0
                               (CV.New_Int_Value (1_000_000, 1, 10));
656
                        else
657 0
                           N := CTU.Make_Literal (CV.New_Int_Value (0, 1, 10));
658
                        end if;
659
                     end if;
660 1
                     Append_Node_To_List (N, Call_Parameters);
661

662 1
                     Append_Node_To_List
663 1
                       (Make_Variable_Address
664 1
                          (Make_Defining_Identifier (Map_Port_Var (F))),
665
                        Call_Parameters);
666

667 1
                     if Use_ARINC653_API then
668 1
                        Add_Return_Variable_In_Parameters (Call_Parameters);
669 1
                        Called_Function := RF (RE_Create_Sampling_Port);
670
                     else
671 0
                        Called_Function := RF (RE_Pok_Port_Sampling_Create);
672
                     end if;
673

674 1
                     Append_Node_To_List
675 1
                       (POK_Make_Function_Call_With_Assert
676
                          (Called_Function,
677
                           Call_Parameters),
678
                        Statements);
679

680 1
                     POK_Add_Return_Assertion (Statements);
681

682 1
                     if Use_ARINC653_API then
683 1
                        Variable_Type := RE (RE_Sampling_Port_Id_Type);
684
                     else
685 0
                        Variable_Type := RE (RE_Uint8_T);
686
                     end if;
687

688 1
                     Append_Node_To_List
689 1
                       (Make_Variable_Declaration
690
                          (Defining_Identifier =>
691 1
                             (Make_Defining_Identifier (Map_Port_Var (F))),
692
                           Used_Type => (Variable_Type)),
693 1
                        CTN.Declarations (Current_File));
694

695
                     N :=
696 1
                       Message_Comment
697
                         ("This sampling port was mapped from a in data" &
698
                          "port contained in the process. It is used" &
699
                          "for inter-partition communication.");
700

701 1
                     CTU.Append_Node_To_List (N, Statements);
702
                  end if;
703
               end if;
704 1
               F := Next_Node (F);
705 1
            end loop;
706
         end Setup_In_Ports;
707

708
         ---------------------
709
         -- Setup_Out_Ports --
710
         ---------------------
711

712 1
         procedure Setup_Out_Ports is
713 1
            F               : Node_Id;
714 1
            Called_Function : Node_Id;
715 1
            Added_Parameter : Node_Id;
716 1
            Variable_Type   : Node_Id;
717
         begin
718

719 1
            Error_Switch_Alternatives := New_List (CTN.K_Alternatives_List);
720

721 1
            if AINU.Is_Empty (Features (Communicating_Component)) then
722 0
               return;
723
            end if;
724

725 1
            F := First_Node (Features (Communicating_Component));
726

727 1
            while Present (F) loop
728

729 1
               Call_Parameters := New_List (CTN.K_Parameter_List);
730

731 1
               if Kind (F) = K_Port_Spec_Instance
732 1
                 and then Is_Out (F)
733 1
                 and then not Is_In (F)
734 1
                 and then Get_Connection_Pattern (F) = Inter_Process
735 1
                 and then not Is_Virtual (Get_Port_By_Name (F, Current_Device))
736
               then
737 1
                  if AIN.Is_Data (F) and then not Is_Event (F) then
738 1
                     Append_Node_To_List
739 1
                       (Make_Literal
740 1
                          (CV.New_Pointed_Char_Value (Map_Port_Name (F))),
741
                        Call_Parameters);
742

743 1
                     if Current_Device = No_Node then
744 1
                        N := Get_Inter_Partition_Port_Size (F);
745

746 1
                        if Is_Using_Virtual_Bus (F) then
747 0
                           Add_Include (RH (RH_Protocols));
748 0
                           Add_Define_Deployment (RE (RE_Pok_Needs_Protocols));
749
                        end if;
750
                     else
751
                        N :=
752 0
                          Get_Inter_Partition_Port_Size
753 0
                            (Get_Port_By_Name (F, Current_Device));
754

755 0
                        if Is_Using_Virtual_Bus
756 0
                            (Get_Port_By_Name (F, Current_Device))
757
                        then
758 0
                           Add_Include (RH (RH_Protocols));
759 0
                           Add_Define_Deployment (RE (RE_Pok_Needs_Protocols));
760
                        end if;
761
                     end if;
762

763 1
                     Append_Node_To_List (N, Call_Parameters);
764

765
                     --  Map the size of the port, take in account
766
                     --  potential virtual bus layers.
767

768 1
                     if Use_ARINC653_API then
769 1
                        Append_Node_To_List (RE (RE_Source), Call_Parameters);
770
                     else
771 0
                        Append_Node_To_List
772 0
                          (RE (RE_Pok_Port_Direction_Out),
773
                           Call_Parameters);
774
                     end if;
775

776 1
                     if Get_POK_Refresh_Time (F) /= Null_Time then
777

778 1
                        if Use_ARINC653_API then
779
                           N :=
780 1
                             Map_Time_To_Millisecond
781 1
                               (Get_POK_Refresh_Time (F));
782
                        else
783 0
                           N := Map_Time (Get_POK_Refresh_Time (F));
784
                        end if;
785

786
                     else
787 0
                        if POK_Flavor = DEOS then
788

789
                           --
790
                           --  DeOS needs a value to refresh the port.
791
                           --
792

793
                           N :=
794 0
                             CTU.Make_Literal
795 0
                               (CV.New_Int_Value (1_000_000, 1, 10));
796
                        else
797 0
                           N := CTU.Make_Literal (CV.New_Int_Value (0, 1, 10));
798
                        end if;
799
                     end if;
800

801 1
                     if POK_Flavor = VXWORKS then
802 1
                        N := RE (RE_Infinite_Time_Value);
803
                     end if;
804

805 1
                     Append_Node_To_List (N, Call_Parameters);
806

807 1
                     Append_Node_To_List
808 1
                       (Make_Variable_Address
809 1
                          (Make_Defining_Identifier (Map_Port_Var (F))),
810
                        Call_Parameters);
811

812 1
                     if Use_ARINC653_API then
813 1
                        Add_Return_Variable_In_Parameters (Call_Parameters);
814 1
                        Called_Function := RF (RE_Create_Sampling_Port);
815
                     else
816 0
                        Called_Function := RF (RE_Pok_Port_Sampling_Create);
817
                     end if;
818

819
                     N :=
820 1
                       POK_Make_Function_Call_With_Assert
821
                         (Called_Function,
822
                          Call_Parameters);
823 1
                     Append_Node_To_List (N, Statements);
824

825 1
                     POK_Add_Return_Assertion (Statements);
826

827 1
                     if Use_ARINC653_API then
828 1
                        Variable_Type := RE (RE_Sampling_Port_Id_Type);
829
                     else
830 0
                        Variable_Type := RE (RE_Uint8_T);
831
                     end if;
832

833 1
                     Append_Node_To_List
834 1
                       (Make_Variable_Declaration
835
                          (Defining_Identifier =>
836 1
                             (Make_Defining_Identifier (Map_Port_Var (F))),
837
                           Used_Type => (Variable_Type)),
838 1
                        CTN.Declarations (Current_File));
839

840
                     N :=
841 1
                       Message_Comment
842
                         ("This sampling port was mapped from an out" &
843
                          "data port contained in the process. It is" &
844
                          "used for inter-partition communication.");
845

846 1
                     CTU.Append_Node_To_List (N, Statements);
847 1
                  elsif AIN.Is_Data (F) and then Is_Event (F) then
848 1
                     Append_Node_To_List
849 1
                       (Make_Literal
850 1
                          (CV.New_Pointed_Char_Value (Map_Port_Name (F))),
851
                        Call_Parameters);
852

853 1
                     if POK_Flavor = POK then
854 0
                        N := Map_Queue_Size_With_Data (F);
855 0
                        Append_Node_To_List (N, Call_Parameters);
856
                     else
857
                        --  Map the size
858

859 1
                        N := Get_Data_Size (Corresponding_Instance (F));
860

861 1
                        Append_Node_To_List (N, Call_Parameters);
862

863
                        --  Map the queue size
864

865 1
                        N := Map_Queue_Size (F);
866 1
                        Append_Node_To_List (N, Call_Parameters);
867
                     end if;
868

869 1
                     if Use_ARINC653_API then
870 1
                        Added_Parameter := RE (RE_Source);
871
                     else
872 0
                        Added_Parameter := RE (RE_Pok_Port_Direction_Out);
873
                     end if;
874

875 1
                     Append_Node_To_List (Added_Parameter, Call_Parameters);
876

877 1
                     Added_Parameter := Map_Queueing_Policy (F);
878

879 1
                     Append_Node_To_List (Added_Parameter, Call_Parameters);
880

881 1
                     Append_Node_To_List
882 1
                       (Make_Variable_Address
883 1
                          (Make_Defining_Identifier (Map_Port_Var (F))),
884
                        Call_Parameters);
885

886 1
                     if Use_ARINC653_API then
887 1
                        Add_Return_Variable_In_Parameters (Call_Parameters);
888

889 1
                        Called_Function := RF (RE_Create_Queuing_Port);
890
                     else
891 0
                        Called_Function := RF (RE_Pok_Port_Queueing_Create);
892
                     end if;
893

894
                     N :=
895 1
                       POK_Make_Function_Call_With_Assert
896
                         (Called_Function,
897
                          Call_Parameters);
898

899 1
                     Append_Node_To_List (N, Statements);
900

901 1
                     POK_Add_Return_Assertion (Statements);
902

903 1
                     if Use_ARINC653_API then
904 1
                        Variable_Type := RE (RE_Queuing_Port_Id_Type);
905
                     else
906 0
                        Variable_Type := RE (RE_Uint8_T);
907
                     end if;
908

909 1
                     Append_Node_To_List
910 1
                       (Make_Variable_Declaration
911
                          (Defining_Identifier =>
912 1
                             (Make_Defining_Identifier (Map_Port_Var (F))),
913
                           Used_Type => (Variable_Type)),
914 1
                        CTN.Declarations (Current_File));
915

916
                     N :=
917 1
                       Message_Comment
918
                         ("This queueing port was mapped from an out " &
919
                          "event data port contained in the process. It" &
920
                          "is used for inter-partition communication.");
921

922 1
                     CTU.Append_Node_To_List (N, Statements);
923
                  end if;
924
               end if;
925 1
               F := Next_Node (F);
926 1
            end loop;
927
         end Setup_Out_Ports;
928

929
         -------------------------
930
         -- Setup_Virtual_Ports --
931
         -------------------------
932

933 1
         procedure Setup_Virtual_Ports is
934 1
            F : Node_Id;
935
         begin
936 1
            Call_Parameters := New_List (CTN.K_Parameter_List);
937

938 1
            if AINU.Is_Empty (Features (Communicating_Component)) then
939 0
               return;
940
            end if;
941

942 1
            F := First_Node (Features (Communicating_Component));
943

944 1
            while Present (F) loop
945 1
               Call_Parameters := New_List (CTN.K_Parameter_List);
946

947 1
               if Kind (F) = K_Port_Spec_Instance
948 1
                 and then Is_Data (F)
949 1
                 and then Get_Connection_Pattern (F) = Inter_Process
950 1
                 and then Is_Virtual (Get_Port_By_Name (F, Current_Device))
951
               then
952 0
                  Append_Node_To_List
953 0
                    (Make_Literal
954 0
                       (CV.New_Pointed_Char_Value (Map_Port_Name (F))),
955
                     Call_Parameters);
956

957 0
                  Append_Node_To_List
958 0
                    (Make_Variable_Address
959 0
                       (Make_Defining_Identifier (Map_Port_Var (F))),
960
                     Call_Parameters);
961

962
                  N :=
963 0
                    Make_Call_Profile
964 0
                      (RF (RE_Pok_Port_Virtual_Create),
965
                       Call_Parameters);
966 0
                  Append_Node_To_List (N, Statements);
967

968 0
                  Append_Node_To_List
969 0
                    (Make_Variable_Declaration
970
                       (Defining_Identifier =>
971 0
                          (Make_Defining_Identifier (Map_Port_Var (F))),
972 0
                        Used_Type => RE (RE_Uint8_T)),
973 0
                     CTN.Declarations (Current_File));
974
               end if;
975 1
               F := Next_Node (F);
976 1
            end loop;
977
         end Setup_Virtual_Ports;
978

979
      begin
980 1
         if Real_Process then
981
            U :=
982 1
              CTN.Distributed_Application_Unit
983 1
                (CTN.Naming_Node (Backend_Node (Identifier (E))));
984 1
            P := CTN.Entity (U);
985

986 1
            Push_Entity (P);
987 1
            Push_Entity (U);
988

989 1
            Communicating_Component := E;
990
         else
991 0
            Communicating_Component := Corresponding_Component;
992
         end if;
993

994 1
         Set_Main_Source;
995

996 1
         Use_Error_Handling := False;
997

998 1
         Thread_Id := 1;
999

1000 1
         Statements := New_List (CTN.K_Statement_List);
1001

1002 1
         Add_Include (E => RH (RH_Activity));
1003 1
         Add_Include (E => RH (RH_Gtypes));
1004

1005 1
         if Use_ARINC653_API then
1006 1
            Process_Variable_Type := RE (RE_Process_Id_Type);
1007 1
            Process_Variable_Name := RE (RE_Arinc_Threads);
1008
         else
1009 0
            Process_Variable_Type := RE (RE_Uint32_T);
1010 0
            Process_Variable_Name := RE (RE_Pok_Threads);
1011
         end if;
1012

1013
         --  Set up ports of the partition
1014 1
         Append_Node_To_List
1015 1
           (Make_Variable_Declaration
1016 1
              (CTU.Make_Array_Declaration
1017
                 (Defining_Identifier => Process_Variable_Name,
1018 1
                  Array_Size          => RE (RE_Pok_Config_Nb_Threads)),
1019
               Used_Type => Process_Variable_Type),
1020 1
            CTN.Declarations (Current_File));
1021

1022 1
         Set_Str_To_Name_Buffer ("tattr");
1023 1
         Tattr := Make_Defining_Identifier (Name_Find);
1024

1025 1
         if Use_ARINC653_API then
1026
            N :=
1027 1
              Make_Variable_Declaration
1028 1
                (Defining_Identifier => Copy_Node (Tattr),
1029 1
                 Used_Type           => RE (RE_Process_Attribute_Type));
1030
         else
1031
            N :=
1032 0
              Make_Variable_Declaration
1033 0
                (Defining_Identifier => Copy_Node (Tattr),
1034 0
                 Used_Type           => RE (RE_Pok_Thread_Attr_T));
1035
         end if;
1036

1037
         --  Declare the variable that contain
1038
         --  tasks/process attributes.
1039

1040 1
         Append_Node_To_List (N, Statements);
1041

1042 1
         POK_Declare_Return_Variable (Statements);
1043

1044 1
         Setup_In_Ports;
1045 1
         Setup_Out_Ports;
1046 1
         Setup_Virtual_Ports;
1047

1048
         --  Make the main function specification and add it in the current
1049
         --  file (main.c).
1050

1051
         Spec :=
1052 1
           Make_Function_Specification
1053 1
             (Defining_Identifier => RE (RE_Main),
1054
              Parameters          => No_List,
1055 1
              Return_Type         => RE (RE_Int));
1056

1057 1
         if Init_Function /= No_Node then
1058 0
            Append_Node_To_List (Init_Function, Statements);
1059
         end if;
1060

1061
         --  First, generate code to create semaphores associated
1062
         --  with data components.
1063 1
         if not AINU.Is_Empty (Subcomponents (E)) then
1064 1
            S := First_Node (Subcomponents (E));
1065 1
            while Present (S) loop
1066 1
               if AINU.Is_Data (Corresponding_Instance (S)) then
1067 0
                  Shared_Data := Corresponding_Instance (S);
1068
                  --  Automatically use the types.h header if we use
1069
                  --  protected data.
1070

1071 0
                  Add_Include (RH (RH_Types));
1072

1073
                  --  Declare the variable in the file
1074

1075
                  N :=
1076 0
                    Make_Variable_Declaration
1077 0
                      (Map_C_Defining_Identifier (S),
1078 0
                       Map_C_Data_Type_Designator (Shared_Data));
1079

1080 0
                  Append_Node_To_List (N, CTN.Declarations (Current_File));
1081

1082 0
                  Bind_AADL_To_Object (Identifier (S), N);
1083

1084
                  --  If the data needs to be protected, generate
1085
                  --  function call to create locking objects.
1086

1087 0
                  if Is_Protected_Data (Shared_Data) then
1088 0
                     Call_Parameters := New_List (CTN.K_Parameter_List);
1089

1090 0
                     if Use_ARINC653_API then
1091
                        --  Add the semaphore name.
1092 0
                        Append_Node_To_List
1093 0
                          (Make_Literal
1094 0
                             (CV.New_Pointed_Char_Value
1095 0
                                (Map_Associated_Locking_Entity_Name (S))),
1096
                           Call_Parameters);
1097

1098
                        --  Current semaphore value.
1099 0
                        Append_Node_To_List
1100 0
                          (Make_Literal (New_Int_Value (1, 1, 10)),
1101
                           Call_Parameters);
1102

1103
                        --  Maximum semaphore value.
1104 0
                        Append_Node_To_List
1105 0
                          (Make_Literal (New_Int_Value (1, 1, 10)),
1106
                           Call_Parameters);
1107

1108
                        --  Specify the queueing port discipline
1109 0
                        Append_Node_To_List (RE (RE_Fifo), Call_Parameters);
1110

1111 0
                        Append_Node_To_List
1112 0
                          (Make_Variable_Address
1113 0
                             (Make_Defining_Identifier
1114 0
                                (Map_Associated_Locking_Entity_Name (S))),
1115
                           Call_Parameters);
1116

1117 0
                        Add_Return_Variable_In_Parameters (Call_Parameters);
1118

1119
                        Function_Call :=
1120 0
                          POK_Make_Function_Call_With_Assert
1121 0
                            (RF (RE_Create_Semaphore),
1122
                             Call_Parameters);
1123
                     else
1124 0
                        Append_Node_To_List
1125 0
                          (Make_Variable_Address
1126 0
                             (Make_Defining_Identifier
1127 0
                                (Map_Associated_Locking_Entity_Name (S))),
1128
                           Call_Parameters);
1129

1130
                        --  Current semaphore value.
1131 0
                        Append_Node_To_List
1132 0
                          (Make_Literal (New_Int_Value (1, 1, 10)),
1133
                           Call_Parameters);
1134

1135
                        --  Maximum semaphore value.
1136 0
                        Append_Node_To_List
1137 0
                          (Make_Literal (New_Int_Value (1, 1, 10)),
1138
                           Call_Parameters);
1139

1140
                        --  Specify the queueing port discipline
1141 0
                        Append_Node_To_List
1142 0
                          (RE (RE_Pok_Semaphore_Discipline_Fifo),
1143
                           Call_Parameters);
1144

1145
                        Function_Call :=
1146 0
                          POK_Make_Function_Call_With_Assert
1147 0
                            (RF (RE_Pok_Sem_Create),
1148
                             Call_Parameters);
1149
                     end if;
1150

1151 0
                     Append_Node_To_List (Function_Call, Statements);
1152
                  end if;
1153
               end if;
1154

1155 1
               S := Next_Node (S);
1156 1
            end loop;
1157
         end if;
1158

1159
         --  Then, generate the other components
1160
         --  correspond to thread initialization.
1161

1162 1
         if not AINU.Is_Empty (Subcomponents (E)) then
1163 1
            S := First_Node (Subcomponents (E));
1164 1
            while Present (S) loop
1165 1
               Visit (Corresponding_Instance (S));
1166 1
               S := Next_Node (S);
1167 1
            end loop;
1168
         end if;
1169

1170 1
         if Use_Error_Handling then
1171 0
            Call_Parameters := New_List (CTN.K_Parameter_List);
1172

1173 0
            if Use_ARINC653_API then
1174 0
               Called_Function := RF (RE_Create_Error_Handler);
1175

1176 0
               Append_Node_To_List
1177 0
                 (RE (RE_Pok_Error_Handler_Worker),
1178
                  Call_Parameters);
1179

1180 0
               Append_Node_To_List
1181 0
                 (Make_Literal (CV.New_Int_Value (8192, 1, 10)),
1182
                  Call_Parameters);
1183

1184 0
               Add_Return_Variable_In_Parameters (Call_Parameters);
1185
            else
1186 0
               Called_Function := RF (RE_Pok_Error_Handler_Create);
1187
            end if;
1188

1189 0
            N := CTU.Make_Call_Profile (Called_Function, Call_Parameters);
1190 0
            Append_Node_To_List (N, Statements);
1191

1192 0
            POK_Add_Return_Assertion (Statements);
1193

1194
            N :=
1195 0
              Message_Comment
1196
                ("One thread inside the partition can raise faults." &
1197
                 "We start the error handle to treat these potential" &
1198
                 "faults.");
1199

1200 0
            CTU.Append_Node_To_List (N, Statements);
1201
         end if;
1202

1203
         --  Here, all threads were created. Put the partition
1204
         --  in the NORMAL state.
1205

1206 1
         if POK_Flavor = POK then
1207
            N :=
1208 0
              CTU.Make_Call_Profile
1209 0
                (RF (RE_Pok_Partition_Set_Mode),
1210 0
                 Make_List_Id (RE (RE_Pok_Partition_Mode_Normal)));
1211
         else
1212 1
            Call_Parameters := New_List (CTN.K_Parameter_List);
1213

1214 1
            Append_Node_To_List (RE (RE_Normal), Call_Parameters);
1215 1
            Add_Return_Variable_In_Parameters (Call_Parameters);
1216

1217
            N :=
1218 1
              CTU.Make_Call_Profile
1219 1
                (RF (RE_Set_Partition_Mode),
1220
                 Call_Parameters);
1221
         end if;
1222 1
         Append_Node_To_List (N, Statements);
1223

1224
         N :=
1225 1
           Message_Comment
1226
             ("Now, we created all resources of the process. Consequently," &
1227
              "this thread will not be used any more and it will be kept" &
1228
              "in a dormant state. By doing that, we also allow one more" &
1229
              "thread in this partition");
1230

1231 1
         CTU.Append_Node_To_List (N, Statements);
1232

1233
         N :=
1234 1
           CTU.Make_Return_Statement (Make_Literal (New_Int_Value (0, 1, 10)));
1235 1
         Append_Node_To_List (N, Statements);
1236

1237 1
         Main_Function :=
1238 1
           Make_Function_Implementation (Spec, Declarations, Statements);
1239

1240
         --  Now, we define the error handler callback.
1241
         --  This function is used each time an error is raised by
1242
         --  the kernel.
1243

1244 1
         if Use_Error_Handling then
1245 0
            Set_Deployment_Header;
1246

1247
            N :=
1248 0
              CTU.Make_Define_Statement
1249
                (Defining_Identifier =>
1250 0
                   RE (RE_Pok_Use_Generated_Error_Handler),
1251 0
                 Value => CTU.Make_Literal (CV.New_Int_Value (1, 1, 10)));
1252

1253 0
            CTU.Append_Node_To_List (N, CTN.Declarations (CTU.Current_File));
1254

1255 0
            Set_Main_Source;
1256

1257 0
            Declarations := New_List (CTN.K_Declaration_List);
1258 0
            Statements   := New_List (CTN.K_Statement_List);
1259

1260 0
            if Use_ARINC653_API then
1261 0
               Used_Type := RE (RE_Error_Status_Type);
1262
            else
1263 0
               Used_Type := RE (RE_Pok_Error_Status_T);
1264
            end if;
1265

1266 0
            Append_Node_To_List
1267 0
              (Make_Variable_Declaration
1268
                 (Defining_Identifier =>
1269 0
                    Make_Defining_Identifier (VN (V_Error_Status)),
1270
                  Used_Type => Used_Type),
1271
               Statements);
1272

1273 0
            if Use_ARINC653_API then
1274 0
               Append_Node_To_List
1275 0
                 (Make_Variable_Declaration
1276
                    (Defining_Identifier =>
1277 0
                       Make_Defining_Identifier (VN (V_Ret)),
1278 0
                     Used_Type => RE (RE_Return_Code_Type)),
1279
                  Statements);
1280
            end if;
1281

1282
            N :=
1283 0
              Message_Comment
1284
                ("The variables error and thread are created" &
1285
                 "to store the thread-id and the error-id" &
1286
                 "when a fault is raised");
1287

1288 0
            CTU.Append_Node_To_List (N, Statements);
1289

1290
            N :=
1291 0
              Message_Comment
1292
                ("We prefer to force a default value to the variables" &
1293
                 "error and thread");
1294 0
            Append_Node_To_List (N, Statements);
1295

1296
            --  Here, we initialize the variables to be sure to have
1297
            --  a good default value.
1298

1299 0
            Call_Parameters := New_List (CTN.K_Parameter_List);
1300

1301 0
            Append_Node_To_List
1302 0
              (Make_Variable_Address
1303 0
                 (Make_Defining_Identifier (VN (V_Error_Status))),
1304
               Call_Parameters);
1305

1306
            N :=
1307 0
              Message_Comment
1308
                ("Here, we declare the fault handler as ready and" &
1309
                 "that faulty thread-id and error-id must be stored" &
1310
                 "in the thread and error variables");
1311

1312 0
            CTU.Append_Node_To_List (N, Statements);
1313

1314 0
            if Use_ARINC653_API then
1315 0
               Called_Function := RF (RE_Stop_Self);
1316
            else
1317 0
               Called_Function := RF (RE_Pok_Thread_Stop_Self);
1318
            end if;
1319

1320 0
            Append_Node_To_List
1321 0
              (Make_Call_Profile (Called_Function, No_List),
1322
               While_Statements);
1323

1324 0
            if Use_ARINC653_API then
1325 0
               Called_Function := RF (RE_Get_Error_Status);
1326
            else
1327 0
               Called_Function := RF (RE_Pok_Error_Get);
1328
            end if;
1329

1330 0
            Call_Parameters := New_List (CTN.K_Parameter_List);
1331

1332 0
            Append_Node_To_List
1333 0
              (Make_Variable_Address
1334 0
                 (Make_Defining_Identifier (VN (V_Error_Status))),
1335
               Call_Parameters);
1336

1337 0
            if Use_ARINC653_API then
1338 0
               Append_Node_To_List
1339 0
                 (Make_Variable_Address
1340 0
                    (Make_Defining_Identifier (VN (V_Ret))),
1341
                  Call_Parameters);
1342
            end if;
1343

1344 0
            Append_Node_To_List
1345 0
              (Make_Call_Profile (Called_Function, Call_Parameters),
1346
               While_Statements);
1347

1348 0
            if Use_ARINC653_API then
1349 0
               Used_Member := RE (RE_Failed_Process_Id);
1350
            else
1351 0
               Used_Member := Make_Defining_Identifier (MN (M_Failed_Thread));
1352
            end if;
1353 0
            Append_Node_To_List
1354 0
              (Make_Switch_Statement
1355 0
                 (Make_Member_Designator
1356
                    (Used_Member,
1357 0
                     Make_Defining_Identifier (VN (V_Error_Status))),
1358
                  Error_Switch_Alternatives),
1359
               While_Statements);
1360

1361
            --  We declare the while (1) loop executed by the task
1362

1363 0
            Append_Node_To_List
1364 0
              (Make_While_Statement
1365 0
                 (Make_Literal (CV.New_Int_Value (1, 0, 10)),
1366
                  While_Statements),
1367
               Statements);
1368

1369
            Spec :=
1370 0
              Make_Function_Specification
1371 0
                (Defining_Identifier => RE (RE_Pok_Error_Handler_Worker),
1372
                 Parameters          => No_List,
1373 0
                 Return_Type => Make_Defining_Identifier (TN (T_Void)));
1374

1375 0
            Append_Node_To_List
1376 0
              (Make_Function_Implementation (Spec, Declarations, Statements),
1377 0
               CTN.Declarations (Current_File));
1378

1379
            N :=
1380 0
              Message_Comment
1381
                ("IMPORTANT : this main function creates all resources " &
1382
                 "(ports, data, tasks/threads/processes used by this   " &
1383
                 "node");
1384

1385 0
            CTU.Append_Node_To_List (N, Statements);
1386

1387
            --  Finally, we implement the main function that handles errors.
1388
         end if;
1389

1390 1
         Append_Node_To_List (Main_Function, CTN.Declarations (Current_File));
1391

1392 1
         if Real_Process then
1393 1
            Pop_Entity; -- U
1394 1
            Pop_Entity; -- P
1395
         end if;
1396 1
      end Visit_Process_Instance;
1397

1398
      ---------------------------
1399
      -- Visit_System_Instance --
1400
      ---------------------------
1401

1402 1
      procedure Visit_System_Instance (E : Node_Id) is
1403 1
         S : Node_Id;
1404
      begin
1405
         --  Visit all the subcomponents of the system
1406

1407 1
         if not AINU.Is_Empty (Subcomponents (E)) then
1408 1
            S := First_Node (Subcomponents (E));
1409 1
            while Present (S) loop
1410
               --  Visit the component instance corresponding to the
1411
               --  subcomponent S.
1412 1
               if AINU.Is_Processor (Corresponding_Instance (S)) then
1413 1
                  Visit (Corresponding_Instance (S));
1414
               end if;
1415 1
               S := Next_Node (S);
1416 1
            end loop;
1417
         end if;
1418 1
      end Visit_System_Instance;
1419

1420
      ---------------------------
1421
      -- Visit_Device_Instance --
1422
      ---------------------------
1423

1424 0
      procedure Visit_Device_Instance (E : Node_Id) is
1425
         U : constant Node_Id :=
1426 0
           CTN.Distributed_Application_Unit
1427 0
             (CTN.Naming_Node (Backend_Node (Identifier (E))));
1428 0
         P              : constant Node_Id := CTN.Entity (U);
1429 0
         Implementation : Node_Id;
1430 0
         S              : Node_Id;
1431 0
         Entrypoint : constant Node_Id := Get_Thread_Initialize_Entrypoint (E);
1432
      begin
1433 0
         Push_Entity (P);
1434 0
         Push_Entity (U);
1435

1436 0
         Set_Main_Source;
1437

1438 0
         Current_Device := E;
1439

1440 0
         if Entrypoint /= No_Node then
1441 0
            Init_Function :=
1442 0
              Make_Call_Profile (Map_C_Subprogram_Identifier (Entrypoint));
1443
         end if;
1444

1445 0
         Implementation := Get_Classifier_Property (E, "implemented_as");
1446

1447 0
         if Implementation /= No_Node then
1448 0
            if not AINU.Is_Empty (AIN.Subcomponents (Implementation)) then
1449 0
               S := First_Node (Subcomponents (Implementation));
1450 0
               while Present (S) loop
1451 0
                  if Get_Category_Of_Component (S) = CC_Process then
1452 0
                     Visit_Process_Instance
1453 0
                       (Corresponding_Instance (S),
1454
                        False,
1455
                        E);
1456
                  end if;
1457

1458 0
                  S := Next_Node (S);
1459 0
               end loop;
1460
            end if;
1461
         end if;
1462

1463 0
         Init_Function := No_Node;
1464

1465 0
         Current_Device := No_Node;
1466

1467 0
         Pop_Entity; -- U
1468 0
         Pop_Entity; -- P
1469 0
      end Visit_Device_Instance;
1470

1471
      --------------------------------------
1472
      -- Visit_Virtual_Processor_Instance --
1473
      --------------------------------------
1474

1475 1
      procedure Visit_Virtual_Processor_Instance (E : Node_Id) is
1476 1
         S         : Node_Id;
1477 1
         U         : Node_Id;
1478 1
         Processes : List_Id;
1479
      begin
1480 1
         if Present (Backend_Node (Identifier (E))) then
1481 1
            Processes := CTN.Processes (Backend_Node (Identifier (E)));
1482 1
            S         := AIN.First_Node (Processes);
1483 1
            while Present (S) loop
1484 1
               U := Current_Entity;
1485 1
               Pop_Entity;
1486 1
               Visit (AIN.Item (S));
1487 1
               Push_Entity (U);
1488 1
               S := AIN.Next_Node (S);
1489 1
            end loop;
1490
         end if;
1491 1
      end Visit_Virtual_Processor_Instance;
1492

1493
      ------------------------------
1494
      -- Visit_Processor_Instance --
1495
      ------------------------------
1496

1497 1
      procedure Visit_Processor_Instance (E : Node_Id) is
1498 1
         S : Node_Id;
1499 1
         U : Node_Id;
1500 1
         P : Node_Id;
1501
      begin
1502 1
         U := CTN.Naming_Node (Backend_Node (Identifier (E)));
1503 1
         P := CTN.Entity (U);
1504

1505 1
         Push_Entity (C_Root);
1506

1507 1
         Runtime.Register_Kernel_Unit (U);
1508

1509 1
         Push_Entity (P);
1510 1
         Push_Entity (U);
1511

1512 1
         if not AINU.Is_Empty (Subcomponents (E)) then
1513 1
            S := First_Node (Subcomponents (E));
1514 1
            while Present (S) loop
1515

1516 1
               Visit (Corresponding_Instance (S));
1517

1518 1
               S := Next_Node (S);
1519 1
            end loop;
1520
         end if;
1521

1522 1
         Pop_Entity;
1523 1
         Pop_Entity;
1524 1
         Pop_Entity;
1525 1
      end Visit_Processor_Instance;
1526

1527
      ---------------------------
1528
      -- Visit_Thread_Instance --
1529
      ---------------------------
1530

1531 1
      procedure Visit_Thread_Instance (E : Node_Id) is
1532

1533 1
         procedure Setup_Ports is
1534 1
            F               : Node_Id;
1535 1
            Call_Parameters : List_Id;
1536 1
            Called_Function : Node_Id;
1537 1
            Type_Used       : Node_Id;
1538 1
            N               : Node_Id;
1539
         begin
1540 1
            if AINU.Is_Empty (Features (E)) then
1541 0
               return;
1542
            end if;
1543

1544 1
            F := AIN.First_Node (Features (E));
1545 1
            while Present (F) loop
1546 1
               Call_Parameters := New_List (CTN.K_Parameter_List);
1547

1548 1
               if Kind (F) = K_Port_Spec_Instance
1549 1
                 and then Is_In (F)
1550 1
                 and then not Is_Out (F)
1551 1
                 and then Get_Port_By_Name (F, Current_Device) = No_Node
1552 1
                 and then Get_Connection_Pattern (F) = Intra_Process
1553
               then
1554 1
                  if AIN.Is_Data (F) and then not AIN.Is_Event (F) then
1555 1
                     Append_Node_To_List
1556 1
                       (Make_Literal
1557 1
                          (CV.New_Pointed_Char_Value (Map_Port_Name (F))),
1558
                        Call_Parameters);
1559

1560 1
                     N := CTU.Get_Data_Size (Corresponding_Instance (F));
1561 1
                     Append_Node_To_List (N, Call_Parameters);
1562

1563 1
                     Append_Node_To_List
1564 1
                       (Make_Variable_Address
1565 1
                          (Make_Defining_Identifier (Map_Port_Var (F))),
1566
                        Call_Parameters);
1567

1568 1
                     if Use_ARINC653_API then
1569 1
                        Add_Return_Variable_In_Parameters (Call_Parameters);
1570

1571 1
                        Called_Function := RF (RE_Create_Blackboard);
1572 1
                        Type_Used       := RE (RE_Blackboard_Id_Type);
1573
                     else
1574 0
                        Called_Function := RF (RE_Pok_Blackboard_Create);
1575 0
                        Type_Used       := RE (RE_Uint8_T);
1576
                     end if;
1577

1578
                     N :=
1579 1
                       POK_Make_Function_Call_With_Assert
1580
                         (Called_Function,
1581
                          Call_Parameters);
1582 1
                     Append_Node_To_List (N, Statements);
1583

1584 1
                     POK_Add_Return_Assertion (Statements);
1585

1586 1
                     Append_Node_To_List
1587 1
                       (Make_Extern_Entity_Declaration
1588 1
                          (Make_Variable_Declaration
1589
                             (Defining_Identifier =>
1590 1
                                (Make_Defining_Identifier (Map_Port_Var (F))),
1591
                              Used_Type => Type_Used)),
1592 1
                        CTN.Declarations (Current_File));
1593

1594 1
                  elsif AIN.Is_Data (F)
1595 1
                    and then Is_Event (F)
1596 1
                    and then Is_In (F)
1597
                  then
1598 1
                     if Use_ARINC653_API then
1599 1
                        Append_Node_To_List
1600 1
                          (Make_Literal
1601 1
                             (CV.New_Pointed_Char_Value (Map_Port_Name (F))),
1602
                           Call_Parameters);
1603

1604 1
                        N := CTU.Get_Data_Size (Corresponding_Instance (F));
1605 1
                        Append_Node_To_List (N, Call_Parameters);
1606

1607 1
                        N := Map_Queue_Size (F);
1608 1
                        Append_Node_To_List (N, Call_Parameters);
1609

1610 1
                        Append_Node_To_List
1611 1
                          (Map_Queueing_Policy (F),
1612
                           Call_Parameters);
1613

1614 1
                        Append_Node_To_List
1615 1
                          (Make_Variable_Address
1616 1
                             (Make_Defining_Identifier (Map_Port_Var (F))),
1617
                           Call_Parameters);
1618

1619 1
                        Add_Return_Variable_In_Parameters (Call_Parameters);
1620

1621 1
                        Called_Function := RF (RE_Create_Buffer);
1622 1
                        Type_Used       := RE (RE_Buffer_Id_Type);
1623
                     else
1624 0
                        Append_Node_To_List
1625 0
                          (Make_Literal
1626 0
                             (CV.New_Pointed_Char_Value (Map_Port_Name (F))),
1627
                           Call_Parameters);
1628

1629 0
                        N := Map_Queue_Size (F);
1630 0
                        Append_Node_To_List (N, Call_Parameters);
1631

1632 0
                        N := CTU.Get_Data_Size (Corresponding_Instance (F));
1633 0
                        Append_Node_To_List (N, Call_Parameters);
1634

1635 0
                        Append_Node_To_List
1636 0
                          (Map_Queueing_Policy (F),
1637
                           Call_Parameters);
1638

1639 0
                        Append_Node_To_List
1640 0
                          (Make_Variable_Address
1641 0
                             (Make_Defining_Identifier (Map_Port_Var (F))),
1642
                           Call_Parameters);
1643

1644 0
                        Called_Function := RF (RE_Pok_Buffer_Create);
1645 0
                        Type_Used       := RE (RE_Uint8_T);
1646
                     end if;
1647

1648
                     N :=
1649 1
                       POK_Make_Function_Call_With_Assert
1650
                         (Called_Function,
1651
                          Call_Parameters);
1652 1
                     Append_Node_To_List (N, Statements);
1653

1654 1
                     POK_Add_Return_Assertion (Statements);
1655

1656 1
                     Append_Node_To_List
1657 1
                       (Make_Extern_Entity_Declaration
1658 1
                          (Make_Variable_Declaration
1659
                             (Defining_Identifier =>
1660 1
                                (Make_Defining_Identifier (Map_Port_Var (F))),
1661
                              Used_Type => Type_Used)),
1662 1
                        CTN.Declarations (Current_File));
1663 0
                  elsif not AIN.Is_Data (F)
1664 0
                    and then Is_Event (F)
1665 0
                    and then Is_In (F)
1666
                  then
1667 0
                     if Use_ARINC653_API then
1668 0
                        Append_Node_To_List
1669 0
                          (Make_Literal
1670 0
                             (CV.New_Pointed_Char_Value (Map_Port_Name (F))),
1671
                           Call_Parameters);
1672

1673 0
                        Append_Node_To_List
1674 0
                          (Make_Variable_Address
1675 0
                             (Make_Defining_Identifier (Map_Port_Var (F))),
1676
                           Call_Parameters);
1677

1678 0
                        Add_Return_Variable_In_Parameters (Call_Parameters);
1679

1680 0
                        Called_Function := RF (RE_Create_Event);
1681 0
                        Type_Used       := RE (RE_Event_Id_Type);
1682
                     else
1683 0
                        Append_Node_To_List
1684 0
                          (Make_Variable_Address
1685 0
                             (Make_Defining_Identifier (Map_Port_Var (F))),
1686
                           Call_Parameters);
1687

1688 0
                        Called_Function := RF (RE_Pok_Event_Create);
1689 0
                        Type_Used       := RE (RE_Pok_Event_Id_T);
1690
                     end if;
1691

1692
                     N :=
1693 0
                       POK_Make_Function_Call_With_Assert
1694
                         (Called_Function,
1695
                          Call_Parameters);
1696 0
                     Append_Node_To_List (N, Statements);
1697

1698 0
                     POK_Add_Return_Assertion (Statements);
1699

1700 0
                     Append_Node_To_List
1701 0
                       (Make_Extern_Entity_Declaration
1702 0
                          (Make_Variable_Declaration
1703
                             (Defining_Identifier =>
1704 0
                                (Make_Defining_Identifier (Map_Port_Var (F))),
1705
                              Used_Type => Type_Used)),
1706 0
                        CTN.Declarations (Current_File));
1707
                  else
1708 0
                     Display_Communication_Error;
1709
                  end if;
1710
               end if;
1711 1
               F := Next_Node (F);
1712 1
            end loop;
1713
         end Setup_Ports;
1714

1715 1
         Used_Member : Node_Id;
1716
      begin
1717 1
         Setup_Ports;
1718 1
         Setup_Thread (E);
1719

1720 1
         Runtime.POK_Mode;
1721

1722 1
         if Get_POK_Recovery_Errors (E) /= POK_Empty_Handled_Errors then
1723 0
            declare
1724 0
               POK_Errors : constant POK_Handled_Errors :=
1725 0
                 Get_POK_Recovery_Errors (E);
1726 0
               POK_Actions : constant POK_Handled_Actions :=
1727 0
                 Get_POK_Recovery_Actions (E);
1728 0
               POK_Error : Node_Id;
1729
               --  Corresponding error code in the POK runtime.
1730

1731 0
               Error : Supported_POK_Error;
1732
               --  Error code from the model.
1733

1734 0
               Action : Supported_POK_Action;
1735
               --  Error code from the model.
1736

1737 0
               Comment : Node_Id;
1738

1739
               Thread_Switch_Alternatives : constant List_Id :=
1740 0
                 New_List (CTN.K_Alternatives_List);
1741
            begin
1742 0
               Use_Error_Handling := True;
1743

1744 0
               for Error_Id in POK_Errors'Range loop
1745
                  --  Here, for each error, we take its associated
1746
                  --  actions and call the right function to recover
1747
                  --  the error.
1748

1749 0
                  Error := POK_Errors (Error_Id);
1750
                  --  This array correspond to the property
1751
                  --  POK_Recovery_Errors.
1752

1753 0
                  Action := POK_Actions (Error_Id);
1754
                  --  This array correspond to the property
1755
                  --  POK_Recovery_Actions.
1756

1757 0
                  POK_Error := Map_POK_Error (Error);
1758

1759 0
                  if POK_Error /= No_Node then
1760 0
                     Append_Node_To_List
1761 0
                       (Make_Switch_Alternative
1762 0
                          (Make_List_Id (POK_Error),
1763 0
                           Make_List_Id
1764 0
                             (Map_POK_Action (Action, Thread_Id, POK_Error))),
1765
                        Thread_Switch_Alternatives);
1766
                  end if;
1767 0
               end loop;
1768

1769 0
               if Use_ARINC653_API then
1770 0
                  Used_Member := RE (RE_Error_Code);
1771
               else
1772 0
                  Used_Member := Make_Defining_Identifier (MN (M_Error_Kind));
1773
               end if;
1774

1775 0
               Append_Node_To_List
1776 0
                 (Make_Switch_Alternative
1777 0
                    (Make_List_Id
1778 0
                       (Make_Literal (New_Int_Value (Thread_Id, 1, 10))),
1779 0
                     Make_List_Id
1780 0
                       (Make_Switch_Statement
1781 0
                          (Make_Member_Designator
1782
                             (Used_Member,
1783 0
                              Make_Defining_Identifier (VN (V_Error_Status))),
1784
                           Thread_Switch_Alternatives))),
1785
                  Error_Switch_Alternatives);
1786

1787
               --  Here, we make a switch statement that is added
1788
               --  to a global switch that choose the thread.
1789

1790
               Comment :=
1791 0
                 Message_Comment
1792
                   ("Here, we declare the error handling mecanisms " &
1793
                    "for the task");
1794 0
               Append_Node_To_List (Comment, Error_Switch_Alternatives);
1795 0
            end;
1796
         end if;
1797

1798 1
         if Get_ARINC653_HM_Errors (E) /= ARINC653_Empty_Errors then
1799 0
            declare
1800 0
               Errors : constant ARINC653_Errors := Get_ARINC653_HM_Errors (E);
1801

1802 0
               Actions : constant ARINC653_Actions :=
1803 0
                 Get_ARINC653_HM_Actions (E);
1804

1805 0
               Error : Supported_ARINC653_Error;
1806
               --  The error code of the model.
1807

1808 0
               Action : Supported_ARINC653_Action;
1809
               --  The action of the model.
1810

1811 0
               POK_Error : Node_Id;
1812
               --  Corresponding error code in the POK runtime.
1813

1814 0
               Comment : Node_Id;
1815

1816
               Thread_Switch_Alternatives : constant List_Id :=
1817 0
                 New_List (CTN.K_Alternatives_List);
1818
            begin
1819 0
               Use_Error_Handling := True;
1820

1821 0
               for Error_Id in Errors'Range loop
1822
                  --  Here, for each error, we take its associated
1823
                  --  actions and call the right function to recover
1824
                  --  the error.
1825

1826 0
                  Error := Errors (Error_Id);
1827

1828 0
                  Action := Actions (Error_Id);
1829

1830 0
                  POK_Error := Map_ARINC653_Error (Error);
1831

1832 0
                  if POK_Error /= No_Node then
1833 0
                     Append_Node_To_List
1834 0
                       (Make_Switch_Alternative
1835 0
                          (Make_List_Id (POK_Error),
1836 0
                           Make_List_Id
1837 0
                             (Map_POK_Action (Action, Thread_Id, POK_Error))),
1838
                        Thread_Switch_Alternatives);
1839
                  end if;
1840 0
               end loop;
1841

1842 0
               if Use_ARINC653_API then
1843 0
                  Used_Member := RE (RE_Error_Code);
1844
               else
1845 0
                  Used_Member := Make_Defining_Identifier (MN (M_Error_Kind));
1846
               end if;
1847

1848 0
               Append_Node_To_List
1849 0
                 (Make_Switch_Alternative
1850 0
                    (Make_List_Id
1851 0
                       (Make_Literal (New_Int_Value (Thread_Id, 1, 10))),
1852 0
                     Make_List_Id
1853 0
                       (Make_Switch_Statement
1854 0
                          (Make_Member_Designator
1855
                             (Used_Member,
1856 0
                              Make_Defining_Identifier (VN (V_Error_Status))),
1857
                           Thread_Switch_Alternatives))),
1858
                  Error_Switch_Alternatives);
1859

1860
               --  Here, we make a switch statement that is added
1861
               --  to a global switch that choose the thread.
1862

1863
               Comment :=
1864 0
                 Message_Comment
1865
                   ("Here, we declare the error handling mecanisms " &
1866
                    "for the task");
1867 0
               Append_Node_To_List (Comment, Error_Switch_Alternatives);
1868 0
            end;
1869
         end if;
1870

1871 1
         Runtime.Normal_Mode;
1872

1873 1
         Thread_Id := Thread_Id + 1;
1874 1
      end Visit_Thread_Instance;
1875

1876
   end Source_File;
1877

1878 1
end Ocarina.Backends.POK_C.Main;

Read our documentation on viewing source code .

Loading