po_hi_transport.c 16.3 KB
Newer Older
1
2
3
4
5
/*
 * This is a part of PolyORB-HI-C distribution, a minimal
 * middleware written for generated code from AADL models.
 * You should use it with the Ocarina toolsuite.
 *
yoogx's avatar
yoogx committed
6
 * For more informations, please visit http://taste.tuxfamily.org/wiki
7
 *
8
 * Copyright (C) 2007-2009 Telecom ParisTech, 2010-2018 ESA & ISAE.
9
10
 */

11
#include<stddef.h>
12
#include<assert.h>
13

14
15
16
17
18
19
20
#include <po_hi_config.h>
#include <po_hi_types.h>
#include <po_hi_debug.h>
#include <po_hi_transport.h>
#include <po_hi_giop.h>
#include <po_hi_messages.h>
#include <po_hi_returns.h>
julien.delange's avatar
julien.delange committed
21
#include <po_hi_gqueue.h>
22
23

#include <deployment.h>
julien.delange's avatar
julien.delange committed
24
25
#include <marshallers.h>
#include <types.h>
26
27
28
#include <activity.h>
#include <request.h>

Antonia Francis's avatar
Antonia Francis committed
29
30
31
32
#if defined (MONITORING)
#include <trace_manager.h>
#endif

33
34
35
36
37
/*
 * The following arrays are declared in the generated header
 * deployment.h.
 */

jdelange's avatar
jdelange committed
38
39
40
41
42
43
44
45
extern __po_hi_node_t            __po_hi_entity_table[__PO_HI_NB_ENTITIES];
extern __po_hi_entity_t          __po_hi_port_global_to_entity[__PO_HI_NB_PORTS];
extern __po_hi_local_port_t      __po_hi_port_global_to_local[__PO_HI_NB_PORTS];
extern __po_hi_request_t*        __po_hi_gqueues_most_recent_values[__PO_HI_NB_TASKS];
extern char*                     __po_hi_port_global_model_names[__PO_HI_NB_PORTS];
extern char*                     __po_hi_port_global_names[__PO_HI_NB_PORTS];
extern __po_hi_uint8_t           __po_hi_deployment_endiannesses[__PO_HI_NB_NODES];
extern __po_hi_protocol_conf_t   __po_hi_protocols_configuration[__PO_HI_NB_PROTOCOLS];
46
47

#if __PO_HI_NB_DEVICES > 0
jdelange's avatar
jdelange committed
48
49
50
51
52
53
54
__po_hi_transport_sending_func            __po_hi_transport_devices_sending_funcs[__PO_HI_NB_DEVICES];
extern __po_hi_port_t                     __po_hi_devices_to_nodes[__PO_HI_NB_DEVICES];
extern __po_hi_device_id                  __po_hi_port_to_device[__PO_HI_NB_PORTS];
extern char*                              __po_hi_devices_naming[__PO_HI_NB_DEVICES];
extern __po_hi_uint32_t*                  __po_hi_devices_configuration_values[__PO_HI_NB_DEVICES];
extern __po_hi_uint32_t                   __po_hi_devices_nb_accessed_buses[__PO_HI_NB_DEVICES];
extern __po_hi_bus_id*                    __po_hi_devices_accessed_buses[__PO_HI_NB_DEVICES];
55
#endif
56

57
58
59
60
#if __PO_HI_NB_PROTOCOLS > 0
extern __po_hi_protocol_t        __po_hi_ports_protocols[__PO_HI_NB_PORTS][__PO_HI_NB_PORTS];
#endif

yoogx's avatar
yoogx committed
61
62
63
#if defined(AIR_HYPERVISOR)
#include <air.h>
#include <a653.h>
64
65
66
67

#include <deployment.h>
#include <po_hi_types.h>
#include <po_hi_transport.h>
yoogx's avatar
yoogx committed
68

yoogx's avatar
yoogx committed
69
70
long int  __po_hi_air_port[__PO_HI_NB_PORTS];
/* Store either SAMPLING_PORT_ID_TYPE or QUEUING_PORT_ID_TYPE */
yoogx's avatar
yoogx committed
71
72
73
#endif

