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 _ H I _ C . A C T I V I T Y     --
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

35
with Ocarina.ME_AADL;
36
with Ocarina.ME_AADL.AADL_Instances.Nodes;
37
with Ocarina.ME_AADL.AADL_Instances.Nutils;
38
with Ocarina.Backends.Utils;
39
with Ocarina.ME_AADL.AADL_Instances.Entities;
40
with Ocarina.Backends.Properties;
41
with Ocarina.Backends.C_Tree.Nutils;
42
with Ocarina.Backends.C_Tree.Nodes;
43
with Ocarina.Backends.C_Common.Mapping;
44
with Ocarina.Backends.PO_HI_C.Runtime;
45
with Ocarina.Backends.C_Values;
46
with Ocarina.Backends.Messages;
47
with Ocarina.Backends.C_Common.BA;
48
with Ocarina.ME_AADL_BA.BA_Tree.Nutils;
49
with Ocarina.ME_AADL_BA.BA_Tree.Nodes;
50

51 1
package body Ocarina.Backends.PO_HI_C.Activity is
52

53
   use Ocarina.Namet;
54
   use Ocarina.ME_AADL;
55
   use Ocarina.ME_AADL.AADL_Instances.Nodes;
56
   use Ocarina.Backends.Utils;
57
   use Ocarina.ME_AADL.AADL_Instances.Entities;
58
   use Ocarina.Backends.Properties;
59
   use Ocarina.Backends.C_Tree.Nutils;
60
   use Ocarina.Backends.C_Common.Mapping;
61
   use Ocarina.Backends.PO_HI_C.Runtime;
62
   use Ocarina.Backends.Messages;
63
   use Ocarina.Backends.C_Common.BA;
64

65
   package AAU renames Ocarina.ME_AADL.AADL_Instances.Nutils;
66
   package AAN renames Ocarina.ME_AADL.AADL_Instances.Nodes;
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
   package BATN renames Ocarina.ME_AADL_BA.BA_Tree.Nodes;
71
   package BANu renames Ocarina.ME_AADL_BA.BA_Tree.Nutils;
72

73
   Current_Device : Node_Id := No_Node;
74

75
   ------------
76
   -- Header --
77
   ------------
78

79
   package body Header_File is
80

81
      procedure Visit_Architecture_Instance (E : Node_Id);
82
      procedure Visit_Component_Instance (E : Node_Id);
83
      procedure Visit_System_Instance (E : Node_Id);
84
      procedure Visit_Process_Instance (E : Node_Id);
85
      procedure Visit_Device_Instance (E : Node_Id);
86
      procedure Visit_Thread_Instance (E : Node_Id);
87
      function Task_Job_Spec (E : Node_Id) return Node_Id;
88
      function Task_Deliver_Spec (E : Node_Id) return Node_Id;
89

90
      Have_Main_Deliver : Boolean := False;
91

92
      -------------------
93
      -- Task_Job_Spec --
94
      -------------------
95

96 1
      function Task_Job_Spec (E : Node_Id) return Node_Id is
97 1
         N : Node_Id;
98 1
         S : constant Node_Id := Parent_Subcomponent (E);
99
      begin
100
         N :=
101 1
           Make_Function_Specification
102
             (Defining_Identifier =>
103 1
                Map_Task_Job_Identifier (S, Current_Device),
104
              Parameters  => No_List,
105 1
              Return_Type => CTU.Make_Pointer_Type (New_Node (CTN.K_Void)));
106 1
         return N;
107
      end Task_Job_Spec;
108

109
      -----------------------
110
      -- Task_Deliver_Spec --
111
      -----------------------
112

113 1
      function Task_Deliver_Spec (E : Node_Id) return Node_Id is
114 1
         N          : Node_Id;
115 1
         S          : constant Node_Id := Parent_Subcomponent (E);
116 1
         Parameters : constant List_Id := New_List (CTN.K_Parameter_List);
117
      begin
118
         N :=
119 1
           Make_Parameter_Specification
120 1
             (Defining_Identifier => Make_Defining_Identifier (PN (P_Request)),
121 1
              Parameter_Type      => Make_Pointer_Type (RE (RE_Request_T)));
122 1
         Append_Node_To_List (N, Parameters);
123

124
         N :=
125 1
           Make_Function_Specification
126 1
             (Defining_Identifier => Map_Task_Deliver_Identifier (S),
127
              Parameters          => Parameters,
128 1
              Return_Type         => New_Node (CTN.K_Void));
129

130 1
         Have_Main_Deliver := True;
131

132 1
         return N;
133
      end Task_Deliver_Spec;
134

135
      -----------
136
      -- Visit --
137
      -----------
138

139 1
      procedure Visit (E : Node_Id) is
140
      begin
141 1
         case Kind (E) is
142 1
            when K_Architecture_Instance =>
143 1
               Visit_Architecture_Instance (E);
144

145 1
            when K_Component_Instance =>
146 1
               Visit_Component_Instance (E);
147

148 0
            when others =>
149 0
               null;
150 1
         end case;
151 1
      end Visit;
152

153
      ---------------------------------
154
      -- Visit_Architecture_Instance --
155
      ---------------------------------
156

157 1
      procedure Visit_Architecture_Instance (E : Node_Id) is
158
      begin
159 1
         Visit (Root_System (E));
160 1
      end Visit_Architecture_Instance;
161

162
      ------------------------------
163
      -- Visit_Component_Instance --
164
      ------------------------------
165

166 1
      procedure Visit_Component_Instance (E : Node_Id) is
167
         Category : constant Component_Category :=
168 1
           Get_Category_Of_Component (E);
169
      begin
170 1
         case Category is
171 1
            when CC_System =>
172 1
               Visit_System_Instance (E);
173

174 1
            when CC_Process =>
175 1
               Visit_Process_Instance (E);
176

177 1
            when CC_Thread =>
178 1
               Visit_Thread_Instance (E);
179

180 1
            when others =>
181 1
               null;
182 1
         end case;
183 1
      end Visit_Component_Instance;
184

185
      ----------------------------
186
      -- Visit_Process_Instance --
187
      ----------------------------
188

189 1
      procedure Visit_Process_Instance (E : Node_Id) is
190
         U : constant Node_Id :=
191 1
           CTN.Distributed_Application_Unit
192 1
             (CTN.Naming_Node (Backend_Node (Identifier (E))));
193 1
         P          : constant Node_Id := CTN.Entity (U);
194 1
         Parameters : constant List_Id := New_List (CTN.K_Parameter_List);
195 1
         S          : Node_Id;
196 1
         N          : Node_Id;
197
         The_System : constant Node_Id :=
198 1
           Parent_Component (Parent_Subcomponent (E));
199
      begin
200 1
         Push_Entity (P);
201 1
         Push_Entity (U);
202 1
         Set_Activity_Header (U);
203

204 1
         Have_Main_Deliver := False;
205

206 1
         if not AAU.Is_Empty (Subcomponents (E)) then
207 1
            S := First_Node (Subcomponents (E));
208 1
            while Present (S) loop
209

210 1
               Visit (Corresponding_Instance (S));
211

212 1
               S := Next_Node (S);
213 1
            end loop;
214
         end if;
215

216 1
         if Have_Main_Deliver then
217
            N :=
218 1
              Make_Parameter_Specification
219
                (Defining_Identifier =>
220 1
                   Make_Defining_Identifier (PN (P_Request)),
221 1
                 Parameter_Type => Make_Pointer_Type (RE (RE_Request_T)));
222 1
            Append_Node_To_List (N, Parameters);
223

224
            N :=
225 1
              Make_Function_Specification
226 1
                (Defining_Identifier => RE (RE_Main_Deliver),
227
                 Parameters          => Parameters,
228 1
                 Return_Type         => New_Node (CTN.K_Void));
229

230 1
            Append_Node_To_List (N, CTN.Declarations (Current_File));
231

232 1
            Bind_AADL_To_Job (Identifier (Parent_Subcomponent (E)), N);
233
         end if;
234

235
         --  Visit all devices attached to the parent system that
236
         --  share the same processor as process E.
237

238 1
         if not AAU.Is_Empty (Subcomponents (The_System)) then
239 1
            S := First_Node (Subcomponents (The_System));
240 1
            while Present (S) loop
241 1
               if AAU.Is_Device (Corresponding_Instance (S))
242
                 and then
243 1
                 Get_Bound_Processor (Corresponding_Instance (S)) =
244 1
                 Get_Bound_Processor (E)
245
               then
246 1
                  Visit_Device_Instance (Corresponding_Instance (S));
247
               end if;
248 1
               S := Next_Node (S);
249 1
            end loop;
250
         end if;
251

252 1
         Pop_Entity; -- U
253 1
         Pop_Entity; -- P
254 1
      end Visit_Process_Instance;
255

256
      ---------------------------
257
      -- Visit_Device_Instance --
258
      ---------------------------
259

260 1
      procedure Visit_Device_Instance (E : Node_Id) is
261 1
         Implementation : constant Node_Id := Get_Implementation (E);
262 1
         S              : Node_Id;
263
      begin
264 1
         Current_Device := E;
265 1
         if Implementation /= No_Node then
266 1
            if not AAU.Is_Empty (AAN.Subcomponents (Implementation)) then
267 1
               S := First_Node (Subcomponents (Implementation));
268 1
               while Present (S) loop
269 1
                  Visit_Component_Instance (Corresponding_Instance (S));
270 1
                  S := Next_Node (S);
271 1
               end loop;
272
            end if;
273
         end if;
274 1
         Current_Device := No_Node;
275 1
      end Visit_Device_Instance;
276

277
      ---------------------------
278
      -- Visit_System_Instance --
279
      ---------------------------
280

281 1
      procedure Visit_System_Instance (E : Node_Id) is
282 1
         S : Node_Id;
283
      begin
284 1
         Push_Entity (C_Root);
285

286
         --  Visit all the subcomponents of the system
287

288 1
         if not AAU.Is_Empty (Subcomponents (E)) then
289 1
            S := First_Node (Subcomponents (E));
290 1
            while Present (S) loop
291
               --  Visit the component instance corresponding to the
292
               --  subcomponent S.
293

294 1
               Visit (Corresponding_Instance (S));
295 1
               S := Next_Node (S);
296 1
            end loop;
297
         end if;
298

299 1
         Pop_Entity; --  C_Root
300 1
      end Visit_System_Instance;
301

302
      ---------------------------
303
      -- Visit_Thread_Instance --
304
      ---------------------------
305

306 1
      procedure Visit_Thread_Instance (E : Node_Id) is
307 1
         S : constant Node_Id := Parent_Subcomponent (E);
308 1
         N : Node_Id;
309
      begin
310

311 1
         if Has_Ports (E) then
312 1
            N := Task_Deliver_Spec (E);
313 1
            Append_Node_To_List (N, CTN.Declarations (Current_File));
314 1
            Bind_AADL_To_Global_Port (Identifier (S), N);
315

316 1
            N := Task_Deliver_Spec (E);
317

318
         end if;
319

320
         --  Create the spec of the parameterless subprogram
321
         --  that executes the thread job.
322

323 1
         N := Task_Job_Spec (E);
324 1
         Append_Node_To_List (N, CTN.Declarations (Current_File));
325 1
         Bind_AADL_To_Job (Identifier (S), N);
326

327 1
      end Visit_Thread_Instance;
328

329
   end Header_File;
330

331
   ------------
332
   -- Source --
333
   ------------
334

335
   package body Source_File is
336

337
      procedure Visit_Architecture_Instance (E : Node_Id);
338
      procedure Visit_Component_Instance (E : Node_Id);
339
      procedure Visit_System_Instance (E : Node_Id);
340
      procedure Visit_Process_Instance (E : Node_Id);
341
      procedure Visit_Device_Instance (E : Node_Id);
342
      procedure Visit_Thread_Instance (E : Node_Id);
343

344
      function Task_Job_Body (E : Node_Id) return Node_Id;
345
      --  Create the parameterless subprogram body that does the
346
      --  thread's job.
347

348 1
      Main_Deliver_Alternatives : List_Id;
349

350
      Current_Device : Node_Id := No_Node;
351

352
      function Task_Initialize (E : Node_Id) return Node_Id;
353
      --  Return the snipet of code to initialize thread E
354

355 1
      function Task_Initialize (E : Node_Id) return Node_Id is
356 1
         S    : constant Node_Id := Parent_Subcomponent (E);
357 1
         Call_Parameters  : List_Id;
358 1
         N : Node_Id;
359
      begin
360 1
         if Has_Ports (E) then
361
            --  Make the __po_hi_gqueue_init call
362

363 1
            Call_Parameters := New_List (CTN.K_Parameter_List);
364

365 1
            Append_Node_To_List
366 1
              (Make_Defining_Identifier
367 1
                 (Map_C_Enumerator_Name (S, Current_Device)),
368
               Call_Parameters);
369

370 1
            Append_Node_To_List
371 1
              (Make_Defining_Identifier
372 1
                 (Map_C_Define_Name (S, Nb_Ports => True)),
373
               Call_Parameters);
374

375 1
            Append_Node_To_List
376 1
              (Make_Defining_Identifier
377 1
                 (Map_C_Variable_Name (S, Port_Queue => True)),
378
               Call_Parameters);
379

380 1
            Append_Node_To_List
381 1
              (Make_Defining_Identifier
382 1
                 (Map_C_Variable_Name (S, Port_Fifo_Size => True)),
383
               Call_Parameters);
