taste-concurrency_view.adb 23.5 KB
Newer Older
1
--  *************************** kazoo ***********************  --
Maxime Perrotin's avatar
Maxime Perrotin committed
2
--  (c) 2019 European Space Agency - maxime.perrotin@esa.int
3
4
--  LGPL license, see LICENSE file

Maxime Perrotin's avatar
Maxime Perrotin committed
5
6
with Ada.Directories,
     Ada.IO_Exceptions,
Maxime Perrotin's avatar
Maxime Perrotin committed
7
8
     Ada.Exceptions,
     Ada.Characters.Latin_1;
Maxime Perrotin's avatar
Maxime Perrotin committed
9
10
11

use Ada.Directories;

12
13
package body TASTE.Concurrency_View is

Maxime Perrotin's avatar
Maxime Perrotin committed
14
15
   Newline : Character renames Ada.Characters.Latin_1.LF;

16
   procedure Debug_Dump (CV : Taste_Concurrency_View; Output : File_Type) is
Maxime Perrotin's avatar
Maxime Perrotin committed
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
      procedure Dump_Partition (Partition : CV_Partition) is
      begin
         for Block of Partition.Blocks loop
            Put_Line (Output, "Protected Block : " & To_String (Block.Name));
            for Provided of Block.Provided loop
               Put_Line (Output, " |_ PI : " & To_String (Provided.Name));
            end loop;
            for Required of Block.Required loop
               Put_Line (Output, " |_ RI : " & To_String (Required.Name));
            end loop;
            for Thread of Block.Calling_Threads loop
               Put_Line (Output, " |_ Calling_Thread : " & Thread);
            end loop;
            if Block.Node.Has_Value then
               Put_Line (Output, " |_ Node : "
                         & To_String (Block.Node.Unsafe_Just.Name));
               declare
                  P : constant Taste_Partition :=
                    Block.Node.Unsafe_Just.Find_Partition
                      (To_String (Block.Name)).Unsafe_Just;
               begin
                  Put_Line (Output, " |_ Partition : " & To_String (P.Name));
                  Put_Line (Output, "   |_ Coverage       : "
                            & P.Coverage'Img);
                  Put_Line (Output, "   |_ Package        : "
                            & To_String (P.Package_Name));
                  Put_Line (Output, "   |_ CPU Name       : "
                            & To_String (P.CPU_Name));
                  Put_Line (Output, "   |_ CPU Platform   : "
                            & P.CPU_Platform'Img);
                  Put_Line (Output, "   |_ CPU Classifier : "
                            & To_String (P.CPU_Classifier));
               end;
            end if;
Maxime Perrotin's avatar
Maxime Perrotin committed
51
         end loop;
52

Maxime Perrotin's avatar
Maxime Perrotin committed
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
         for Thread of Partition.Threads loop
            Put_Line (Output, "Thread : " & To_String (Thread.Name));
            Put_Line (Output, " |_ Port : "
                      & To_String (Thread.Entry_Port_Name));
            Put_Line (Output, " |_ Protected Block : "
                      & To_String (Thread.Protected_Block_Name));
            Put_Line (Output, " |_ Node : "
                      & To_String (Thread.Node.Value_Or
                        (Taste_Node'(Name   => US ("(none)"),
                                     others => <>)).Name));
            for Out_Port of Thread.Output_Ports loop
               Put_Line (Output, " |_ Output port remote thread : "
                         & To_String (Out_Port.Remote_Thread));
               Put_Line (Output, " |_ Output port remote PI : "
                         & To_String (Out_Port.Remote_PI));
            end loop;
         end loop;
      end Dump_Partition;
   begin
      for Node of CV.Nodes loop
         for Partition of Node.Partitions loop
            Dump_Partition (Partition);
Maxime Perrotin's avatar
Maxime Perrotin committed
75
         end loop;
76
77
78
      end loop;
   end Debug_Dump;

79
   --  This function translates a protected block into a template
80
   function Prepare_Template (B : Protected_Block) return Block_As_Template is
81
      Calling_Threads : Tag;
82
      Result          : Block_As_Template;
83
84
85
86
87
   begin
      for Thread of B.Calling_Threads loop
         Calling_Threads := Calling_Threads & Thread;
      end loop;

88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
      for PI of B.Provided loop
         declare
            Basic : constant Translate_Set := PI.PI.To_Template
              & Assoc ("Protected_Block_Name", To_String (PI.Name))
              & Assoc ("Caller_Is_Local", PI.Local_Caller);
         begin
            Result.Provided.Append (Basic);
         end;
      end loop;

      for RI of B.Required loop
         Result.Required.Append (RI.To_Template);
      end loop;

      Result.Header := +Assoc  ("Name",            To_String (B.Name))
103
                       & Assoc ("Language",        B.Language)
104
105
106
107
                       & Assoc ("Calling_Threads", Calling_Threads)
                       & Assoc ("Node_Name",       To_String (B.Node.Value_Or
                         (Taste_Node'(Name => US (""), others => <>)).Name));
      return Result;
108
   end Prepare_Template;
109
110

   --  This function translates a thread definition into a template
Maxime Perrotin's avatar
Maxime Perrotin committed
111
   function To_Template (T : AADL_Thread) return Translate_Set is
112
      Remote_Thread    : Vector_Tag;
Maxime Perrotin's avatar
Maxime Perrotin committed
113
      RI_Port_Name     : Vector_Tag;  --  Name of the local RI (= port name)
114
115
116
      Remote_PI        : Vector_Tag;  --  Name of the remote PI
      Remote_PI_Sort   : Vector_Tag;  --  ASN.1 type of the parameter
      Remote_PI_Module : Vector_Tag;  --  ASN.1 module containing the type
117
118
   begin
      for Out_Port of T.Output_Ports loop
Maxime Perrotin's avatar
Maxime Perrotin committed
119
         RI_Port_Name  := RI_Port_Name & Out_Port.Name;
120
121
         Remote_Thread := Remote_Thread & To_String (Out_Port.Remote_Thread);
         Remote_PI     := Remote_PI     & To_String (Out_Port.Remote_PI);
122
123
124
125
126
127
128
129
130
131
         --  Set the Asn.1 module and type of the optional RI parameter
         if Out_Port.RI.Params.Length > 0 then
            Remote_PI_Sort := Remote_PI_Sort
              & Out_Port.RI.Params.First_Element.Sort;
            Remote_PI_Module := Remote_PI_Module
              & Out_Port.RI.Params.First_Element.ASN1_Module;
         else
            Remote_PI_Sort   := Remote_PI_Sort   & "";
            Remote_PI_Module := Remote_PI_Module & "";
         end if;
132
133
134
      end loop;

      return Result : constant Translate_Set :=
135
136
137
138
139
140
141
142
        T.PI.To_Template   --  Template of the PI used to create the thread
        & Assoc ("Thread_Name",       To_String (T.Name))
        & Assoc ("Entry_Port_Name",   To_String (T.Entry_Port_Name))
        & Assoc ("RCM",               To_String (T.RCM))
        & Assoc ("Pro_Block_Name",    To_String (T.Protected_Block_Name))
        & Assoc ("Node_Name",         To_String (T.Node.Value_Or
          (Taste_Node'(Name => US (""), others => <>)).Name))
        & Assoc ("Remote_Threads",    Remote_Thread)
Maxime Perrotin's avatar
Maxime Perrotin committed
143
        & Assoc ("RI_Port_Names",     RI_Port_Name)
144
145
146
        & Assoc ("Remote_PIs",        Remote_PI)
        & Assoc ("Remote_PI_Sorts",   Remote_PI_Sort)
        & Assoc ("Remote_PI_Modules", Remote_PI_Module);
Maxime Perrotin's avatar
Maxime Perrotin committed
147
   end To_Template;
148

Maxime Perrotin's avatar
Maxime Perrotin committed
149
   --  Generate the code by iterating over template folders
150
   procedure Generate_Code (CV : Taste_Concurrency_View)
151
   is
Maxime Perrotin's avatar
Maxime Perrotin committed
152
      Prefix   : constant String := CV.Base_Template_Path.Element
Maxime Perrotin's avatar
Maxime Perrotin committed
153
154
155
156
157
158
        & "templates/concurrency_view";
      --  To iterate over template folders
      ST       : Search_Type;
      Current  : Directory_Entry_Type;
      Filter   : constant Filter_Type := (Directory => True,
                                          others    => False);
159
160
      Output_File      : File_Type;

161
162
      CV_Out_Dir  : constant String  :=
        CV.Base_Output_Path.Element & "/concurrency_view/";
163
164
165
166
167
168

      --  Tags that are built over the whole system
      --  and cleant up between each template folder:
      Threads          : Unbounded_String;
      All_Thread_Names : Tag;  --  Complete list of threads
      All_Target_Names : Tag;  --  List of all targets used (AADL packages)
169
   begin
Maxime Perrotin's avatar
Maxime Perrotin committed
170
171
172
173
174
175
176
177
178
179
180
181
182
      Start_Search (Search    => ST,
                    Pattern   => "",
                    Directory => Prefix,
                    Filter    => Filter);

      if not More_Entries (ST) then
         --  On Unix, this will never happen because "." and ".." are part
         --  of the search result. We'll only get an IO Error if the
         --  concurrency_view folder itself does not exist
         raise Concurrency_View_Error with
           "No folders with templates for concurrency view";
      end if;

183
      --  Iterate over the folders containing template files
Maxime Perrotin's avatar
Maxime Perrotin committed
184
      while More_Entries (ST) loop
185
186
187
188
189
         --  Clean-up system-wise tags before the next template folder:
         Threads := US ("");
         Clear (All_Thread_Names);
         Clear (All_Target_Names);

Maxime Perrotin's avatar
Maxime Perrotin committed
190
191
192
193
194
195
196
         Get_Next_Entry (ST, Current);

         --  Ignore Unix special directories
         if Simple_Name (Current) = "." or Simple_Name (Current) = ".." then
            goto continue;
         end if;

Maxime Perrotin's avatar
Maxime Perrotin committed
197
         declare
Maxime Perrotin's avatar
Maxime Perrotin committed
198
199
            Path  : constant String  := Full_Name (Current);

200
201
            function Generate_Partition (Node_Name      : String;
                                         Partition_Name : String)
Maxime Perrotin's avatar
Maxime Perrotin committed
202
                                         return String
Maxime Perrotin's avatar
Maxime Perrotin committed
203
            is
Maxime Perrotin's avatar
Maxime Perrotin committed
204
205
               Partition       : constant CV_Partition :=
                 CV.Nodes (Node_Name).Partitions (Partition_Name);
206
               Thread_Names    : Tag;
207
208
               Block_Names     : Vector_Tag;
               Block_Languages : Vector_Tag;
Maxime Perrotin's avatar
Maxime Perrotin committed
209
               Blocks          : Unbounded_String;
Maxime Perrotin's avatar
Maxime Perrotin committed
210
               Partition_Assoc : Translate_Set;
211
212
213
214
215
               --  Connections between threads:
               Thread_Src_Name : Vector_Tag;
               Thread_Src_Port : Vector_Tag;
               Thread_Dst_Name : Vector_Tag;
               Thread_Dst_Port : Vector_Tag;
216
217
218
219
220
221
222
223
224
225
               --  Optionally generate partition code in separate files
               --  (if filepart.tmplt is present and contains a filename)
               File_Id         : constant String := Path & "/filepart.tmplt";
               Part_Check      : constant Boolean := Exists (File_Id);
               Part_Tag        : constant Translate_Set :=
                 +Assoc ("Partition_Name", Partition_Name);
               Part_File_Name  : constant String :=
                 (if Part_Check then Strip_String (Parse (File_Id, Part_Tag))
                  else "");
               Part_Content    : Unbounded_String;
Maxime Perrotin's avatar
Maxime Perrotin committed
226
            begin
227
228
229
               for T of Partition.Threads loop
                  declare
                     --  Render each thread
230
                     Name         : constant String := To_String (T.Name);
231
                     Thread_Assoc : constant Translate_Set := T.To_Template;
232
                     Result       : constant String :=
233
                       (Parse (Path & "/thread.tmplt", Thread_Assoc));
234
235
236
237
238
239
240
241
242
243
244
245
246

                     --  Optionally generate thread code in separate files
                     --  (if filethread.tmplt present and contains a filename)
                     Thread_File_Id   : constant String :=
                       Path & "/filethread.tmplt";
                     Thread_Check     : constant Boolean :=
                       Exists (Thread_File_Id);
                     Thread_Tag       : constant Translate_Set :=
                       +Assoc ("Thread_Name", Name);
                     Thread_File_Name : constant String :=
                       (if Thread_Check
                        then Strip_String (Parse (Thread_File_Id, Thread_Tag))
                        else "");
247
                  begin
248
249
                     Threads      := Threads & Newline & Result;
                     Thread_Names := Thread_Names & Name;
250
                     All_Thread_Names := All_Thread_Names & Name;
251
252
253
254
255
256
257
258
259
                     for P of T.Output_Ports loop
                        Thread_Src_Name := Thread_Src_Name & Name;
                        Thread_Src_Port := Thread_Src_Port
                          & To_String (P.Name);
                        Thread_Dst_Name := Thread_Dst_Name
                          & To_String (P.Remote_Thread);
                        Thread_Dst_Port := Thread_Dst_Port
                          & To_String (P.Remote_PI);
                     end loop;
260
261
262
263
264
265
266
267
268
269
270
271
                     --  Save the content of the thread in a file
                     --  (if required at template folder level)
                     if Thread_File_Name /= "" then
                        Create_Path (CV_Out_Dir & Node_Name);
                        Create (File => Output_File,
                                Mode => Out_File,
                                Name =>
                                  CV_Out_Dir & Node_Name
                                & "/" & Thread_File_Name);
                        Put_Line (Output_File, Result);
                        Close (Output_File);
                     end if;
272
                  end;
Maxime Perrotin's avatar
Maxime Perrotin committed
273
               end loop;
274

275
276
               for B of Partition.Blocks loop
                  declare
277
                     Block_Name  : constant String := To_String (B.Name);
278
279
                     Tmpl        : constant Block_As_Template :=
                       B.Prepare_Template;
280
                     Block_Assoc : Translate_Set := Tmpl.Header;
281
282
                     PI_Tag      : Unbounded_String;
                     RI_Tag      : Unbounded_String;
283
284
285
286
287
288
289
290
291
292
293
294
295
296
                     Result      : Unbounded_String;

                     --  Optionally generate block code in separate files
                     --  (if fileblock.tmplt present and contains a filename)
                     Block_File_Id   : constant String :=
                       Path & "/fileblock.tmplt";
                     Block_Check     : constant Boolean :=
                       Exists (Block_File_Id);
                     Block_Tag       : constant Translate_Set :=
                       +Assoc ("Block_Name", B.Name);
                     Block_File_Name : constant String :=
                       (if Block_Check
                        then Strip_String (Parse (Block_File_Id, Block_Tag))
                        else "");
297
                  begin
298
299
300
                     Block_Names     := Block_Names & Block_Name;
                     Block_Languages := Block_Languages & B.Language;

301
                     for PI_Assoc of Tmpl.Provided loop
Maxime Perrotin's avatar
Maxime Perrotin committed
302
                        PI_Tag := PI_Tag & Newline
303
304
305
                          & String'(Parse (Path & "/pi.tmplt", PI_Assoc));
                     end loop;
                     for RI_Assoc of Tmpl.Required loop
Maxime Perrotin's avatar
Maxime Perrotin committed
306
                        RI_Tag := RI_Tag & Newline
307
308
309
310
311
312
                          & String'(Parse (Path & "/ri.tmplt", RI_Assoc));
                     end loop;
                     Block_Assoc := Block_Assoc
                       & Assoc ("Provided", PI_Tag)
                       & Assoc ("Required", RI_Tag);

313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
                     Result := Parse (Path & "/block.tmplt", Block_Assoc);

                     Blocks := Blocks & Newline & To_String (Result);

                     --  Save the content of the block in a file
                     --  (if required at template folder level)
                     if Block_File_Name /= "" then
                        Create_Path (CV_Out_Dir & Node_Name);
                        Create (File => Output_File,
                                Mode => Out_File,
                                Name => CV_Out_Dir & Node_Name
                                        & "/" & Block_File_Name);
                        Put_Line (Output_File, To_String (Result));
                        Close (Output_File);
                     end if;
328
                  end;
Maxime Perrotin's avatar
Maxime Perrotin committed
329
               end loop;
330
331
332
               --  Association includes Name, Coverage, CPU Info, etc.
               --  (see taste-deployment_view.ads for the complete list)
               Partition_Assoc := Partition.Deployment_Partition.To_Template
333
334
335
336
                 & Assoc ("Threads",         Threads)
                 & Assoc ("Thread_Names",    Thread_Names)
                 & Assoc ("Node_Name",       Node_Name)
                 & Assoc ("Blocks",          Blocks)
337
                 & Assoc ("Block_Names",     Block_Names)
338
                 & Assoc ("Block_Languages", Block_Languages)
339
340
341
342
                 & Assoc ("Thread_Src_Name", Thread_Src_Name)
                 & Assoc ("Thread_Src_Port", Thread_Src_Port)
                 & Assoc ("Thread_Dst_Name", Thread_Dst_Name)
                 & Assoc ("Thread_Dst_Port", Thread_Dst_Port);
343

344
345
346
               All_Target_Names := All_Target_Names
                 & String'(Get (Get (Partition_Assoc, "Package_Name")));

347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
               Part_Content :=
                 Parse (Path & "/partition.tmplt", Partition_Assoc);

               --  Save the content of the partition in a file
               --  (if required at template folder level)
               if Part_File_Name /= "" then
                  Create_Path (CV_Out_Dir & Node_Name);
                  Create (File => Output_File,
                          Mode => Out_File,
                          Name =>
                            CV_Out_Dir & Node_Name & "/" & Part_File_Name);
                  Put_Line (Output_File, To_String (Part_Content));
                  Close (Output_File);
               end if;

               return To_String (Part_Content);
Maxime Perrotin's avatar
Maxime Perrotin committed
363
            end Generate_Partition;
Maxime Perrotin's avatar
Maxime Perrotin committed
364

365
366
            --  Generate the code for one node
            function Generate_Node (Node_Name : String) return String is
367
368
369
               Partitions      : Unbounded_String;
               Partition_Names : Tag;
               Node_Assoc      : Translate_Set;
370
            begin
Maxime Perrotin's avatar
Maxime Perrotin committed
371
               for Partition in CV.Nodes (Node_Name).Partitions.Iterate loop
372
373
                  Partition_Names := Partition_Names
                    & CV_Partitions.Key (Partition);
374
375
376
377
                  Partitions := Partitions & Newline
                    & Generate_Partition
                    (Partition_Name => CV_Partitions.Key (Partition),
                     Node_Name      => Node_Name);
Maxime Perrotin's avatar
Maxime Perrotin committed
378
               end loop;
Maxime Perrotin's avatar
Maxime Perrotin committed
379
               Node_Assoc := +Assoc ("Partitions", Partitions)
380
381
382
383
384
385
386
387
388
389
                 & Assoc ("Partition_Names", Partition_Names)
                 & Assoc ("Node_Name", Node_Name)
                 & Assoc ("CPU_Name",
                         CV.Nodes (Node_Name).Deployment_Node.CPU_Name)
                 & Assoc ("CPU_Platform",
                         CV.Nodes (Node_Name).Deployment_Node.CPU_Platform'Img)
                 & Assoc ("CPU_Classifier",
                         CV.Nodes (Node_Name).Deployment_Node.CPU_Classifier)
                 & Assoc ("Ada_Runtime",
                         CV.Nodes (Node_Name).Deployment_Node.Ada_Runtime);
390
391
               return Parse (Path & "/node.tmplt", Node_Assoc);
            end Generate_Node;
Maxime Perrotin's avatar
Maxime Perrotin committed
392

393
394
395
396
397
            Nodes           : Unbounded_String;
            Tmpl_File       : constant String  := Path & "/filesys.tmplt";
            Tmpl_Sys        : constant String  := Path & "/system.tmplt";
            Valid_Dir       : constant Boolean := Exists (Tmpl_File);
            File_Sys        : constant String  :=
Maxime Perrotin's avatar
Maxime Perrotin committed
398
              (if Valid_Dir then Strip_String (Parse (Tmpl_File)) else "");
399
400
401
402
403
            Trig_Sys        : constant Boolean := Exists (Tmpl_Sys);
            Set_Sys         : Translate_Set;
            Node_Names      : Vector_Tag;  --  List of nodes
            Node_CPU        : Vector_Tag;  --  Corresponding CPU name
            Node_CPU_Cls    : Vector_Tag;  --  Corresponding CPU classifier
404
405
406
            Partition_Names : Vector_Tag;  --  List of processes
            Partition_Node  : Vector_Tag;  --  Corresponding node name
            Partition_CPU   : Vector_Tag;  --  Corresponding CPU name
407
408
409
410
         begin
            for Node in CV.Nodes.Iterate loop
               declare
                  Node_Name    : constant String := CV_Nodes.Key (Node);
Maxime Perrotin's avatar
Maxime Perrotin committed
411
                  Output_Dir   : constant String := CV_Out_Dir & Node_Name;
412
413
414
415
416
417
418
419
420
421
422
423
                  Do_It        : constant Boolean :=
                    Exists (Path & "/filenode.tmplt");
                  Filename_Set : constant Translate_Set :=
                    +Assoc ("Node_Name", Node_Name);
                  --  Get output file name from template
                  File_Name    : constant String :=
                    (if Do_It then
                        Strip_String
                       (Parse (Path & "/filenode.tmplt", Filename_Set))
                     else "");
                  --  Check if file already exists
                  Present      : constant Boolean :=
424
425
                    (File_Name /= ""
                     and then Exists (Output_Dir & "/" & File_Name));
426
427
428
429
430
431
432
433
434
435
436
437
                  Trig_Tmpl    : constant Translate_Set :=
                    +Assoc ("Filename_Is_Present", Present);
                  Trigger      : constant Boolean :=
                    (Node_Name /= "interfaceview"
                     and then Exists (Path & "/trigger.tmplt") and then
                     Strip_String
                       (Parse (Path & "/trigger.tmplt", Trig_Tmpl)) = "TRUE");
                  Node_Content : constant String :=
                    (if Trigger then Generate_Node (Node_Name)
                     else "");
               begin
                  if Trigger then
438
439
440

                     --  Associate node name, CPU name and CPU classifier
                     --  (this is needed for AADL backends)
Maxime Perrotin's avatar
Maxime Perrotin committed
441
                     Node_Names := Node_Names & Node_Name;
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
                     Node_CPU := Node_CPU
                       & CV.Nodes (Node_Name).Deployment_Node.CPU_Name;
                     Node_CPU_Cls := Node_CPU_Cls
                       & CV.Nodes (Node_Name).Deployment_Node.CPU_Classifier;

                     --  Associate partition name, corresponding node and CPU
                     --  for AADL backends
                     for Partition in CV.Nodes (Node_Name).Partitions.Iterate
                     loop
                        Partition_Names := Partition_Names
                          & CV_Partitions.Key (Partition);
                        Partition_CPU := Partition_CPU
                          & CV_Partitions.Element (Partition)
                          .Deployment_Partition.CPU_Name;
                        Partition_Node := Partition_Node & Node_Name;
                     end loop;

                     Nodes := Nodes & Newline & Node_Content;
460
461
462
463
464
465
466
467
468
469
470
                     if File_Name /= "" then
                        Create_Path (Output_Dir);
                        Create (File => Output_File,
                                Mode => Out_File,
                                Name => Output_Dir & "/" & File_Name);
                        Put_Line (Output_File, Node_Content);
                        Close (Output_File);
                     end if;
                  end if;
               end;
            end loop;
Maxime Perrotin's avatar
Maxime Perrotin committed
471
            if Trig_Sys and File_Sys /= "" and Nodes /= "" then
Maxime Perrotin's avatar
Maxime Perrotin committed
472
473
               Set_Sys := CV.Configuration.To_Template
                 & Assoc ("Nodes",       Nodes)
474
475
476
477
478
479
                 & Assoc ("Node_Names",          Node_Names)
                 & Assoc ("Node_CPU",            Node_CPU)
                 & Assoc ("Node_CPU_Classifier", Node_CPU_Cls)
                 & Assoc ("Partition_Names",     Partition_Names)
                 & Assoc ("Partition_Node",      Partition_Node)
                 & Assoc ("Partition_CPU",       Partition_CPU)
480
481
482
                 & Assoc ("Threads",             Threads)
                 & Assoc ("Thread_Names",        All_Thread_Names)
                 & Assoc ("Target_Packages",     All_Target_Names);
Maxime Perrotin's avatar
Maxime Perrotin committed
483
484
485
486
487
488
489
               Create_Path (CV_Out_Dir);
               Create (File => Output_File,
                       Mode => Out_File,
                       Name => CV_Out_Dir & File_Sys);
               Put_Line (Output_File, Parse (Tmpl_Sys, Set_Sys));
               Close (Output_File);
            end if;
Maxime Perrotin's avatar
Maxime Perrotin committed
490
         end;
Maxime Perrotin's avatar
Maxime Perrotin committed
491
492
         <<continue>>
      end loop;
Maxime Perrotin's avatar
Maxime Perrotin committed
493
      End_Search (ST);
494
   end Generate_Code;
Maxime Perrotin's avatar
Maxime Perrotin committed
495
496
497

   procedure Generate_CV (CV : Taste_Concurrency_View) is
   begin
498
499
500
501
      --  In this first iteration Nodes are generated in standalone files,
      --  and they include their processes. It would be useful to be able
      --  to decide if processes could also have their own files, since
      --  in the future they may be more than one process per node (for TSP).
502
      CV.Generate_Code;
Maxime Perrotin's avatar
Maxime Perrotin committed
503
504
505
506
507
508
   exception
      when Error : Concurrency_View_Error | Ada.IO_Exceptions.Name_Error =>
         Put_Error ("Concurrency View : "
                    & Ada.Exceptions.Exception_Message (Error));
         raise Quit_Taste;
   end Generate_CV;
Maxime Perrotin's avatar
Maxime Perrotin committed
509

510
end TASTE.Concurrency_View;