#ifdef XM3_RTEMS_MODE
74
#include <xm.h>
yoogx's avatar
yoogx committed
75

yoogx's avatar
yoogx committed
76
77
78
#include <deployment.h>
#include <po_hi_types.h>
#include <po_hi_transport.h>
79

yoogx's avatar
yoogx committed
80
81
int      __po_hi_xtratum_port[__PO_HI_NB_PORTS];
#endif
82

83

jdelange's avatar
jdelange committed
84
int __po_hi_transport_send (__po_hi_task_id id, __po_hi_port_t port)
85
{
86
   
87
88
89
90
   __po_hi_request_t*    request;
   __po_hi_uint8_t       ndest;
   __po_hi_uint8_t       i;
   __po_hi_local_port_t  local_port;
yoogx's avatar
yoogx committed
91
   __po_hi_port_t        destination_port;
92
   __po_hi_local_port_t  destination_port_local;
93
   __po_hi_entity_t      destination_entity;
94

95
   local_port  = __po_hi_get_local_port_from_global_port (port);
96
   request     = __po_hi_gqueue_get_most_recent_value (id, local_port);
97
98
99

   if (request->port == -1)
   {
100
      __PO_HI_DEBUG_DEBUG ("Send output task %d, global port %d : no value to send\n", id, port);
101
      return __PO_HI_SUCCESS;
102
   }
julien.delange's avatar
julien.delange committed
103

104
   ndest          = __po_hi_gqueue_get_destinations_number (id, local_port);
105
   assert(ndest);
106
   __PO_HI_DEBUG_DEBUG ("Send value, emitter task %d, emitter port %d, emitter port local %d, emitter entity %d, destination ports list:\n", id,  port, local_port, __po_hi_port_global_to_entity[port]);
107

julien.delange's avatar
julien.delange committed
108
#if __PO_HI_DEBUG_LEVEL >= __PO_HI_DEBUG_LEVEL_INFO
109
   __DEBUGMSG ("Packet to send: |");
110
111
112
113
114
115
116
117
   {
         int s;
         int i;
         unsigned int* tmp;
         tmp = (unsigned int*) &request->vars;
         s = sizeof (request->vars);
         for (i = 0 ; i < s ; i+=4)
         {
jdelange's avatar
jdelange committed
118
            __DEBUGMSG("%x", *tmp);
119
120
121
122
123
124
            tmp++;
            fflush (stdout);
         }
   }
   __DEBUGMSG ("|\n");
#endif
125
   for (i=0 ; i < __po_hi_gqueue_get_destinations_number (id, local_port) ; i++)
126
   {
127
      destination_port     = __po_hi_gqueue_get_destination (id, local_port, i);
128
      destination_port_local  = __po_hi_get_local_port_from_global_port (destination_port);
129
      destination_entity   = __po_hi_get_entity_from_global_port (destination_port);
130
      assert(destination_entity != -1);
131
132
133
134
135
136
      __PO_HI_DEBUG_DEBUG ("Destination number %d, global port \t%d, local port %d, (entity=%d)", i, destination_port, destination_port_local, destination_entity);
      if ((__po_hi_gqueue_used_size(id, destination_port_local) == __po_hi_gqueue_get_port_size(id, destination_port_local)) && (__po_hi_gqueue_get_port_size(id, destination_port_local) != __PO_HI_GQUEUE_FIFO_INDATA)){
        /* The gqueue on the destination port is full, error message transmitted */
        __PO_HI_DEBUG_CRITICAL("[TRANSPORT] QUEUE FULL ON THE DESTINATION PORT, NOT TRANSMITTED, task-id=%d, port=%d", id, destination_port_local);
        return __PO_HI_ERROR_QUEUE_FULL;
      } 
137

138
      request->port = destination_port;
139

140
      if (__po_hi_transport_get_node_from_entity (__po_hi_get_entity_from_global_port (port)) ==
141
          __po_hi_transport_get_node_from_entity (__po_hi_get_entity_from_global_port (destination_port)))
142
      {
143
144
145
#if __PO_HI_NB_DEVICES > 0
        /* If the application defines devices for communication, and
           the port uses one, forces remote delivery */
146
147
148
149
        if (__po_hi_port_to_device[port] != -1) {
            __PO_HI_DEBUG_DEBUG (" [deliver remotely]\n");
            __po_hi_transport_call_sending_func_by_port (id, port);
        } else {
julien.delange's avatar
julien.delange committed
150
            __PO_HI_DEBUG_DEBUG (" [deliver locally]\n");
151
            __po_hi_main_deliver (request);
152
        }
153
154
155
156
157
#else
        __PO_HI_DEBUG_DEBUG (" [deliver locally]\n");
        __po_hi_main_deliver (request);
#endif

158
      }
yoogx's avatar
yoogx committed
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173

#ifdef XM3_RTEMS_MODE /* for XTratuM */
      else {
        __po_hi_port_kind_t pkind = __po_hi_transport_get_port_kind (port);
        int ret = -1;
        if (pkind == __PO_HI_OUT_DATA_INTER_PROCESS) {
          ret = XM_write_sampling_message
            (__po_hi_xtratum_port[port],
             request, sizeof (__po_hi_request_t));
        }

        if (pkind == __PO_HI_OUT_EVENT_DATA_INTER_PROCESS) {
          ret = XM_send_queuing_message
            (__po_hi_xtratum_port[port],
             request, sizeof (__po_hi_request_t));
174
175
         }

yoogx's avatar
yoogx committed
176
177
178
179
180
181
182
183
         if (ret < 0) {
           __PO_HI_DEBUG_CRITICAL
             ("[GQUEUE] Error delivering using inter-partitions ports, %d\n",
              ret);
         } else {
           __PO_HI_DEBUG_DEBUG
             ("[GQUEUE] Data delivered using inter-partitions ports, %d\n",
              ret);
184
         }
yoogx's avatar
yoogx committed
185
      }
186

yoogx's avatar
yoogx committed
187
188
189
#elif defined (AIR_HYPERVISOR) /* for AIR */
      else {
        __po_hi_port_kind_t pkind = __po_hi_transport_get_port_kind (port);
yoogx's avatar
yoogx committed
190
191
        RETURN_CODE_TYPE ret;

yoogx's avatar
yoogx committed
192
193
        if (pkind == __PO_HI_OUT_DATA_INTER_PROCESS) {
          WRITE_SAMPLING_MESSAGE
yoogx's avatar
yoogx committed
194
            (__po_hi_air_port[port],
yoogx's avatar
yoogx committed
195
196
197
198
199
200
             request, sizeof (__po_hi_request_t),
             &ret);
        }

        if (pkind == __PO_HI_OUT_EVENT_DATA_INTER_PROCESS) {
          SEND_QUEUING_MESSAGE
yoogx's avatar
yoogx committed
201
            (__po_hi_air_port[port],
yoogx's avatar
yoogx committed
202
203
             request, sizeof (__po_hi_request_t),
             INFINITE_TIME_VALUE, &ret);
204
         }
yoogx's avatar
yoogx committed
205

yoogx's avatar
yoogx committed
206
         if (ret != NO_ERROR) {
yoogx's avatar
yoogx committed
207
208
209
210
211
212
213
           __PO_HI_DEBUG_CRITICAL
             ("[GQUEUE] Error delivering using inter-partitions ports, %d\n",
              ret);
         } else {
           __PO_HI_DEBUG_DEBUG
             ("[GQUEUE] Data delivered using inter-partitions ports, %d\n",
              ret);
214
215
         }
      }
yoogx's avatar
yoogx committed
216
217
218
219
220
221

#else
      else {
        __PO_HI_DEBUG_DEBUG (" [deliver remotely]\n");
        __po_hi_transport_call_sending_func_by_port (id, port);
      }
222
#endif
yoogx's avatar
yoogx committed
223
224

      /** The trace_managing is done for every step of the for loop */
Antonia Francis's avatar
Antonia Francis committed
225
#if defined (MONITORING)
yoogx's avatar
yoogx committed
226
227
228
      record_event
        (ANY, TRANSPORT_SEND, id, port, destination_port, local_port,
         __po_hi_get_local_port_from_global_port (destination_port), request);
Antonia Francis's avatar
Antonia Francis committed
229
#endif
230
   }
Antonia Francis's avatar
Antonia Francis committed
231

232
   request->port = __PO_HI_GQUEUE_INVALID_PORT;
julien.delange's avatar
julien.delange committed
233
234

#ifdef __PO_HI_DEBUG
julien.delange's avatar
julien.delange committed
235
   __PO_HI_DEBUG_DEBUG ("\n");
236
#endif
julien.delange's avatar
julien.delange committed
237

238
   return __PO_HI_SUCCESS;
julien.delange's avatar
julien.delange committed
239
240
}