384

385 1
            Append_Node_To_List
386 1
              (Make_Defining_Identifier
387 1
                 (Map_C_Variable_Name (S, Port_First => True)),
388
               Call_Parameters);
389

390 1
            Append_Node_To_List
391 1
              (Make_Defining_Identifier
392 1
                 (Map_C_Variable_Name (S, Port_Offsets => True)),
393
               Call_Parameters);
394

395 1
            Append_Node_To_List
396 1
              (Make_Defining_Identifier
397 1
                 (Map_C_Variable_Name (S, Port_Woffsets => True)),
398
               Call_Parameters);
399

400 1
            Append_Node_To_List
401 1
              (Make_Defining_Identifier
402 1
                 (Map_C_Variable_Name (S, Port_N_Dest => True)),
403
               Call_Parameters);
404

405 1
            Append_Node_To_List
406 1
              (Make_Defining_Identifier
407 1
                 (Map_C_Variable_Name (S, Port_Destinations => True)),
408
               Call_Parameters);
409

410 1
            Append_Node_To_List
411 1
              (Make_Defining_Identifier
412 1
                 (Map_C_Variable_Name (S, Port_Used_Size => True)),
413
               Call_Parameters);
414

415 1
            Append_Node_To_List
416 1
              (Make_Defining_Identifier
417 1
                 (Map_C_Variable_Name (S, Port_History => True)),
418
               Call_Parameters);
419

420 1
            Append_Node_To_List
421 1
              (Make_Defining_Identifier
422 1
                 (Map_C_Variable_Name (S, Port_Recent => True)),
423
               Call_Parameters);
424

425 1
            Append_Node_To_List
426 1
              (Make_Defining_Identifier
427 1
                 (Map_C_Variable_Name (S, Port_Empties => True)),
428
               Call_Parameters);
429

430 1
            Append_Node_To_List
431 1
              (Make_Defining_Identifier
432 1
                 (Map_C_Variable_Name (S, Port_Total_Fifo => True)),
433
               Call_Parameters);
434

435 1
            N := Make_Call_Profile (RE (RE_Gqueue_Init), Call_Parameters);
436 1
            return N;
437
         end if;
438

439 1
         return No_Node;
440
      end Task_Initialize;
441

442
      -------------------
443
      -- Task_Job_Body --
444
      -------------------
445

446 1
      function Task_Job_Body (E : Node_Id) return Node_Id is
447 1
         S    : constant Node_Id := Parent_Subcomponent (E);
448
         Spec : constant Node_Id :=
449 1
           CTN.Job_Node (Backend_Node (Identifier (S)));
450 1
         Declarations : constant List_Id := New_List (CTN.K_Declaration_List);
451 1
         Statements   : constant List_Id := New_List (CTN.K_Statement_List);
452 1
         WStatements  : constant List_Id := New_List (CTN.K_Statement_List);
453
         P            : constant Supported_Thread_Dispatch_Protocol :=
454 1
           Get_Thread_Dispatch_Protocol (E);
455
         Impl_Kind : constant Supported_Thread_Implementation :=
456 1
           Get_Thread_Implementation_Kind (E);
457 1
         Call_Parameters  : List_Id;
458 1
         Call_Parameters_Of_BA_Initialization_Function : List_Id;
459 1
         N, N1           : Node_Id;
460

461
         procedure Make_Wait_Event;
462
         procedure Make_Wait_Specific_Events;
463
         procedure Make_Call_Sequence;
464
         procedure Make_Set_Out_Ports;
465
         procedure Make_Send_Out_Ports (WStats : List_Id);
466
         procedure Make_Task_Blocking (WStats : List_Id);
467
         procedure Make_Fetch_In_Ports;
468
         procedure Make_Wait_Offset;
469
         procedure Make_Thread_Compute_Entrypoint;
470
         procedure Make_Thread_Behavior_Specification;
471
         procedure Make_Ports_Compute_Entrypoint;
472
         procedure Make_Activate_Entrypoint;
473
         function Make_Get_Valid_Value (F : Node_Id) return Node_Id;
474

475
         ------------------------------
476
         -- Make_Activate_Entrypoint --
477
         ------------------------------
478

479 1
         procedure Make_Activate_Entrypoint is
480
            Entrypoint : constant Node_Id :=
481 1
              Get_Thread_Activate_Entrypoint (E);
482

483 1
            Parameter_List : constant List_Id := New_List (CTN.K_List_Id);
484
         begin
485 1
            if Entrypoint /= No_Node then
486 0
               Append_Node_To_List
487 0
                 (Make_Call_Profile (Map_C_Subprogram_Identifier (Entrypoint)),
488
                  Statements);
489

490 0
               Append_Node_To_List
491 0
                 (Make_Extern_Entity_Declaration
492 0
                    (Make_Function_Specification
493 0
                       (Map_C_Subprogram_Identifier (Entrypoint),
494
                        Parameters  => Parameter_List, --  XXX
495 0
                        Return_Type => New_Node (CTN.K_Void))),
496 0
                  CTN.Declarations (Current_File));
497
            end if;
498 1
         end Make_Activate_Entrypoint;
499

500
         --------------------------
501
         -- Make_Get_Valid_Value --
502
         --------------------------
503

504 1
         function Make_Get_Valid_Value (F : Node_Id) return Node_Id is
505
            Then_Statements : constant List_Id :=
506 1
              New_List (CTN.K_Statement_List);
507 1
            Condition : Node_Id;
508 1
            N         : Node_Id;
509
         begin
510
            N :=
511 1
              Make_Variable_Declaration
512
                (Defining_Identifier =>
513 1
                   Make_Defining_Identifier
514 1
                     (Map_C_Variable_Name (F, Port_Request => True)),
515 1
                 Used_Type => RE (RE_Request_T),
516
                 Is_Static => True);
517 1
            Append_Node_To_List (N, Declarations);
518

519 1
            Call_Parameters := New_List (CTN.K_Parameter_List);
520 1
            Append_Node_To_List
521 1
              (Make_Defining_Identifier (Map_C_Enumerator_Name (S)),
522
               Call_Parameters);
523 1
            Append_Node_To_List
524 1
              (Make_Defining_Identifier
525 1
                 (Map_C_Enumerator_Name (F, Local_Port => True)),
526
               Call_Parameters);
527

528 1
            if not Get_Wait_For_All_Events (E) then
529
               Condition :=
530 1
                 Make_Call_Profile (RE (RE_Gqueue_Get_Count), Call_Parameters);
531
            else
532 0
               Condition := Make_Literal (CV.New_Int_Value (1, 0, 10));
533
            end if;
534

535
            --  If we wait for all events ports, the condition is always true
536

537 1
            Call_Parameters := New_List (CTN.K_Parameter_List);
538

539 1
            Append_Node_To_List
540 1
              (Make_Defining_Identifier (Map_C_Enumerator_Name (S)),
541
               Call_Parameters);
542

543 1
            Append_Node_To_List
544 1
              (Make_Defining_Identifier
545 1
                 (Map_C_Enumerator_Name (F, Local_Port => True)),
546
               Call_Parameters);
547

548 1
            Append_Node_To_List
549 1
              (Make_Variable_Address
550 1
                 (Make_Defining_Identifier
551 1
                    (Map_C_Variable_Name (F, Port_Request => True))),
552
               Call_Parameters);
553

554 1
            N := Make_Call_Profile (RE (RE_Gqueue_Get_Value), Call_Parameters);
555

556 1
            Append_Node_To_List (N, Then_Statements);
557

558
            --  Add the call to next_value
559

560 1
            Call_Parameters := New_List (CTN.K_Parameter_List);
561

562 1
            Append_Node_To_List
563 1
              (Make_Defining_Identifier (Map_C_Enumerator_Name (S)),
564
               Call_Parameters);
565

566 1
            Append_Node_To_List
567 1
              (Make_Defining_Identifier
568 1
                 (Map_C_Enumerator_Name (F, Local_Port => True)),
569
               Call_Parameters);
570

571
            N :=
572 1
              Make_Call_Profile (RE (RE_Gqueue_Next_Value), Call_Parameters);
573

574 1
            Append_Node_To_List (N, Then_Statements);
575

576 1
            return Make_If_Statement (Condition, Then_Statements);
577
         end Make_Get_Valid_Value;
578

579
         -------------------------------
580
         -- Make_Wait_Specific_Events --
581
         -------------------------------
582

583 1
         procedure Make_Wait_Specific_Events is
584
         begin
585

586
            --  __po_hi_int32_t index_transition_to_execute;
587

588
            N :=
589 1
              Make_Variable_Declaration
590 1
                (Defining_Identifier => Make_Defining_Identifier
591
                   (VN (V_Index_Transition_To_Execute)),
592 1
                 Used_Type           => RE (RE_Int32_T));
593 1
            Append_Node_To_List (N, Declarations);
594

595
            --  Make the call to
596
            --  __po_hi_gqueue_wait_for_specific_incoming_events
597

598 1
            Call_Parameters := New_List (CTN.K_Parameter_List);
599 1
            N := Make_Defining_Identifier (Map_C_Enumerator_Name (S));
600 1
            Append_Node_To_List (N, Call_Parameters);
601

602 1
            N := Make_Defining_Identifier (VN (V_Next_Complete_State));
603 1
            Append_Node_To_List (N, Call_Parameters);
604

605 1
            N := Make_Variable_Address
606 1
              (Make_Defining_Identifier (VN (V_Index_Transition_To_Execute)));
607 1
            Append_Node_To_List (N, Call_Parameters);
608

609
            N :=
610 1
              CTU.Make_Call_Profile
611 1
                (RE (RE_Gqueue_Wait_For_Specific_Incoming_Events),
612
                 Call_Parameters);
613 1
            Append_Node_To_List (N, WStatements);
614

615
            --  Make the call to __po_hi_compute_next_period
616

617 1
            Call_Parameters := New_List (CTN.K_Parameter_List);
618
            N               :=
619 1
              Make_Defining_Identifier
620 1
                (Map_C_Enumerator_Name (S, Custom_Parent => Current_Device));
621

622 1
            Append_Node_To_List (N, Call_Parameters);
623

624
            N :=
625 1
              CTU.Make_Call_Profile
626 1
                (RE (RE_Compute_Next_Period),
627
                 Call_Parameters);
628 1
            Append_Node_To_List (N, WStatements);
629 1
         end Make_Wait_Specific_Events;
630

631
         ---------------------
632
         -- Make_Wait_Event --
633
         ---------------------
634

635 1
         procedure Make_Wait_Event is
636
         begin
637

638
            N :=
639 1
              Make_Variable_Declaration
640 1
                (Defining_Identifier => Make_Defining_Identifier
641
                   (VN (V_Port)),
642 1
                 Used_Type           => RE (RE_Local_Port_T));
643 1
            Append_Node_To_List (N, Declarations);
644

645
            --  Make the call to __po_hi_gqueue_wait_for_incoming_event
646

647 1
            Call_Parameters := New_List (CTN.K_Parameter_List);
648 1
            N := Make_Defining_Identifier (Map_C_Enumerator_Name (S));
649 1
            Append_Node_To_List (N, Call_Parameters);
650

651
            N :=
652 1
              Make_Variable_Address
653 1
                (Make_Defining_Identifier
654
                   (VN (V_Port)));
655 1
            Append_Node_To_List (N, Call_Parameters);
656

657
            N :=
658 1
              CTU.Make_Call_Profile
659 1
                (RE (RE_Gqueue_Wait_For_Incoming_Event),
660
                 Call_Parameters);
661 1
            Append_Node_To_List (N, WStatements);
662

663
            --  Make the call to __po_hi_compute_next_period
664

665 1
            Call_Parameters := New_List (CTN.K_Parameter_List);
666
            N               :=
667 1
              Make_Defining_Identifier
668 1
                (Map_C_Enumerator_Name (S, Custom_Parent => Current_Device));
669

670 1
            Append_Node_To_List (N, Call_Parameters);
671

672
            N :=
673 1
              CTU.Make_Call_Profile
674 1
                (RE (RE_Compute_Next_Period),
675
                 Call_Parameters);
676 1
            Append_Node_To_List (N, WStatements);
677 1
         end Make_Wait_Event;
678

679
         ------------------------
680
         -- Make_Task_Blocking --
681
         ------------------------
682

683 1
         procedure Make_Task_Blocking (WStats : List_Id) is
684
         begin
685
            --  Make the __po_hi_wait_for_next_period call
686

687 1
            Call_Parameters := New_List (CTN.K_Parameter_List);
688 1
            if Current_Device /= No_Node then
689
               N :=
690 0
                 Make_Defining_Identifier
691 0
                   (Map_C_Enumerator_Name
692
                      (S,
693
                       Custom_Parent => Current_Device));
694
            else
695 1
               N := Make_Defining_Identifier (Map_C_Enumerator_Name (S));
696
            end if;
697 1
            Append_Node_To_List (N, Call_Parameters);
698

699
            N :=
700 1
              CTU.Make_Call_Profile
701 1
                (RE (RE_Wait_For_Next_Period),
702
                 Call_Parameters);
703 1
            Append_Node_To_List (N, WStats);
704 1
         end Make_Task_Blocking;
705

706
         ------------------------
707
         -- Make_Set_Out_Ports --
708
         ------------------------
709

710 1
         procedure Make_Set_Out_Ports is
711 1
            N          : Node_Id;
712 1
            L          : Node_Id;