241

242
__po_hi_node_t __po_hi_transport_get_node_from_entity (const __po_hi_entity_t entity)
julien.delange's avatar
julien.delange committed
243
{
244
   return __po_hi_entity_table[entity];
245
}
246

247
248
249
250
251
252
253
__po_hi_node_t __po_hi_transport_get_mynode (void)
{
   extern __po_hi_node_t __po_hi_mynode;
   return (__po_hi_mynode);
}


254
255
256
257
__po_hi_entity_t __po_hi_get_entity_from_global_port (const __po_hi_port_t port)
{
    return __po_hi_port_global_to_entity[port];
}
258

259
char* __po_hi_get_port_name (const __po_hi_port_t port)
260
261
262
263
264
{
      return (__po_hi_port_global_names[port]);
}


265
char* __po_hi_get_port_model_name (const __po_hi_port_t port)
266
267
268
269
{
      return (__po_hi_port_global_model_names[port]);
}

270
271
272
273
__po_hi_local_port_t __po_hi_get_local_port_from_global_port (const __po_hi_port_t global_port)
{
   return (__po_hi_port_global_to_local[global_port]);
}
274
275
276
277
278

__po_hi_uint8_t __po_hi_get_endianness (const __po_hi_node_t node)
{
   return __po_hi_deployment_endiannesses[node];
}
279