713 1
            R          : Node_Id;
714 1
            F          : Node_Id;
715 1
            T          : Node_Id;
716 1
            Z          : Node_Id;
717 1
            Parameters : List_Id;
718
         begin
719 1
            N := Message_Comment ("Set the OUT port values");
720 1
            Append_Node_To_List (N, WStatements);
721

722 1
            F := First_Node (Features (E));
723

724 1
            while Present (F) loop
725 1
               if Kind (F) = K_Port_Spec_Instance
726 1
                 and then Is_Out (F)
727 1
                 and then not AAU.Is_Empty (AAN.Sources (F))
728
               then
729
                  --  We do not set the ports that are connected to
730
                  --  subprogram out ports, this should be done during
731
                  --  the subprogram call sequence handling.
732

733
                  declare
734
                     use Ocarina.Backends.C_Tree.Nodes;
735 1
                     D   : Node_Id := AAN.First_Node (AAN.Sources (F));
736 1
                     Set : Boolean := True;
737
                  begin
738 1
                     while Present (D) loop
739 1
                        Set := Kind (Item (D)) /= K_Port_Spec_Instance;
740 1
                        exit when not Set;
741

742 1
                        D := AAN.Next_Node (D);
743 1
                     end loop;
744

745 1
                     if Set then
746
                        N :=
747 1
                          Make_Variable_Declaration
748 1
                            (Make_Defining_Identifier
749 1
                               (Map_C_Variable_Name (F, Port_Request => True)),
750 1
                             RE (RE_Request_T),
751
                             Is_Static => True);
752 1
                        Append_Node_To_List (N, Declarations);
753

754
                        L :=
755 1
                          Make_Member_Designator
756
                            (Defining_Identifier =>
757 1
                               Make_Member_Designator
758
                                 (Defining_Identifier =>
759 1
                                    Make_Member_Designator
760
                                      (Defining_Identifier =>
761 1
                                         Make_Defining_Identifier
762 1
                                           (Map_C_Enumerator_Name (F)),
763
                                       Aggregate_Name =>
764 1
                                         Make_Defining_Identifier
765 1
                                           (Map_C_Enumerator_Name (F))),
766
                                  Aggregate_Name =>
767 1
                                    Make_Defining_Identifier (MN (M_Vars))),
768
                             Aggregate_Name =>
769 1
                               Make_Defining_Identifier
770 1
                                 (Map_C_Variable_Name
771
                                    (F,
772
                                     Port_Request => True)));
773
                        R :=
774 1
                          Make_Defining_Identifier
775 1
                            (Map_C_Variable_Name
776
                               (F,
777
                                Request_Variable => True));
778

779 1
                        Z := AAN.Corresponding_Instance (F);
780 1
                        T := No_Node;
781

782 1
                        if Present (Backend_Node (Identifier (Z)))
783 1
                          and then Present
784 1
                            (CTN.Type_Definition_Node
785 1
                               (Backend_Node (Identifier (Z))))
786
                        then
787
                           T :=
788 1
                             CTN.Type_Name
789 1
                               (CTN.Type_Definition_Node
790 1
                                  (Backend_Node (Identifier (Z))));
791
                        end if;
792

793 1
                        if T /= No_Node
794 1
                          and then CTN.Kind (T) = CTN.K_Array_Declaration
795
                        then
796 1
                           Parameters := New_List (CTN.K_Parameter_List);
797 1
                           Append_Node_To_List (L, Parameters);
798 1
                           Append_Node_To_List (R, Parameters);
799 1
                           Append_Node_To_List (Get_Data_Size (Z), Parameters);
800 1
                           N :=
801 1
                             CTU.Make_Call_Profile
802 1
                               (RE (RE_Copy_Array),
803
                                Parameters);
804
                        else
805
                           N :=
806 1
                             Make_Expression
807
                               (Left_Expr  => L,
808
                                Operator   => Op_Equal,
809
                                Right_Expr => R);
810
                        end if;
811

812 1
                        Append_Node_To_List (N, WStatements);
813

814
                        N :=
815 1
                          Make_Expression
816
                            (Left_Expr =>
817 1
                               Make_Member_Designator
818
                                 (Defining_Identifier =>
819 1
                                    Make_Defining_Identifier (MN (M_Port)),
820
                                  Aggregate_Name =>
821 1
                                    Make_Defining_Identifier
822 1
                                      (Map_C_Variable_Name
823
                                         (F,
824
                                          Port_Request => True))),
825
                             Operator   => Op_Equal,
826
                             Right_Expr =>
827 1
                               Make_Defining_Identifier
828 1
                                 (Map_C_Enumerator_Name (F)));
829 1
                        Append_Node_To_List (N, WStatements);
830

831 1
                        Call_Parameters := New_List (CTN.K_Parameter_List);
832
                        N               :=
833 1
                          Make_Defining_Identifier
834 1
                            (Map_C_Enumerator_Name (S, Current_Device));
835 1
                        Append_Node_To_List (N, Call_Parameters);
836

837
                        N :=
838 1
                          Make_Defining_Identifier
839 1
                            (Map_C_Enumerator_Name (F, Local_Port => True));
840 1
                        Append_Node_To_List (N, Call_Parameters);
841

842
                        N :=
843 1
                          Make_Variable_Address
844 1
                            (Make_Defining_Identifier
845 1
                               (Map_C_Variable_Name
846
                                  (F,
847
                                   Port_Request => True)));
848 1
                        Append_Node_To_List (N, Call_Parameters);
849

850
                        N :=
851 1
                          CTU.Make_Call_Profile
852 1
                            (RE (RE_Gqueue_Store_Out),
853
                             Call_Parameters);
854

855 1
                        Append_Node_To_List (N, WStatements);
856
                     end if;
857
                  end;
858
               end if;
859

860 1
               F := Next_Node (F);
861 1
            end loop;
862 1
         end Make_Set_Out_Ports;
863

864
         -------------------------
865
         -- Make_Send_Out_Ports --
866
         -------------------------
867

868 1
         procedure Make_Send_Out_Ports (WStats : List_Id) is
869 1
            N                     : Node_Id;
870 1
            F                     : Node_Id;
871 1
            Error_Already_Defined : Boolean := False;
872 1
            Decl                  : Node_Id;
873
         begin
874 1
            N := Message_Comment ("Send the OUT ports");
875 1
            Append_Node_To_List (N, WStats);
876

877 1
            F := First_Node (Features (E));
878

879 1
            while Present (F) loop
880

881 1
               if Kind (F) = K_Port_Spec_Instance and then Is_Out (F) then
882

883
                  --  Then, call the send_output in the main loop.
884 1
                  Call_Parameters := New_List (CTN.K_Parameter_List);
885
                  N               :=
886 1
                    Make_Defining_Identifier
887 1
                      (Map_C_Enumerator_Name (S, Current_Device));
888 1
                  Append_Node_To_List (N, Call_Parameters);
889

890 1
                  N := Make_Defining_Identifier (Map_C_Enumerator_Name (F));
891 1
                  Append_Node_To_List (N, Call_Parameters);
892

893
                  N :=
894 1
                    CTU.Make_Call_Profile
895 1
                      (RE (RE_Send_Output),
896
                       Call_Parameters);
897

898 1
                  if Get_Miss_Rate (F) /= 0 then
899
                     --  XXX is this required ? from PolyORB-HI/C,
900
                     --  looks like it is some hack to add fake miss
901
                     --  of events.
902

903 0
                     Append_Node_To_List
904 0
                       (Make_If_Statement
905
                          (Condition =>
906 0
                             Make_Call_Profile
907 0
                               (RE (RE_Compute_Miss),
908 0
                                Make_List_Id
909 0
                                  (Make_Literal
910 0
                                     (CV.New_Int_Value
911 0
                                        (Get_Miss_Rate (F),
912
                                         0,
913
                                         10)))),
914 0
                           Statements => Make_List_Id (N)),
915
                        WStats);
916
                  else
917
                     N :=
918 1
                       Make_Assignment_Statement
919
                         (Variable_Identifier =>
920 1
                            Make_Defining_Identifier (VN (V_Error)),
921
                          Expression => N);
922 1
                     Append_Node_To_List (N, WStats);
923

924
                     declare
925
                        use Ocarina.Backends.C_Tree.Nodes;
926
                     begin
927 1
                        Decl := CTN.First_Node (Declarations);
928 1
                        while Present (Decl) loop
929

930 1
                           if CTN.Kind (Decl) = CTN.K_Variable_Declaration
931 1
                             and then
932 1
                               Get_Name_String
933 1
                                 (CTN.Name (CTN.Defining_Identifier (Decl)))
934 1
                             = Get_Name_String (VN (V_Error))
935
                           then
936 1
                              Error_Already_Defined := True;
937
                           end if;
938 1
                           exit when Error_Already_Defined;
939 1
                           Decl := CTN.Next_Node (Decl);
940 1
                        end loop;
941
                     end;
942

943 1
                     if not Error_Already_Defined then
944
                        N :=
945 1
                          Make_Variable_Declaration
946
                            (Defining_Identifier =>
947 1
                               Make_Defining_Identifier (VN (V_Error)),
948 1
                             Used_Type => RE (RE_Int32_T));
949 1
                        Append_Node_To_List (N, Declarations);
950 1
                        Error_Already_Defined := True;
951
                     end if;
952
                     declare
953
                        Rec_Entrypoint : constant Name_Id :=
954 1
                          Get_Thread_Recover_Entrypoint (E);
955
                        Parameter_List : constant List_Id :=
956 1
                          New_List (CTN.K_List_Id);
957
                        Then_Statements : constant List_Id :=
958 1
                          New_List (CTN.K_Statement_List);
959
                     begin
960 1
                        if Rec_Entrypoint /= No_Name then
961
                           N :=
962 1
                             Make_Extern_Entity_Declaration
963 1
                               (Make_Function_Specification
964 1
                                  (Make_Defining_Identifier (Rec_Entrypoint),
965
                                   Parameters  => Parameter_List, --  XXX
966 1
                                   Return_Type => New_Node (CTN.K_Void)));
967 1
                           Append_Node_To_List
968
                             (N,
969 1
                              CTN.Declarations (Current_File));
970

971
                           N :=
972 1
                             CTU.Make_Call_Profile
973 1
                               (Make_Defining_Identifier (Rec_Entrypoint),
974
                                No_List);
975 1
                           Append_Node_To_List (N, Then_Statements);
976

977
                           N :=
978 1
                             Make_If_Statement
979
                               (Condition =>
980 1
                                  Make_Expression
981 1
                                    (Make_Defining_Identifier (VN (V_Error)),
982
                                     Op_Not_Equal,
983 1
                                     RE (RE_SUCCESS)),
984
                                Statements => Then_Statements);
985 1
                           Append_Node_To_List (N, WStats);
986
                        else
987 1
                           N := Make_Type_Conversion
988
                                 (Subtype_Mark =>
989 1
                                    Make_Defining_Identifier (TN (T_Void)),
990
                                  Expression   =>
991 1
                                    Make_Defining_Identifier (VN (V_Error)));
992 1
                           Append_Node_To_List (N, WStats);
993
                        end if;
994
                     end;
995

996
                  end if;
997
               end if;
998

999 1
               F := Next_Node (F);
1000 1
            end loop;
1001 1
         end Make_Send_Out_Ports;
1002

1003
         ----------------------
1004
         -- Make_Wait_Offset --
1005
         ----------------------
1006

1007 1
         procedure Make_Wait_Offset is
1008 1
            D : Time_Type;
1009
         begin
1010 1
            if Get_Thread_Dispatch_Protocol (E) /= Thread_Periodic then
1011 1
               return;
1012
            end if;
1013

1014 1
            D := Get_Dispatch_Offset (E);
1015

1016 1
            if D /= Null_Time then
1017
               N :=
1018 1
                 Make_Variable_Declaration
1019 1
                   (Make_Defining_Identifier (VN (V_Offset)),
1020 1
                    RE (RE_Time_T));
1021 1
               Append_Node_To_List (N, Statements);
1022

1023 1
               N := Map_Time (D, VN (V_Offset));
1024 1
               Append_Node_To_List (N, Statements);
1025

1026 1
               Append_Node_To_List
1027 1
                 (CTU.Make_Call_Profile
1028 1
                    (RE (RE_Task_Wait_Offset),
1029 1
                     Make_List_Id
1030 1
                       (Make_Variable_Address
1031 1
                          (Make_Defining_Identifier (VN (V_Offset))))),
1032
                  Statements);
1033
            end if;
1034 1
         end Make_Wait_Offset;
1035

1036
         -------------------------
1037
         -- Make_Fetch_In_Ports --
1038
         -------------------------
1039

1040 1
         procedure Make_Fetch_In_Ports is
1041 1
            F : Node_Id;
1042
         begin
1043 1
            N := Message_Comment ("Get the IN ports values");
1044 1
            Append_Node_To_List (N, CTN.Declarations (Current_File));
1045

1046 1
            F := First_Node (Features (E));
1047

1048 1
            while Present (F) loop
1049 1
               if Kind (F) = K_Port_Spec_Instance
1050 1
                 and then Is_In (F)
1051 1
                 and then AAN.Is_Data (F)
1052
               then
1053
                  --  Assign the port value
1054

1055 1
                  N := Make_Get_Valid_Value (F);
1056 1
                  Append_Node_To_List (N, WStatements);
1057

1058 1
                  Call_Parameters := New_List (CTN.K_Parameter_List);
1059

1060 1
                  Append_Node_To_List
1061 1
                    (Make_Defining_Identifier (Map_C_Enumerator_Name (S)),
1062
                     Call_Parameters);
1063

1064 1
                  Append_Node_To_List
1065 1
                    (Make_Defining_Identifier (Map_C_Enumerator_Name (F)),
1066
                     Call_Parameters);
1067

1068
                  N :=
1069 1
                    Make_Call_Profile
1070 1
                      (RE (RE_Gqueue_Next_Value),
1071
                       Call_Parameters);
1072

1073
               end if;
1074

1075 1
               F := Next_Node (F);
1076 1
            end loop;
1077 1
         end Make_Fetch_In_Ports;
1078

1079
         ------------------------
1080
         -- Make_Call_Sequence --
1081
         ------------------------
1082

1083 1
         procedure Make_Call_Sequence is
1084 1
            Call_Seq : constant Node_Id := First_Node (Calls (E));
1085
         begin
1086 1
            if not Has_Modes (E) or else AAU.Length (Calls (E)) = 1 then
1087
               --  If the thread has no modes, then it should has one
1088
               --  unique call sequence, handle it.
1089

1090 1
               CTU.Handle_Call_Sequence
1091
                 (S,
1092
                  Call_Seq,
1093
                  Declarations,
1094
                  WStatements,
1095
                  Current_Device);
1096
            else
1097 0
               N := Message_Comment ("not implemented yet");
1098 0
               Append_Node_To_List (N, WStatements);
1099
            end if;
1100 1
         end Make_Call_Sequence;
1101

1102
         -----------------------------------
1103
         -- Make_Ports_Compute_Entrypoint --
1104
         -----------------------------------
1105

1106 1
         procedure Make_Ports_Compute_Entrypoint is
1107 1
            N                   : Node_Id;
1108 1
            F                   : Node_Id;
1109 1
            Switch_Alternatives : List_Id;
1110 1
            Switch_Statements   : List_Id;
1111 1
            Switch_Labels       : List_Id;
1112
         begin
1113 1
            N := Message_Comment ("Make_Ports_Compute_Entrypoint");
1114 1
            Append_Node_To_List (N, WStatements);
1115

1116 1
            F := First_Node (Features (E));
1117

1118 1
            Switch_Alternatives := New_List (CTN.K_Alternatives_List);
1119

1120 1
            while Present (F) loop
1121 1
               if Kind (F) = K_Port_Spec_Instance and then Is_In (F) then
1122

1123 1
                  Switch_Statements := New_List (CTN.K_Statement_List);
1124 1
                  Switch_Labels     := New_List (CTN.K_Label_List);
1125

1126
                  --  Declare local data variable if the port is a
1127
                  --  data port.
1128

1129 1
                  if AAN.Is_Data (F) then
1130 1
                     N := Make_Get_Valid_Value (F);
1131 1
                     Append_Node_To_List (N, Switch_Statements);
1132
                  end if;
1133

1134 1
                  if Is_Event (F) and then not AAN.Is_Data (F) then
1135 1
                     Call_Parameters := New_List (CTN.K_Parameter_List);
1136

1137 1
                     Append_Node_To_List
1138 1
                       (Make_Defining_Identifier (Map_C_Enumerator_Name (S)),
1139
                        Call_Parameters);
1140

1141 1
                     Append_Node_To_List
1142 1
                       (Make_Defining_Identifier
1143 1
                          (Map_C_Enumerator_Name (F, Local_Port => True)),
1144
                        Call_Parameters);
1145

1146
                     N :=
1147 1
                       Make_Call_Profile
1148 1
                         (RE (RE_Gqueue_Next_Value),
1149
                          Call_Parameters);
1150

1151 1
                     Append_Node_To_List (N, Switch_Statements);
1152
                  end if;
1153

1154 1
                  Call_Parameters := New_List (CTN.K_Parameter_List);
1155 1
                  N := Make_Defining_Identifier (Map_C_Enumerator_Name (S));
1156 1
                  Append_Node_To_List (N, Call_Parameters);
1157

1158
                  declare
1159
                     Parameter_List : constant List_Id :=
1160 1
                       New_List (CTN.K_List_Id);
1161
                  begin
1162
                     N :=
1163 1
                       Make_Parameter_Specification
1164 1
                         (Make_Defining_Identifier (PN (P_Self)),
1165 1
                          Parameter_Type => RE (RE_Task_Id));
1166 1
                     Append_Node_To_List (N, Parameter_List);
1167

1168 1
                     if AAN.Is_Data (F) then
1169
                        N :=
1170 1
                          Make_Member_Designator
1171
                            (Defining_Identifier =>
1172 1
                               Make_Member_Designator
1173
                                 (Defining_Identifier =>
1174 1
                                    Make_Member_Designator
1175
                                      (Defining_Identifier =>
1176 1
                                         Make_Defining_Identifier
1177 1
                                           (Map_C_Enumerator_Name (F)),
1178
                                       Aggregate_Name =>
1179 1
                                         Make_Defining_Identifier
1180 1
                                           (Map_C_Enumerator_Name (F))),
1181
                                  Aggregate_Name =>
1182 1
                                    Make_Defining_Identifier (MN (M_Vars))),
1183
                             Aggregate_Name =>
1184 1
                               Make_Defining_Identifier
1185 1
                                 (Map_C_Variable_Name
1186
                                    (F,
1187
                                     Port_Request => True)));
1188

1189 1
                        Append_Node_To_List (N, Call_Parameters);
1190

1191
                        N :=
1192 1
                          Map_C_Data_Type_Designator
1193 1
                            (Corresponding_Instance (F));
1194
                        N :=
1195 1
                          Make_Parameter_Specification
1196 1
                            (Map_C_Defining_Identifier (F),
1197
                             N);
1198 1
                        Append_Node_To_List (N, Parameter_List);
1199
                     end if;
1200

1201
                     N :=
1202 1
                       Make_Extern_Entity_Declaration
1203 1
                         (Make_Function_Specification
1204 1
                            (Map_C_Subprogram_Identifier (F),
1205
                             Parameters  => Parameter_List,
1206 1
                             Return_Type => New_Node (CTN.K_Void)));
1207 1
                     Append_Node_To_List (N, CTN.Declarations (Current_File));
1208
                  end;
1209

1210
                  N :=
1211 1
                    Make_Call_Profile
1212 1
                      (Map_C_Subprogram_Identifier (F),
1213
                       Call_Parameters);
1214 1
                  Append_Node_To_List (N, Switch_Statements);
1215

1216 1
                  Append_Node_To_List
1217 1
                    (Make_Defining_Identifier
1218 1
                       (Map_C_Enumerator_Name (F, Local_Port => True)),
1219
                     Switch_Labels);
1220

1221
                  N :=
1222 1
                    Make_Switch_Alternative (Switch_Labels, Switch_Statements);
1223 1
                  Append_Node_To_List (N, Switch_Alternatives);
1224
               end if;
1225

1226 1
               F := Next_Node (F);
1227 1
            end loop;
1228

1229 1
            N := Make_Switch_Alternative (No_List, No_List);
1230 1
            Append_Node_To_List (N, Switch_Alternatives);
1231

1232
            --  Make the case statement
1233

1234
            N :=
1235 1
              Make_Switch_Statement
1236 1
                (Expression   => Make_Defining_Identifier (MN (M_Port)),
1237
                 Alternatives => Switch_Alternatives);
1238 1
            Append_Node_To_List (N, WStatements);
1239 1
         end Make_Ports_Compute_Entrypoint;
1240

1241
         ------------------------------------
1242
         -- Make_Thread_Compute_Entrypoint --
1243
         ------------------------------------
1244

1245 1
         procedure Make_Thread_Compute_Entrypoint is
1246 1
            N              : Node_Id;
1247 1
            Parameter_List : constant List_Id := New_List (CTN.K_List_Id);
1248
         begin
1249 1
            N := Message_Comment ("Make_Thread_Compute_Entrypoint");
1250 1
            Append_Node_To_List (N, WStatements);
1251

1252 1
            Call_Parameters := New_List (CTN.K_Parameter_List);
1253 1
            N := Make_Defining_Identifier (Map_C_Enumerator_Name (S));
1254 1
            Append_Node_To_List (N, Call_Parameters);
1255

1256
            N :=
1257 1
              Make_Parameter_Specification
1258 1
                (Make_Defining_Identifier (PN (P_Self)),
1259 1
                 Parameter_Type => RE (RE_Task_Id));
1260 1
            Append_Node_To_List (N, Parameter_List);
1261

1262 1
            if P = Thread_Sporadic then
1263 1
               Append_Node_To_List
1264 1
                 (Make_Defining_Identifier (VN (V_Port)),
1265
                  Call_Parameters);
1266

1267
               N :=
1268 1
                 Make_Parameter_Specification
1269 1
                   (Make_Defining_Identifier (VN (V_Port)),
1270 1
                    Parameter_Type => RE (RE_Port_T));
1271 1
               Append_Node_To_List (N, Parameter_List);
1272
            end if;
1273

1274 1
            if not Has_Modes (E) then
1275
               N :=
1276 1
                 Make_Extern_Entity_Declaration
1277 1
                   (Make_Function_Specification
1278 1
                      (Map_C_Subprogram_Identifier (E),
1279
                       Parameters  => Parameter_List,
1280 1
                       Return_Type => New_Node (CTN.K_Void)));
1281

1282 1
               Append_Node_To_List (N, CTN.Declarations (Current_File));
1283

1284
               N :=
1285 1
                 Make_Call_Profile
1286 1
                   (Map_C_Subprogram_Identifier (E),
1287
                    Call_Parameters);
1288 1
               Append_Node_To_List (N, WStatements);
1289
            else
1290 0
               Display_Located_Error
1291 0
                 (Loc (E),
1292
                  "Threads with mode controlled compute entrypoints not" &
1293
                    " supported yet",
1294
                  Fatal => True);
1295
            end if;
1296 1
         end Make_Thread_Compute_Entrypoint;
1297

1298
         ----------------------------------------
1299
         -- Make_Thread_Behavior_Specification --
1300
         ----------------------------------------
1301

1302 1
         procedure Make_Thread_Behavior_Specification is
1303 1
            N, N1          : Node_Id;
1304
         begin
1305

1306
            --  Add_Include (RH (RH_Subprograms));
1307

1308 1
            N := Message_Comment
1309
              ("Call the function implementing"
1310
                 & " the C-Mapping of the Behavior_Specification");
1311

1312 1
            Append_Node_To_List (N, WStatements);
1313

1314 1
            Call_Parameters := New_List (CTN.K_Parameter_List);
1315 1
            N := Make_Defining_Identifier (Map_C_Enumerator_Name (S));
1316 1
            Append_Node_To_List (N, Call_Parameters);
1317

1318 1
            if P = Thread_Sporadic and then
1319 1
              Compute_Nb_On_Dispatch_Transitions (E) > 1
1320
            then
1321

1322 1
               N := Make_Defining_Identifier (VN (V_Next_Complete_State));
1323 1
               Append_Node_To_List (N, Call_Parameters);
1324

1325 1
               N := Make_Defining_Identifier
1326
                 (VN (V_Index_Transition_To_Execute));
1327 1
               Append_Node_To_List (N, Call_Parameters);
1328

1329
            end if;
1330
            --  add data subcomponents of the thread to the call_parameters
1331
            --  of the procedure <<thread_instance_name>>_ba_body
1332

1333 1
            if not AAU.Is_Empty (Subcomponents (E)) then
1334 1
               N1 := First_Node (Subcomponents (E));
1335

1336 1
               while Present (N1) loop
1337 1
                  if AAU.Is_Data (Corresponding_Instance (N1)) then
1338

1339
                     N :=
1340 1
                       Make_Variable_Address
1341 1
                         (Map_C_Defining_Identifier (N1));
1342

1343 1
                     Append_Node_To_List (N, Call_Parameters);
1344

1345
                  end if;
1346 1
                  N1 := Next_Node (N1);
1347 1
               end loop;
1348
            end if;
1349

1350 1
            N := Make_Extern_Entity_Declaration
1351 1
              (Make_Specification_Of_BA_Related_Function
1352
                 (E, BA_Body => True));
1353

1354 1
            Append_Node_To_List (N, CTN.Declarations (Current_File));
1355

1356
            N :=
1357 1
              Make_Call_Profile
1358 1
                (Defining_Identifier => Make_Defining_Identifier
1359 1
                   (Map_C_BA_Related_Function_Name (S, BA_Body => True)),
1360
                 Parameters          => Call_Parameters);
1361

1362 1
            Append_Node_To_List (N, WStatements);
1363

1364 1
         end Make_Thread_Behavior_Specification;
1365

1366
      begin
1367 1
         case P is
1368 1
            when Thread_Periodic =>
1369 1
               N :=
1370 1
                 Message_Comment
1371 1
                   ("Periodic task : " &
1372 1
                      Get_Name_String (Display_Name (Identifier (S))));
1373 1
               Append_Node_To_List (N, CTN.Declarations (Current_File));
1374

1375 1
            when Thread_Sporadic =>
1376 1
               N :=
1377 1
                 Message_Comment
1378 1
                   ("Sporadic task : " &
1379 1
                      Get_Name_String (Display_Name (Identifier (S))));
1380 1
               Append_Node_To_List (N, CTN.Declarations (Current_File));
1381

1382 0
            when Thread_Aperiodic =>