280
#if __PO_HI_NB_DEVICES > 0
jdelange's avatar
jdelange committed
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
int __po_hi_transport_call_sending_func_by_port (__po_hi_task_id task_id, __po_hi_port_t port)
{
   __po_hi_device_id device =__po_hi_get_device_from_port (port);

   __PO_HI_DEBUG_DEBUG ("[TRANSPORT] Calling function for device %d\n", device);
   if (device != invalid_device_id)
   {
      return __po_hi_transport_call_sending_func_by_device (device, task_id, port);
   }
   return __PO_HI_UNAVAILABLE;
}

int __po_hi_transport_call_sending_func_by_device (const __po_hi_device_id device, __po_hi_task_id task_id, __po_hi_port_t port)
{
   __po_hi_transport_sending_func send_func;
   send_func = __po_hi_transport_get_sending_func (device);

   if (send_func == NULL)
   {
      return __PO_HI_UNAVAILABLE;
   }
   return send_func (task_id, port);
}


__po_hi_transport_sending_func __po_hi_transport_get_sending_func (const __po_hi_device_id device)
{
   if (device > __PO_HI_NB_DEVICES)
   {
      return NULL;
   }

   return __po_hi_transport_devices_sending_funcs[device];
}

int __po_hi_transport_set_sending_func (const __po_hi_device_id device, const __po_hi_transport_sending_func func)
{
   if (device > __PO_HI_NB_DEVICES)
   {
      return __PO_HI_UNAVAILABLE;
   }

   __po_hi_transport_devices_sending_funcs[device] = func;
324
325

   return 0;
jdelange's avatar
jdelange committed
326
327
328
}