1383 0
               N :=
1384 0
                 Message_Comment
1385 0
                   ("Sporadic task : " &
1386 0
                      Get_Name_String (Display_Name (Identifier (S))));
1387 0
               Append_Node_To_List (N, CTN.Declarations (Current_File));
1388

1389 1
            when Thread_Background =>
1390 1
               N :=
1391 1
                 Message_Comment
1392 1
                   ("Background task : " &
1393 1
                      Get_Name_String (Display_Name (Identifier (S))));
1394 1
               Append_Node_To_List (N, CTN.Declarations (Current_File));
1395

1396 0
            when others =>
1397 0
               Display_Error ("unknown type of thread", Fatal => False);
1398 0
               null;
1399 1
         end case;
1400

1401 1
         Check_Thread_Consistency (E);
1402

1403
         --  Visit the data subcomponents of the thread
1404

1405 1
         if not AAU.Is_Empty (Subcomponents (E)) then
1406 1
            N1 := First_Node (Subcomponents (E));
1407

1408 1
            while Present (N1) loop
1409 1
               if AAU.Is_Data (Corresponding_Instance (N1)) then
1410

1411
                  N :=
1412 1
                    Make_Variable_Declaration
1413 1
                      (Map_C_Defining_Identifier (N1),
1414 1
                       Map_C_Data_Type_Designator
1415 1
                         (Corresponding_Instance (N1)));
1416

1417 1
                  Append_Node_To_List (N, Declarations);
1418

1419
               end if;
1420 1
               N1 := Next_Node (N1);
1421 1
            end loop;
1422
         end if;
1423

1424 1
         if not AAU.Is_Empty (Subcomponents (E)) then
1425 1
            N1 := First_Node (Subcomponents (E));
1426

1427 1
            while Present (N1) loop
1428

1429 1
               if not AAU.Is_Data (Corresponding_Instance (N1)) then
1430 0
                  Visit (Corresponding_Instance (N1));
1431
               end if;
1432 1
               N1 := Next_Node (N1);
1433 1
            end loop;
1434
         end if;
1435

1436 1
         if Impl_Kind = Thread_With_Behavior_Specification then
1437
            declare
1438 1
               BA : constant Node_Id := Get_Behavior_Specification (E);
1439
            begin
1440 1
               if P = Thread_Sporadic and then
1441 1
                 BANu.Length (BATN.States (BA)) > 1 and then
1442 1
                 Compute_Nb_On_Dispatch_Transitions (E) > 1
1443
               then
1444

1445
                  --  __po_hi_ba_automata_state_t *next_complete_state =
1446
                  --    (__po_hi_ba_automata_state_t *)
1447
                  --      malloc(sizeof(__po_hi_ba_automata_state_t));
1448

1449
                  N :=
1450 1
                    Make_Variable_Declaration
1451 1
                      (Defining_Identifier => Make_Defining_Identifier
1452
                         (VN (V_Next_Complete_State)),
1453 1
                       Used_Type           => Make_Pointer_Type
1454 1
                         (RE (RE_Ba_Automata_State_T)),
1455 1
                       Value               => Make_Type_Conversion
1456 1
                         (Subtype_Mark => Make_Pointer_Type
1457 1
                            (RE (RE_Ba_Automata_State_T)),
1458 1
                          Expression   => Make_Call_Profile
1459 1
                            (Make_Defining_Identifier (FN (F_Malloc)),
1460 1
                             Make_List_Id
1461 1
                               (Make_Call_Profile
1462 1
                                    (Make_Defining_Identifier (FN (F_Sizeof)),
1463 1
                                     Make_List_Id
1464 1
                                       (RE (RE_Ba_Automata_State_T)))))));
1465

1466 1
                  Append_Node_To_List (N, Declarations);
1467

1468
                  --  next_complete_state
1469
                  --       ->nb_dispatch_triggers_of_each_transition =
1470
                  --  (__po_hi_int32_t *)
1471
                  --     malloc( sizeof(__po_hi_int32_t) *
1472
                  --  __po_hi_consumer_max_dispatch_transitions_
1473
                  --  per_complete_state);
1474

1475 1
                  N := Make_Assignment_Statement
1476 1
                    (Variable_Identifier => Make_Member_Designator
1477 1
                       (Defining_Identifier => Make_Defining_Identifier
1478
                            (MN
1479
                                 (M_Nb_Dispatch_Triggers_Of_Each_Transition)),
1480 1
                        Aggregate_Name      => Make_Defining_Identifier
1481
                          (VN (V_Next_Complete_State)),
1482
                        Is_Pointer          => True),
1483 1
                     Expression          => Make_Type_Conversion
1484 1
                       (Subtype_Mark => Make_Pointer_Type
1485 1
                            (RE (RE_Int32_T)),
1486 1
                        Expression   => Make_Call_Profile
1487 1
                          (Make_Defining_Identifier (FN (F_Malloc)),
1488 1
                           Make_List_Id
1489 1
                             (Make_Expression
1490 1
                               (Left_Expr  => Make_Call_Profile
1491 1
                                  (Make_Defining_Identifier (FN (F_Sizeof)),
1492 1
                                   Make_List_Id
1493 1
                                       (RE (RE_Int32_T))),
1494
                                Operator   => Op_Asterisk,
1495 1
                                Right_Expr => Make_Defining_Identifier
1496 1
                                 (Map_C_Define_Name
1497
                                   (S,
1498
                                    Max_Dispatch_Transitions_Per_Complete_State
1499
                                         => True)))))));
1500 1
                  Append_Node_To_List (N, Statements);
1501

1502
                  --  next_complete_state->dispatch_triggers_of_all_transitions
1503
                  --  = (__po_hi_int32_t *)
1504
                  --  malloc( sizeof(__po_hi_int32_t) *
1505
                  --   (__po_hi_consumer_max_dispatch_transitions_per_
1506
                  --     complete_state*__po_hi_consumer_max_dispatch_
1507
                  --           triggers_per_dispatch_transition));
1508

1509 1
                  N := Make_Assignment_Statement
1510 1
                    (Variable_Identifier => Make_Member_Designator
1511 1
                       (Defining_Identifier => Make_Defining_Identifier
1512
                            (MN (M_Dispatch_Triggers_Of_All_Transitions)),
1513 1
                        Aggregate_Name      => Make_Defining_Identifier
1514
                          (VN (V_Next_Complete_State)),
1515
                        Is_Pointer          => True),
1516 1
                     Expression          => Make_Type_Conversion
1517 1
                       (Subtype_Mark => Make_Pointer_Type
1518 1
                            (RE (RE_Int32_T)),
1519 1
                        Expression   => Make_Call_Profile
1520 1
                          (Make_Defining_Identifier (FN (F_Malloc)),
1521 1
                           Make_List_Id
1522 1
                             (Make_Expression
1523 1
                               (Left_Expr  => Make_Call_Profile
1524 1
                                  (Make_Defining_Identifier (FN (F_Sizeof)),
1525 1
                                   Make_List_Id
1526 1
                                       (RE (RE_Int32_T))),
1527
                                Operator   => Op_Asterisk,
1528 1
                                Right_Expr => Make_Expression
1529 1
                                  (Left_Expr  => Make_Defining_Identifier
1530 1
                                 (Map_C_Define_Name
1531
                                   (S,
1532
                                    Max_Dispatch_Transitions_Per_Complete_State
1533
                                         => True)),
1534
                                   Operator   => Op_Asterisk,
1535 1
                                   Right_Expr => Make_Defining_Identifier
1536 1
                                 (Map_C_Define_Name
1537
                                 (S,
1538
                                  Max_Dispatch_Triggers_Per_Dispatch_Transition
1539
                                         => True))))))));
1540 1
                  Append_Node_To_List (N, Statements);
1541

1542
               end if;
1543
            end;
1544
         end if;
1545

1546 1
         Make_Activate_Entrypoint;
1547

1548
         --  If the thread is sporadic or aperiodic, we generate the
1549
         --  call to block waiting for events.
1550

1551 1
         if P = Thread_Aperiodic then
1552 0
            Make_Wait_Event;
1553 1
         elsif P = Thread_Sporadic then
1554 1
            if Impl_Kind = Thread_With_Behavior_Specification and then
1555 1
              Compute_Nb_On_Dispatch_Transitions (E) > 1
1556
            then
1557 1
               Make_Wait_Specific_Events;
1558
            else
1559 1
               Make_Wait_Event;
1560
            end if;
1561
         end if;
1562

1563
         --  Depending on the implementation kind, call the proper
1564
         --  implementation routines.
1565

1566 1
         case Impl_Kind is
1567 1
            when Thread_With_Call_Sequence =>
1568
               --  This kind of implementation is the simplest
1569
               --  one. The user has only to implementation the
1570
               --  behaviour of subprograms and does not have to worry
1571
               --  about sending and receiving ports.
1572

1573
               --  Get IN ports values and dequeue them
1574

1575 1
               if Has_In_Ports (E) then
1576 1
                  Make_Fetch_In_Ports;
1577
               end if;
1578

1579
               --  Handle the thread call sequences
1580

1581 1
               if not AAU.Is_Empty (Calls (E)) then
1582 1
                  Make_Call_Sequence;
1583
               end if;
1584

1585
               --  Set OUT ports values
1586

1587 1
               if Has_Out_Ports (E) then
1588 1
                  Make_Set_Out_Ports;
1589
               end if;
1590

1591
               --  Send OUT ports
1592

1593 1
               if Has_Out_Ports (E) then
1594 1
                  Make_Send_Out_Ports (WStatements);
1595
               end if;
1596

1597 1
            when Thread_With_Compute_Entrypoint =>
1598
               --  Call the compute entrypoint. The code of the
1599
               --  compute entry point will include the setting of
1600
               --  the thread OUT ports.
1601

1602 1
               Make_Thread_Compute_Entrypoint;
1603

1604
               --  Send OUT ports
1605

1606
               --  FIXME: Depending on an AADL property, the code of
1607
               --  the thread entrypoint may include the sending of
1608
               --  OUT ports.
1609

1610 1
               if Has_Out_Ports (E) then
1611 1
                  Make_Send_Out_Ports (WStatements);
1612
               end if;
1613

1614 1
            when Thread_With_Port_Compute_Entrypoint =>
1615
               --  Call the compute entrypoints of the triggeing
1616
               --  port. The code of the compute entry point will
1617
               --  include the sending of the thread OUT ports.
1618

1619 1
               Make_Ports_Compute_Entrypoint;
1620

1621
               --  Send OUT ports
1622

1623
               --  FIXME: Depending on an AADL property, the code of
1624
               --  the port entrypoints may include the sending of OUT
1625
               --  ports.
1626

1627 1
               if Has_Out_Ports (E) then
1628 1
                  Make_Send_Out_Ports (WStatements);
1629
               end if;
1630

1631 1
            when Thread_With_Behavior_Specification =>
1632

1633
               --  For a periodic thread, when its BA has more than one
1634
               --  state, we call the <<thread_name>>_states_initialization
1635
               --  /** Initialize states; this function is called
1636
               --   when the BA of the thread has more than one state **/
1637
               --
1638
               --  producer_states_and_current_state_initialization ();
1639 1
               if P = Thread_Periodic or else P = Thread_Sporadic then
1640
                  declare
1641 1
                     BA : Node_Id;
1642 1
                     P1 : List_Id;
1643
                  begin
1644 1
                     BA := Get_Behavior_Specification (E);
1645 1
                     if BANu.Length (BATN.States (BA)) > 1 then
1646
                        N :=
1647 1
                          Make_Doxygen_C_Comment
1648
                            ("Initialize states",
1649
                             Has_Header_Spaces => False);
1650 1
                        Append_Node_To_List (N, Statements);
1651

1652
                        --  Call <<thread_name>>_states_initialization
1653

1654 1
                        if P = Thread_Periodic
1655 1
                          or else (P = Thread_Sporadic and then
1656 1
                              Compute_Nb_On_Dispatch_Transitions (E) = 1)
1657
                        then
1658 1
                           P1 := No_List;
1659 1
                        elsif P = Thread_Sporadic and then
1660 1
                          Compute_Nb_On_Dispatch_Transitions (E) > 1
1661
                        then
1662 1
                           P1 := Make_List_Id
1663 1
                             (Make_Defining_Identifier
1664
                                (VN (V_Next_Complete_State)));
1665
                        end if;
1666

1667 1
                        N := CTU.Make_Call_Profile
1668 1
                          (Defining_Identifier => Make_Defining_Identifier
1669 1
                             (Map_C_BA_Related_Function_Name
1670
                                  (S, States_Initialization => True)),
1671
                           Parameters          =>  P1);
1672 1
                        Append_Node_To_List (N, Statements);
1673

1674
                        N :=
1675 1
                          Make_Extern_Entity_Declaration
1676 1
                            (Make_Specification_Of_BA_Related_Function
1677
                               (E, States_Initialization => True));
1678

1679 1
                        Append_Node_To_List (N,
1680 1
                                             CTN.Declarations (Current_File));
1681
                     end if;
1682
                  end;
1683
               end if;
1684

1685 1
               Make_Thread_Behavior_Specification;
1686 1
               if Has_Out_Ports (E) then
1687 1
                  Make_Send_Out_Ports (WStatements);
1688
               end if;
1689

1690 0
            when others =>
1691 0
               raise Program_Error with "Unconsistency in Task_Job_Body";
1692 1
         end case;
1693

1694
         --  Block until the next dispatch with respect to the
1695
         --  inter-arrival time in case of a sporadic or periodic
1696
         --  thread.
1697

1698 1
         if P = Thread_Periodic or else P = Thread_Sporadic then
1699 1
            Make_Task_Blocking (WStatements);
1700
         end if;
1701

1702
         --  If an activate entrypoint has been specified for the
1703
         --  thread, add a call to the corresponding function before
1704
         --  initialization of the runtime is done.
1705

1706
         declare
1707
            Activate_Entrypoint : constant Name_Id :=
1708 1
              Get_Thread_Activate_Entrypoint (E);
1709 1
            Parameter_List : constant List_Id := New_List (CTN.K_List_Id);
1710
         begin
1711 1
            if Activate_Entrypoint /= No_Name then
1712
               N :=
1713 0
                 Make_Extern_Entity_Declaration
1714 0
                   (Make_Function_Specification
1715 0
                      (Make_Defining_Identifier (Activate_Entrypoint),
1716
                       Parameters  => Parameter_List, --  XXX
1717 0
                       Return_Type => New_Node (CTN.K_Void)));
1718 0
               Append_Node_To_List (N, CTN.Declarations (Current_File));
1719
               N :=
1720 0
                 CTU.Make_Call_Profile
1721 0
                   (Make_Defining_Identifier (Activate_Entrypoint),
1722
                    No_List);
1723 0
               Append_Node_To_List (N, Statements);
1724
            end if;
1725
         end;
1726

1727
         N :=
1728 1
           Make_Doxygen_C_Comment
1729
             ("Waiting for other tasks initialization",
1730
              Has_Header_Spaces => False);
1731 1
         Append_Node_To_List (N, Statements);
1732

1733
         --  Call __po_hi_wait_initialization
1734

1735 1
         N := CTU.Make_Call_Profile (RE (RE_Wait_Initialization), No_List);
1736 1
         Append_Node_To_List (N, Statements);
1737

1738
         --  Call __po_hi_wait_offset() iff necessary
1739

1740 1
         Make_Wait_Offset;
1741

1742
         --  Compute the next period after initialization, because
1743
         --  the period may have passed after init.
1744

1745 1
         if P = Thread_Periodic or else P = Thread_Sporadic then
1746
            N :=
1747 1
              CTU.Make_Call_Profile
1748 1
                (RE (RE_Compute_Next_Period),
1749 1
                 Make_List_Id
1750 1
                   (Make_Defining_Identifier
1751 1
                      (Map_C_Enumerator_Name (S, Current_Device))));
1752 1
            Append_Node_To_List (N, Statements);
1753
         end if;
1754

1755 1
         if P = Thread_Periodic or else P = Thread_Sporadic then
1756
            --  For periodic threads, we force a first wait to ensure
1757
            --  synchronized start after initialization. The runtime
1758
            --  computes a specific epoch to ensure such start.
1759

1760
            N :=
1761 1
              Make_Doxygen_C_Comment
1762
                ("Waiting for the first dispatch instant",
1763
                 Has_Header_Spaces => False);
1764 1
            Append_Node_To_List (N, Statements);
1765

1766 1
            Call_Parameters := New_List (CTN.K_Parameter_List);
1767
            Call_Parameters_Of_BA_Initialization_Function :=
1768 1
              New_List (CTN.K_Parameter_List);
1769 1
            if Current_Device /= No_Node then
1770
               N :=
1771 0
                 Make_Defining_Identifier
1772 0
                   (Map_C_Enumerator_Name
1773
                      (S,
1774
                       Custom_Parent => Current_Device));
1775
               N1 :=
1776 0
                 Make_Defining_Identifier
1777 0
                   (Map_C_Enumerator_Name
1778
                      (S,
1779
                       Custom_Parent => Current_Device));
1780
            else
1781 1
               N := Make_Defining_Identifier (Map_C_Enumerator_Name (S));
1782 1
               N1 := Make_Defining_Identifier (Map_C_Enumerator_Name (S));
1783
            end if;
1784 1
            Append_Node_To_List (N, Call_Parameters);
1785 1
            Append_Node_To_List
1786
              (N1,
1787
               Call_Parameters_Of_BA_Initialization_Function);
1788
            N :=
1789 1
              CTU.Make_Call_Profile
1790 1
                (RE (RE_Wait_For_Next_Period),
1791
                 Call_Parameters);
1792 1
            Append_Node_To_List (N, Statements);
1793

1794 1
            if Impl_Kind = Thread_With_Behavior_Specification then
1795
               declare
1796 1
                  BA : Node_Id;
1797
               begin
1798 1
                  if not AAU.Is_Empty (Subcomponents (E)) then
1799 1
                     N1 := First_Node (Subcomponents (E));
1800

1801 1
                     while Present (N1) loop
1802 1
                        if AAU.Is_Data (Corresponding_Instance (N1)) then
1803

1804
                           N :=
1805 1
                             Make_Variable_Address
1806 1
                               (Map_C_Defining_Identifier (N1));
1807

1808 1
                           Append_Node_To_List
1809
                             (N,
1810
                              Call_Parameters_Of_BA_Initialization_Function);
1811

1812
                        end if;
1813 1
                        N1 := Next_Node (N1);
1814 1
                     end loop;
1815
                  end if;
1816

1817 1
                  BA := Get_Behavior_Specification (E);
1818 1
                  if BANu.Length (BATN.States (BA)) > 1 then
1819

1820 1
                     if Is_To_Make_Init_Sequence (E) then
1821
                        --  Call the function implementing the initialization
1822
                        --  sequence this is in the case when initial state
1823
                        --  is neither complete nor final
1824

1825
                        N :=
1826 1
                          Make_Doxygen_C_Comment
1827
                            ("Call the function implementing the "
1828
                             & "initialization sequence this is in the case "
1829
                             & "when initial state is neither complete "
1830
                             & "nor final",
1831
                             Has_Header_Spaces => False);
1832 1
                        Append_Node_To_List (N, Statements);
1833

1834 1
                        N := CTU.Make_Call_Profile
1835 1
                          (Defining_Identifier => Make_Defining_Identifier
1836 1
                             (Map_C_BA_Related_Function_Name
1837
                                  (S, BA_Initialization => True)),
1838
                           Parameters          =>
1839
                             Call_Parameters_Of_BA_Initialization_Function);
1840 1
                        Append_Node_To_List (N, Statements);
1841

1842
                        N :=
1843 1
                          Make_Extern_Entity_Declaration
1844 1
                            (Make_Specification_Of_BA_Related_Function
1845
                               (E, BA_Initialization => True));
1846

1847 1
                        Append_Node_To_List (N,
1848 1
                                             CTN.Declarations (Current_File));
1849

1850 1
                        if Has_Out_Ports (E) then
1851 1
                           Make_Send_Out_Ports (Statements);
1852
                        end if;
1853

1854 1
                        Make_Task_Blocking (Statements);
1855

1856
                     end if;
1857
                  end if;
1858
               end;
1859
            end if;
1860
         end if;
1861

1862 1
         if P /= Thread_Background then
1863
            --  Make the while (1){} and add all statements
1864
            N :=
1865 1
              Make_Doxygen_C_Comment
1866
                ("Task body",
1867
                 Has_Header_Spaces => False);
1868 1
            Append_Node_To_List (N, Statements);
1869

1870
            N :=
1871 1
              Make_While_Statement
1872 1
                (Make_Literal (CV.New_Int_Value (1, 0, 10)),
1873
                 WStatements);
1874 1
            Append_Node_To_List (N, Statements);
1875
         else
1876
            --  Simply append statements
1877 1
            Append_Node_To_List (CTN.First_Node (WStatements), Statements);
1878
         end if;
1879

1880 1
         N := Make_Function_Implementation (Spec, Declarations, Statements);
1881

1882 1
         return N;
1883
      end Task_Job_Body;
1884

1885
      -----------
1886
      -- Visit --
1887
      -----------
1888

1889 1
      procedure Visit (E : Node_Id) is
1890
      begin
1891 1
         case Kind (E) is
1892 1
            when K_Architecture_Instance =>
1893 1
               Visit_Architecture_Instance (E);
1894

1895 1
            when K_Component_Instance =>
1896 1
               Visit_Component_Instance (E);
1897

1898 0
            when others =>
1899 0
               null;
1900 1
         end case;
1901 1
      end Visit;
1902

1903
      ---------------------------------
1904
      -- Visit_Architecture_Instance --
1905
      ---------------------------------
1906

1907 1
      procedure Visit_Architecture_Instance (E : Node_Id) is
1908
      begin
1909 1
         Visit (Root_System (E));
1910 1
      end Visit_Architecture_Instance;
1911

1912
      ------------------------------
1913
      -- Visit_Component_Instance --
1914
      ------------------------------
1915

1916 1
      procedure Visit_Component_Instance (E : Node_Id) is
1917
         Category : constant Component_Category :=
1918 1
           Get_Category_Of_Component (E);
1919
      begin
1920 1
         case Category is
1921 1
            when CC_System =>
1922 1
               Visit_System_Instance (E);
1923

1924 1
            when CC_Process =>
1925 1
               Visit_Process_Instance (E);
1926

1927 1
            when CC_Thread =>
1928 1
               Visit_Thread_Instance (E);
1929

1930 1
            when others =>
1931 1
               null;
1932 1
         end case;
1933 1
      end Visit_Component_Instance;
1934

1935
      ----------------------------
1936
      -- Visit_Process_Instance --
1937
      ----------------------------
1938

1939 1
      procedure Visit_Process_Instance (E : Node_Id) is
1940
         U : constant Node_Id :=
1941 1
           CTN.Distributed_Application_Unit
1942 1
             (CTN.Naming_Node (Backend_Node (Identifier (E))));
1943 1
         P            : constant Node_Id := CTN.Entity (U);
1944 1
         S            : Node_Id;
1945 1
         N            : Node_Id;
1946 1
         Declarations : constant List_Id := New_List (CTN.K_Declaration_List);
1947 1
         Statements   : constant List_Id := New_List (CTN.K_Statement_List);
1948
         The_System   : constant Node_Id :=
1949 1
           Parent_Component (Parent_Subcomponent (E));
1950

1951 1
         Init_Spec : Node_Id;
1952
         Init_Declarations : constant List_Id
1953 1
           := New_List (CTN.K_Declaration_List);
1954
         Init_Statements   : constant List_Id
1955 1
           := New_List (CTN.K_Statement_List);
1956

1957
      begin
1958 1
         Push_Entity (P);
1959 1
         Push_Entity (U);
1960 1
         CTU.Set_Activity_Source (U);
1961

1962 1
         Main_Deliver_Alternatives := New_List (CTN.K_Alternatives_List);
1963

1964
         --  Define the __po_hi_main_initialize() function, in charge
1965
         --  of initializing all threads gqueues and other structures.
1966

1967
         Init_Spec :=
1968 1
           Make_Function_Specification
1969 1
           (Defining_Identifier => RE (RE_Main_Initialize),
1970 1
            Parameters          => New_List (CTN.K_Parameter_List),
1971 1
            Return_Type         => New_Node (CTN.K_Void));
1972 1
         Append_Node_To_List (Init_Spec, CTN.Declarations (Current_File));
1973

1974
         --  Visit all the subcomponents of the process
1975

1976 1
         if not AAU.Is_Empty (Subcomponents (E)) then
1977 1
            S := First_Node (Subcomponents (E));
1978

1979 1
            while Present (S) loop
1980 1
               if AAU.Is_Data (Corresponding_Instance (S)) then
1981
                  N :=
1982 1
                    Make_Variable_Declaration
1983 1
                      (Map_C_Defining_Identifier (S),
1984 1
                       Map_C_Data_Type_Designator
1985 1
                         (Corresponding_Instance (S)));
1986

1987 1
                  Append_Node_To_List
1988 1
                    (Make_Extern_Entity_Declaration (N),
1989 1
                     CTN.Declarations (Current_File));
1990

1991 1
                  Bind_AADL_To_Object (Identifier (S), N);
1992

1993 1
               elsif AAU.Is_Thread (Corresponding_Instance (S)) then
1994 1
                  Append_Node_To_List
1995 1
                    (Task_Initialize (Corresponding_Instance (S)),
1996
                     Init_Statements);
1997

1998
               end if;
1999 1
               S := Next_Node (S);
2000 1
            end loop;
2001
         end if;
2002

2003 1
         if not AAU.Is_Empty (Subcomponents (E)) then
2004 1
            S := First_Node (Subcomponents (E));
2005

2006 1
            while Present (S) loop
2007 1
               if not AAU.Is_Data (Corresponding_Instance (S)) then
2008 1
                  Visit (Corresponding_Instance (S));
2009
               end if;
2010 1
               S := Next_Node (S);
2011 1
            end loop;
2012
         end if;
2013

2014
         --  Visit all devices attached to the parent system that
2015
         --  share the same processor as process E.
2016

2017 1
         if not AAU.Is_Empty (Subcomponents (The_System)) then
2018 1
            S := First_Node (Subcomponents (The_System));
2019 1
            while Present (S) loop
2020 1
               if AAU.Is_Device (Corresponding_Instance (S))
2021
                 and then
2022 1
                 Get_Bound_Processor (Corresponding_Instance (S)) =
2023 1
                 Get_Bound_Processor (E)
2024
               then
2025 1
                  Visit_Device_Instance (Corresponding_Instance (S));
2026
               end if;