jdelange's avatar
jdelange committed
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
int __po_hi_transport_associate_port_bus (const __po_hi_port_t port, const __po_hi_bus_id bus)
{
   __po_hi_device_id current_device;
   __po_hi_node_t    current_node;
   __po_hi_bus_id*   tmp_buses;
   __po_hi_uint32_t  tmp_n_buses;
   __po_hi_uint32_t  tmp;
   __po_hi_node_t    tmp_node;
   __po_hi_device_id tmp_device;

   if (port > __PO_HI_NB_PORTS)
   {
      return 0;
   }

   current_device = __po_hi_get_device_from_port (port);

   if (current_device == invalid_device_id)
   {
      return 0;
   }

   current_node = __po_hi_transport_get_node_from_device (current_device);

   for (tmp_device=0 ; tmp_device < __PO_HI_NB_DEVICES ; tmp_device++)
   {
      if (tmp_device == current_device)
      {
         continue;
      }

      tmp_buses      = __po_hi_transport_get_accessed_buses (tmp_device);
      tmp_n_buses    = __po_hi_transport_get_n_accessed_buses (tmp_device);
      tmp_node       = __po_hi_transport_get_node_from_device (tmp_device);

      if (tmp_node != current_node)
      {
         continue;
      }

      for (tmp = 0 ; tmp < tmp_n_buses ; tmp++)
      {
         if (tmp_buses[tmp] == bus)
         {

            __po_hi_port_to_device[port] = tmp_device;
            return 1;
         }
      }
   }
   return 0;
}


jdelange's avatar
jdelange committed
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
int __po_hi_transport_share_bus (const __po_hi_device_id first, const __po_hi_device_id second)
{
   __po_hi_uint32_t i;
   __po_hi_uint32_t j;
   __po_hi_uint32_t first_n_buses;
   __po_hi_uint32_t second_n_buses;

   __po_hi_bus_id* first_buses;
   __po_hi_bus_id* second_buses;

   first_buses       = __po_hi_transport_get_accessed_buses (first);
   second_buses      = __po_hi_transport_get_accessed_buses (second);

   first_n_buses     = __po_hi_transport_get_n_accessed_buses (first);
   second_n_buses    = __po_hi_transport_get_n_accessed_buses (second);

   for (i = 0 ; i < first_n_buses ; i++)
   {
      for (j = 0 ; j < second_n_buses ; j++)
      {
         if (first_buses[i] == second_buses[j])
         {
            return 1;
         }
      }
   }
   return 0;
}


jdelange's avatar
jdelange committed
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
__po_hi_bus_id* __po_hi_transport_get_accessed_buses (const __po_hi_device_id device)
{
   if ((device < 0) || (device >= __PO_HI_NB_DEVICES))
   {
      return NULL;
   }
   return __po_hi_devices_accessed_buses[device];
}


uint32_t __po_hi_transport_get_n_accessed_buses (const __po_hi_device_id device)
{
   if ((device < 0) || (device >= __PO_HI_NB_DEVICES))
   {
      return 0;
   }
   return __po_hi_devices_nb_accessed_buses[device];

}

433
char* __po_hi_get_device_naming (const __po_hi_device_id dev)
434
{
435
      return __po_hi_devices_naming[dev];
436
437
438
439
440
441
}

__po_hi_device_id __po_hi_get_device_from_port (const __po_hi_port_t port)
{
      return __po_hi_port_to_device[port];
}
442

443
void* __po_hi_get_device_configuration (const __po_hi_device_id dev)
julien.delange's avatar
julien.delange committed
444
445
446
447
448
449
450
451
{
   if (dev > __PO_HI_NB_DEVICES)
   {
      return NULL;
   }
   return __po_hi_devices_configuration_values[dev];
}

jdelange's avatar
jdelange committed
452
453
454
455
__po_hi_node_t    __po_hi_transport_get_node_from_device (const __po_hi_device_id device)
{
   return (__po_hi_devices_to_nodes[device]);
}
jdelange's avatar
jdelange committed
456
457
458
#else
int __po_hi_transport_call_sending_func_by_port (__po_hi_task_id task_id, __po_hi_port_t port)
{
459
   __DEBUGMSG ("[TRANSPORT] task id %d port %d, nb protocols is less than or equal to zero\n", task_id,port);
jdelange's avatar
jdelange committed
460
461
462
   return __PO_HI_UNAVAILABLE;
}
#endif /* __PO_HI_NB_DEVICES > 0 */
463

464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525