2027 1
               S := Next_Node (S);
2028 1
            end loop;
2029
         end if;
2030

2031 1
         if Present (Backend_Node (Identifier (Parent_Subcomponent (E))))
2032 1
           and then Present
2033 1
             (CTN.Job_Node
2034 1
                (Backend_Node (Identifier (Parent_Subcomponent (E)))))
2035
         then
2036 1
            Append_Node_To_List
2037 1
              (Make_Variable_Declaration
2038
                 (Defining_Identifier =>
2039 1
                    Make_Defining_Identifier (VN (V_Entity)),
2040 1
                  Used_Type => RE (RE_Entity_T)),
2041
               Declarations);
2042

2043
            --  Add the call to entity = __po_hi_global...[port]
2044

2045
            N :=
2046 1
              Make_Expression
2047 1
                (Left_Expr  => Make_Defining_Identifier (VN (V_Entity)),
2048
                 Operator   => Op_Equal,
2049
                 Right_Expr =>
2050 1
                   Make_Call_Profile
2051 1
                     (RE (RE_Get_Entity_From_Global_Port),
2052 1
                      Make_List_Id
2053 1
                        (Make_Member_Designator
2054
                           (Defining_Identifier =>
2055 1
                              Make_Defining_Identifier (MN (M_Port)),
2056
                            Is_Pointer     => True,
2057
                            Aggregate_Name =>
2058 1
                              Make_Defining_Identifier (VN (V_Request))))));
2059 1
            Append_Node_To_List (N, Statements);
2060

2061
            --  Add the switch which redirect to local deliver functions
2062

2063 1
            N := Make_Switch_Alternative (No_List, No_List);
2064

2065 1
            Append_Node_To_List (N, Main_Deliver_Alternatives);
2066

2067
            N :=
2068 1
              Make_Switch_Statement
2069 1
                (Expression   => Make_Defining_Identifier (VN (V_Entity)),
2070
                 Alternatives => Main_Deliver_Alternatives);
2071

2072 1
            Append_Node_To_List (N, Statements);
2073

2074
            N :=
2075 1
              Make_Doxygen_C_Comment
2076
                (Is_Function  => True,
2077
                 Element_Name =>
2078
                   "void __po_hi_main_deliver " &
2079
                     "(__po_hi_request_t* request)",
2080
                 Brief => "Used to deliver request to the appropriate ports",
2081
                 Desc  =>
2082
                   "This function takes a request as argument (\arg request)" &
2083
                     " and calls the appropriate function for its delivery." &
2084
                     "To specify which function should be called, it " &
2085
                     "extracts the receiver entity using the destination " &
2086
                     "port.",
2087
                 Has_Header_Spaces => False);
2088 1
            Append_Node_To_List (N, CTN.Declarations (Current_File));
2089

2090
            N :=
2091 1
              Make_Function_Implementation
2092 1
                (CTN.Job_Node
2093 1
                   (Backend_Node (Identifier (Parent_Subcomponent (E)))),
2094
                 Declarations,
2095
                 Statements);
2096 1
            Append_Node_To_List (N, CTN.Declarations (Current_File));
2097
            N :=
2098 1
              Make_Function_Implementation
2099
                (Init_Spec,
2100
                 Init_Declarations,
2101
                 Init_Statements);
2102 1
            Append_Node_To_List (N, CTN.Declarations (Current_File));
2103
         end if;
2104

2105 1
         Pop_Entity; -- U
2106 1
         Pop_Entity; -- P
2107 1
      end Visit_Process_Instance;
2108

2109
      ---------------------------
2110
      -- Visit_Device_Instance --
2111
      ---------------------------
2112

2113 1
      procedure Visit_Device_Instance (E : Node_Id) is
2114 1
         Implementation : constant Node_Id := Get_Implementation (E);
2115 1
         S              : Node_Id;
2116
      begin
2117 1
         Current_Device := E;
2118

2119 1
         if Implementation /= No_Node then
2120 1
            if not AAU.Is_Empty (AAN.Subcomponents (Implementation)) then
2121 1
               S := First_Node (Subcomponents (Implementation));
2122 1
               while Present (S) loop
2123 1
                  Visit_Component_Instance (Corresponding_Instance (S));
2124 1
                  S := Next_Node (S);
2125 1
               end loop;
2126
            end if;
2127
         end if;
2128

2129 1
         Current_Device := No_Node;
2130 1
      end Visit_Device_Instance;
2131

2132
      ---------------------------
2133
      -- Visit_System_Instance --
2134
      ---------------------------
2135

2136 1
      procedure Visit_System_Instance (E : Node_Id) is
2137 1
         S : Node_Id;
2138
      begin
2139 1
         Push_Entity (C_Root);
2140

2141
         --  Visit all the subcomponents of the system
2142

2143 1
         if not AAU.Is_Empty (Subcomponents (E)) then
2144 1
            S := First_Node (Subcomponents (E));
2145

2146 1
            while Present (S) loop
2147
               --  Visit the component instance corresponding to the
2148
               --  subcomponent S.
2149

2150 1
               Visit (Corresponding_Instance (S));
2151 1
               S := Next_Node (S);
2152 1
            end loop;
2153
         end if;
2154

2155 1
         Pop_Entity; --  C_Root
2156 1
      end Visit_System_Instance;
2157

2158
      ---------------------------
2159
      -- Visit_Thread_Instance --
2160
      ---------------------------
2161

2162 1
      procedure Visit_Thread_Instance (E : Node_Id) is
2163 1
         S                    : constant Node_Id   := Parent_Subcomponent (E);
2164 1
         N                    : Node_Id;
2165 1
         F                    : Node_Id;
2166 1
         D                    : Node_Id;
2167 1
         Fifo_Size_Values     : Node_Id;
2168 1
         N_Dest_Values        : Node_Id;
2169 1
         Local_Dest_Values    : Node_Id;
2170 1
         Destinations_Values  : Node_Id;
2171 1
         Destinations         : List_Id;
2172 1
         Deliver_Declarations : List_Id;
2173 1
         Deliver_Statements   : List_Id;
2174 1
         Deliver_Alternatives : List_Id;
2175 1
         Switch_Labels        : List_Id;
2176 1
         Switch_Statements    : List_Id;
2177 1
         Parameters           : List_Id;
2178 1
         Queue_Size           : Long_Long;
2179 1
         Fifo_Size            : Unsigned_Long_Long := 0;
2180 1
         Nb_Dest              : Unsigned_Long_Long := 0;
2181 1
         Has_Local_Deliver    : Boolean            := False;
2182
      begin
2183 1
         if Get_Thread_Dispatch_Protocol (E) = Thread_Sporadic and then
2184 1
           not Has_In_Event_Ports (E)
2185
         then
2186 0
            Display_Located_Error
2187 0
              (Loc (E),
2188
               "None of the IN ports of this sporadic thread is an event port",
2189
               Fatal => True);
2190
         end if;
2191

2192 1
         if Has_Ports (E) then
2193 1
            F := First_Node (Features (E));
2194

2195 1
            Fifo_Size_Values    := Make_Array_Values;
2196 1
            N_Dest_Values       := Make_Array_Values;
2197 1
            Destinations_Values := Make_Array_Values;
2198

2199 1
            Deliver_Declarations := New_List (CTN.K_Declaration_List);
2200 1
            Deliver_Statements   := New_List (CTN.K_Statement_List);
2201 1
            Deliver_Alternatives := New_List (CTN.K_Alternatives_List);
2202

2203 1
            while Present (F) loop
2204 1
               if Kind (F) = K_Port_Spec_Instance then
2205

2206 1
                  if Is_Out (F) then
2207 1
                     Destinations := Get_Destination_Ports (F, Current_Device);
2208 1
                     Local_Dest_Values := Make_Array_Values;
2209

2210 1
                     if AAU.Is_Empty (Destinations) then
2211 0
                        Display_Located_Error
2212 0
                          (Loc (F),
2213
                           "This OUT port is not connected to any" &
2214
                             " destination",
2215
                           Fatal => True);
2216
                     end if;
2217

2218 1
                     D := First_Node (Destinations);
2219

2220 1
                     Nb_Dest := 0;
2221

2222 1
                     while Present (D) loop
2223 1
                        Append_Node_To_List
2224 1
                          (Make_Defining_Identifier
2225 1
                             (Map_C_Enumerator_Name
2226 1
                                (Item (D),
2227
                                 Port_Type => True)),
2228 1
                           CTN.Values (Local_Dest_Values));
2229

2230 1
                        Nb_Dest := Nb_Dest + 1;
2231

2232 1
                        D := Next_Node (D);
2233 1
                     end loop;
2234

2235
                     --  Make the array which indicate all destinations
2236
                     --  for an out port
2237

2238
                     N :=
2239 1
                       Make_Expression
2240
                         (Left_Expr =>
2241 1
                            Make_Variable_Declaration
2242
                              (Defining_Identifier =>
2243 1
                                 Make_Array_Declaration
2244
                                   (Defining_Identifier =>
2245 1
                                      Make_Defining_Identifier
2246 1
                                        (Map_C_Variable_Name
2247
                                           (F,
2248
                                            Port_Local_Dest => True)),
2249
                                    Array_Size =>
2250 1
                                      Make_Literal
2251 1
                                        (CV.New_Int_Value (Nb_Dest, 0, 10))),
2252 1
                               Used_Type => RE (RE_Port_T)),
2253
                          Operator   => Op_Equal,
2254
                          Right_Expr => Local_Dest_Values);
2255 1
                     Append_Node_To_List (N, CTN.Declarations (Current_File));
2256

2257
                     --  Add the last array name in the destination array
2258

2259 1
                     Append_Node_To_List
2260 1
                       (Make_Defining_Identifier
2261 1
                          (Map_C_Variable_Name (F, Port_Local_Dest => True)),
2262 1
                        CTN.Values (Destinations_Values));
2263

2264
                     --  Add the number of destinations in the nb_dest array
2265

2266 1
                     N := RE (RE_Gqueue_Fifo_Out);
2267 1
                     Append_Node_To_List
2268 1
                       (Make_Literal (CV.New_Int_Value (Nb_Dest, 0, 10)),
2269 1
                        CTN.Values (N_Dest_Values));
2270

2271 1
                     Append_Node_To_List (N, CTN.Values (Fifo_Size_Values));
2272
                  else
2273 1
                     if AAN.Is_Data (F) and then not Is_Event (F) then
2274

2275 1
                        Has_Local_Deliver := True;
2276 1
                        N                 := RE (RE_Gqueue_Fifo_Indata);
2277 1
                        Queue_Size        := 0;
2278
                     else
2279

2280 1
                        Has_Local_Deliver := True;
2281

2282 1
                        Queue_Size := Get_Queue_Size (F);
2283

2284 1
                        if Queue_Size = -1 then
2285 1
                           Queue_Size := Default_Queue_Size;
2286

2287
                           N :=
2288 1
                             Make_Literal
2289 1
                               (CV.New_Int_Value (Default_Queue_Size, 0, 10));
2290 1
                        elsif Queue_Size = 0 then
2291
                           --  0 length queues are not supported
2292

2293 0
                           Display_Located_Error
2294 0
                             (Loc (F),
2295
                              "Zero length port queues are not supported",
2296
                              Fatal => True);
2297
                        else
2298
                           N :=
2299 1
                             Make_Literal
2300 1
                               (CV.New_Int_Value
2301
                                  (Unsigned_Long_Long (Queue_Size),
2302
                                   0,
2303
                                   10));
2304
                        end if;
2305
                     end if;
2306

2307 1
                     Append_Node_To_List (N, CTN.Values (Fifo_Size_Values));
2308

2309 1
                     Append_Node_To_List
2310 1
                       (Make_Literal (CV.New_Int_Value (0, 0, 10)),
2311 1
                        CTN.Values (N_Dest_Values));
2312

2313
                     N :=
2314 1
                       Make_Defining_Identifier
2315
                         (CONST (C_Null),
2316
                          C_Conversion => False);
2317 1
                     Append_Node_To_List (N, CTN.Values (Destinations_Values));
2318

2319
                     --  Make the switch alternative for the deliver function
2320

2321 1
                     Parameters        := New_List (CTN.K_Parameter_List);
2322 1
                     Switch_Statements := New_List (CTN.K_Statement_List);
2323 1
                     Switch_Labels     := New_List (CTN.K_Label_List);
2324

2325 1
                     Append_Node_To_List
2326 1
                       (Make_Defining_Identifier
2327 1
                          (Map_C_Enumerator_Name (F, Port_Type => True)),
2328
                        Switch_Labels);
2329

2330 1
                     Append_Node_To_List
2331 1
                       (Make_Defining_Identifier (Map_C_Enumerator_Name (S)),
2332
                        Parameters);
2333

2334 1
                     Append_Node_To_List
2335 1
                       (Make_Defining_Identifier
2336 1
                          (Map_C_Enumerator_Name (F, Local_Port => True)),
2337
                        Parameters);
2338

2339 1
                     Append_Node_To_List
2340 1
                       (Make_Defining_Identifier (PN (P_Request)),
2341
                        Parameters);
2342

2343
                     N :=
2344 1
                       Make_Call_Profile (RE (RE_Gqueue_Store_In), Parameters);
2345

2346 1
                     Append_Node_To_List (N, Switch_Statements);
2347

2348
                     N :=
2349 1
                       Make_Switch_Alternative
2350
                         (Switch_Labels,
2351
                          Switch_Statements);
2352 1
                     Append_Node_To_List (N, Deliver_Alternatives);
2353

2354 1
                     Fifo_Size := Fifo_Size + Unsigned_Long_Long (Queue_Size);
2355
                  end if;
2356

2357
               end if;
2358 1
               F := Next_Node (F);
2359 1
            end loop;
2360

2361
            --  Declare all the needed tables by each thread in order
2362
            --  to handle the ports.
2363

2364
            N :=
2365 1
              Make_Variable_Declaration
2366
                (Defining_Identifier =>
2367 1
                   Make_Array_Declaration
2368
                     (Defining_Identifier =>
2369 1
                        Make_Defining_Identifier
2370 1
                          (Map_C_Variable_Name (S, Port_Woffsets => True)),
2371
                      Array_Size =>
2372 1
                        Make_Defining_Identifier
2373 1
                          (Map_C_Define_Name (S, Nb_Ports => True))),
2374 1
                 Used_Type => RE (RE_Port_Id_T));
2375 1
            Append_Node_To_List (N, CTN.Declarations (Current_File));
2376

2377
            N :=
2378 1
              Make_Variable_Declaration
2379
                (Defining_Identifier =>
2380 1
                   Make_Array_Declaration
2381
                     (Defining_Identifier =>
2382 1
                        Make_Defining_Identifier
2383 1
                          (Map_C_Variable_Name (S, Port_Offsets => True)),
2384
                      Array_Size =>
2385 1
                        Make_Defining_Identifier
2386 1
                          (Map_C_Define_Name (S, Nb_Ports => True))),
2387 1
                 Used_Type => RE (RE_Port_Id_T));
2388 1
            Append_Node_To_List (N, CTN.Declarations (Current_File));
2389

2390
            N :=
2391 1
              Make_Variable_Declaration
2392
                (Defining_Identifier =>
2393 1
                   Make_Array_Declaration
2394
                     (Defining_Identifier =>
2395 1
                        Make_Defining_Identifier
2396 1
                          (Map_C_Variable_Name (S, Port_Used_Size => True)),
2397
                      Array_Size =>
2398 1
                        Make_Defining_Identifier
2399 1
                          (Map_C_Define_Name (S, Nb_Ports => True))),
2400 1
                 Used_Type => RE (RE_Port_Id_T));
2401 1
            Append_Node_To_List (N, CTN.Declarations (Current_File));
2402

2403
            N :=
2404 1
              Make_Variable_Declaration
2405
                (Defining_Identifier =>
2406 1
                   Make_Array_Declaration
2407
                     (Defining_Identifier =>
2408 1
                        Make_Defining_Identifier
2409 1
                          (Map_C_Variable_Name (S, Port_Empties => True)),
2410
                      Array_Size =>
2411 1
                        Make_Defining_Identifier
2412 1
                          (Map_C_Define_Name (S, Nb_Ports => True))),
2413 1
                 Used_Type => RE (RE_Port_Id_T));
2414 1
            Append_Node_To_List (N, CTN.Declarations (Current_File));
2415

2416
            N :=
2417 1
              Make_Variable_Declaration
2418
                (Defining_Identifier =>
2419 1
                   Make_Array_Declaration
2420
                     (Defining_Identifier =>
2421 1
                        Make_Defining_Identifier
2422 1
                          (Map_C_Variable_Name (S, Port_First => True)),
2423
                      Array_Size =>
2424 1
                        Make_Defining_Identifier
2425 1
                          (Map_C_Define_Name (S, Nb_Ports => True))),
2426 1
                 Used_Type => RE (RE_Port_Id_T));
2427 1
            Append_Node_To_List (N, CTN.Declarations (Current_File));
2428

2429
            N :=
2430 1
              Make_Variable_Declaration
2431
                (Defining_Identifier =>
2432 1
                   Make_Array_Declaration
2433
                     (Defining_Identifier =>
2434 1
                        Make_Defining_Identifier
2435 1
                          (Map_C_Variable_Name (S, Port_Recent => True)),
2436
                      Array_Size =>
2437 1
                        Make_Defining_Identifier
2438 1
                          (Map_C_Define_Name (S, Nb_Ports => True))),
2439 1
                 Used_Type => RE (RE_Request_T));
2440 1
            Append_Node_To_List (N, CTN.Declarations (Current_File));
2441

2442
            N :=
2443 1
              Make_Variable_Declaration
2444
                (Defining_Identifier =>
2445 1
                   Make_Array_Declaration
2446
                     (Defining_Identifier =>
2447 1
                        Make_Defining_Identifier
2448 1
                          (Map_C_Variable_Name (S, Port_Queue => True)),
2449
                      Array_Size =>
2450 1
                        Make_Literal
2451 1
                          (CV.New_Int_Value (Fifo_Size, 0, 10))),
2452 1
                 Used_Type => RE (RE_Request_T));
2453 1
            Append_Node_To_List (N, CTN.Declarations (Current_File));
2454

2455
            N :=
2456 1
              Make_Variable_Declaration
2457
                (Defining_Identifier =>
2458 1
                   Make_Expression
2459
                     (Left_Expr =>
2460 1
                        Make_Defining_Identifier
2461 1
                          (Map_C_Variable_Name (S, Port_Total_Fifo => True)),
2462
                      Operator   => Op_Equal,
2463
                      Right_Expr =>
2464 1
                        Make_Literal (CV.New_Int_Value (Fifo_Size, 0, 10))),
2465 1
                 Used_Type => RE (RE_Uint16_T));
2466 1
            Append_Node_To_List (N, CTN.Declarations (Current_File));
2467

2468
            N :=
2469 1
              Make_Variable_Declaration
2470
                (Defining_Identifier =>
2471 1
                   Make_Array_Declaration
2472
                     (Defining_Identifier =>
2473 1
                        Make_Defining_Identifier
2474 1
                          (Map_C_Variable_Name (S, Port_History => True)),
2475
                      Array_Size =>
2476 1
                        Make_Literal (CV.New_Int_Value (Fifo_Size, 0, 10))),
2477 1
                 Used_Type => RE (RE_Local_Port_T));
2478 1
            Append_Node_To_List (N, CTN.Declarations (Current_File));
2479

2480
            N :=
2481 1
              Make_Expression
2482
                (Left_Expr =>
2483 1
                   Make_Variable_Declaration
2484
                     (Defining_Identifier =>
2485 1
                        Make_Array_Declaration
2486
                          (Defining_Identifier =>
2487 1
                             Make_Defining_Identifier
2488 1
                               (Map_C_Variable_Name (S, Port_N_Dest => True)),
2489
                           Array_Size =>
2490 1
                             Make_Defining_Identifier
2491 1
                               (Map_C_Define_Name (S, Nb_Ports => True))),
2492 1
                      Used_Type => RE (RE_Port_Id_T)),
2493
                 Operator   => Op_Equal,
2494
                 Right_Expr => N_Dest_Values);
2495 1
            Append_Node_To_List (N, CTN.Declarations (Current_File));
2496

2497
            N :=
2498 1
              Make_Expression
2499
                (Left_Expr =>
2500 1
                   Make_Variable_Declaration
2501
                     (Defining_Identifier =>
2502 1
                        Make_Array_Declaration
2503
                          (Defining_Identifier =>
2504 1
                             Make_Defining_Identifier
2505 1
                               (Map_C_Variable_Name
2506
                                  (S,
2507
                                   Port_Fifo_Size => True)),
2508
                           Array_Size =>
2509 1
                             Make_Defining_Identifier
2510 1
                               (Map_C_Define_Name (S, Nb_Ports => True))),
2511 1
                      Used_Type => RE (RE_Port_Id_T)),
2512
                 Operator   => Op_Equal,
2513
                 Right_Expr => Fifo_Size_Values);
2514 1
            Append_Node_To_List (N, CTN.Declarations (Current_File));
2515

2516
            N :=
2517 1
              Make_Expression
2518
                (Left_Expr =>
2519 1
                   Make_Variable_Declaration
2520
                     (Defining_Identifier =>
2521 1
                        Make_Array_Declaration
2522
                          (Defining_Identifier =>
2523 1
                             Make_Defining_Identifier
2524 1
                               (Map_C_Variable_Name
2525
                                  (S,
2526
                                   Port_Destinations => True)),
2527
                           Array_Size =>
2528 1
                             Make_Defining_Identifier
2529 1
                               (Map_C_Define_Name (S, Nb_Ports => True))),
2530 1
                      Used_Type => Make_Pointer_Type (RE (RE_Port_T))),
2531
                 Operator   => Op_Equal,
2532
                 Right_Expr => Destinations_Values);
2533 1
            Append_Node_To_List (N, CTN.Declarations (Current_File));
2534

2535 1
            Append_Node_To_List
2536 1
              (Make_Switch_Alternative (No_List, No_List),
2537
               Deliver_Alternatives);
2538

2539 1
            if Has_Local_Deliver then
2540
               N :=
2541 1
                 Make_Switch_Statement
2542
                   (Expression =>
2543 1
                      Make_Member_Designator
2544
                        (Defining_Identifier =>
2545 1
                           Make_Defining_Identifier (MN (M_Port)),
2546
                         Aggregate_Name =>
2547 1
                           Make_Defining_Identifier (VN (V_Request)),
2548
                         Is_Pointer => True),
2549
                    Alternatives => Deliver_Alternatives);
2550

2551 1
               Append_Node_To_List (N, Deliver_Statements);
2552

2553
               --  Make the deliver function specific to a thread
2554 1
               N :=
2555 1
                 Make_Doxygen_C_Comment
2556
                   (Is_Function  => True,
2557
                    Element_Name =>
2558
                      "void " &
2559 1
                        Get_Name_String
2560 1
                        (CTN.Name
2561 1
                           (CTN.Defining_Identifier
2562 1
                              (CTN.Global_Port_Node
2563 1
                                 (Backend_Node (Identifier (S)))))) &
2564
                        " (__po_hi_request_t* request)",
2565
                    Brief =>
2566 1
                      "Function that delivers requests to the task " &
2567 1
                        Get_Name_String (Name (Identifier (S))),
2568
                    Desc =>
2569
                      "When the generated application received a request," &
2570
                        " it calls a main delivery function that redirects" &
2571
                        " to localfunctions for each task. This function (" &
2572 1
                        Get_Name_String
2573 1
                        (CTN.Name
2574 1
                           (CTN.Defining_Identifier
2575 1
                              (CTN.Global_Port_Node
2576 1
                                 (Backend_Node (Identifier (S)))))) &
2577 1
                        ") stores the incoming request for the task" &
2578 1
                        Get_Name_String (Name (Identifier (S))),
2579
                    Has_Header_Spaces => False);
2580 1
               Append_Node_To_List (N, CTN.Declarations (Current_File));
2581

2582
               N :=
2583 1
                 Make_Function_Implementation
2584 1
                   (CTN.Global_Port_Node (Backend_Node (Identifier (S))),
2585
                    Deliver_Declarations,
2586
                    Deliver_Statements);
2587 1
               Append_Node_To_List (N, CTN.Declarations (Current_File));
2588

2589
               --  Add a switch alternative to the main deliver
2590
               --  in order to used our local delivery function.
2591

2592 1
               Parameters        := New_List (CTN.K_Parameter_List);
2593 1
               Switch_Statements := New_List (CTN.K_Statement_List);
2594 1
               Switch_Labels     := New_List (CTN.K_Label_List);
2595

2596 1
               Append_Node_To_List
2597 1
                 (Make_Defining_Identifier
2598 1
                    (Map_C_Enumerator_Name (S, Entity => True)),
2599
                  Switch_Labels);
2600

2601 1
               Append_Node_To_List
2602 1
                 (Make_Defining_Identifier (VN (V_Request)),
2603
                  Parameters);
2604

2605
               N :=
2606 1
                 Make_Call_Profile
2607 1
                   (Defining_Identifier => Map_Task_Deliver_Identifier (S),
2608
                    Parameters          => Parameters);
2609

2610 1
               Append_Node_To_List (N, Switch_Statements);
2611

2612 1
               N := Make_Switch_Alternative (Switch_Labels, Switch_Statements);
2613

2614 1
               Append_Node_To_List (N, Main_Deliver_Alternatives);
2615
            end if;
2616
         end if;
2617

2618 1
         N :=
2619 1
           Make_Doxygen_C_Comment
2620
             (Is_Function  => True,
2621
              Element_Name =>
2622
                "void* " &
2623 1
                  Get_Name_String
2624 1
                  (CTN.Name (Map_Task_Job_Identifier (S, Current_Device))) &
2625
                  " (void)",
2626
              Brief =>
2627 1
                "Function executed by the task " &
2628 1
                  Get_Name_String (Name (Identifier (S))),
2629
              Desc =>
2630
                "This function is executed as soon as the task " &
2631
                  " is created. It performs the following operations: " &
2632
                  " Receive incoming data, " &
2633
                  " Execute tasks subprograms, " &
2634
                  " Send output data.",
2635
              Has_Header_Spaces => False);
2636 1
         Append_Node_To_List (N, CTN.Declarations (Current_File));
2637

2638 1
         N := Task_Job_Body (E);
2639 1
         Append_Node_To_List (N, CTN.Declarations (Current_File));
2640

2641 1
      end Visit_Thread_Instance;
2642

2643
   end Source_File;
2644

2645 1
end Ocarina.Backends.PO_HI_C.Activity;

Read our documentation on viewing source code .

Loading