char* __po_hi_transport_get_model_name (const __po_hi_port_t portno)
{
   extern char*                  __po_hi_port_global_model_names[__PO_HI_NB_PORTS];

   if (portno >= __PO_HI_NB_PORTS)
   {
      __DEBUGMSG ("[TRANSPORT] Try to get the name of a non-existing port\n");
      return NULL;
   }
   else
   {
      return __po_hi_port_global_model_names[portno];
   }
}


__po_hi_uint32_t __po_hi_transport_get_queue_size (const __po_hi_port_t portno)
{
   extern __po_hi_uint32_t __po_hi_port_global_queue_size[__PO_HI_NB_PORTS];

   if (portno >= __PO_HI_NB_PORTS)
   {
      __DEBUGMSG ("[TRANSPORT] Try to get the queue size of a non-existing port\n");
      return 1;
   }
   else
   {
      return __po_hi_port_global_queue_size[portno];
   }
}

__po_hi_uint32_t __po_hi_transport_get_data_size (const __po_hi_port_t portno)
{
   extern __po_hi_uint32_t __po_hi_port_global_data_size[__PO_HI_NB_PORTS];

   if (portno >= __PO_HI_NB_PORTS)
   {
      __DEBUGMSG ("[TRANSPORT] Try to get the data size of a non-existing port\n");
      return 1;
   }
   else
   {
      return __po_hi_port_global_data_size[portno];
   }
}

__po_hi_port_kind_t __po_hi_transport_get_port_kind (const __po_hi_port_t portno)
{
   extern __po_hi_port_kind_t    __po_hi_port_global_kind[__PO_HI_NB_PORTS];
   if (portno >= __PO_HI_NB_PORTS)
   {
      __DEBUGMSG ("[TRANSPORT] Try to get the type/kind of a non-existing port\n");
      return __PO_HI_INVALID_PORT_KIND;
   }
   else
   {
      return __po_hi_port_global_kind[portno];
   }

}

jdelange's avatar
jdelange committed
526
527
__po_hi_protocol_t __po_hi_transport_get_protocol (const __po_hi_port_t src, const __po_hi_port_t dst)
{
528
529
__po_hi_protocol_t protocol;

530
#if __PO_HI_NB_PROTOCOLS > 0
531
   protocol= (__po_hi_ports_protocols[src][dst]);
532
#else
533
534
   __DEBUGMSG ("[TRANSPORT] port SRC=%d DST=%d, nb protocols is less than or equal to zero\n", src,dst);
   protocol= invalid_protocol;
535
#endif
536
return protocol;
jdelange's avatar
jdelange committed
537
538
539
540
}

__po_hi_protocol_conf_t*    __po_hi_transport_get_protocol_configuration (const __po_hi_protocol_t p)
{
541

542
#if __PO_HI_NB_PROTOCOLS > 0
jdelange's avatar
jdelange committed
543
544
   if (p == invalid_protocol)
   {
545
        return NULL;
jdelange's avatar
jdelange committed
546
   }
547
   else
548
        return &(__po_hi_protocols_configuration[p]);
549
#else
550
   __DEBUGMSG ("[TRANSPORT] protocol %d, nb protocols is less than or equal to zero\n", p);
551
   return NULL;
552
#endif
553
}
jdelange's avatar
jdelange committed
554

yoogx's avatar
yoogx committed
555
#if defined(XM3_RTEMS_MODE)
556
557
558
559
560
561
562
563
564
565
void __po_hi_transport_xtratum_port_init (const __po_hi_port_t portno, int val)
{
   __po_hi_xtratum_port[portno] = val;
}

int __po_hi_transport_xtratum_get_port (const __po_hi_port_t portno)
{
   return __po_hi_xtratum_port[portno];
}
#endif
yoogx's avatar
yoogx committed
566
567
568
569
570
571
572
573
574
575
576
577

#if defined(AIR_HYPERVISOR)
void __po_hi_transport_air_port_init (const __po_hi_port_t portno, long int val)
{
   __po_hi_air_port[portno] = val;
}

long int __po_hi_transport_air_get_port (const __po_hi_port_t portno)
{
   return __po_hi_air_port[portno];
}
#endif