po_hi_transport.c 13.1 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.
 *
jhugues's avatar
jhugues committed
6
 * For more informations, please visit http://assert-project.net/taste
7
 *
jhugues's avatar
jhugues committed
8
 * Copyright (C) 2007-2009 Telecom ParisTech, 2010-2012 ESA & ISAE.
9
10
11
12
13
14
15
16
17
 */

#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
18
#include <po_hi_gqueue.h>
19
20

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

/*
 * The following arrays are declared in the generated header
 * deployment.h.
 */

jdelange's avatar
jdelange committed
31
32
33
34
35
36
37
38
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];
39
40

#if __PO_HI_NB_DEVICES > 0
jdelange's avatar
jdelange committed
41
42
43
44
45
46
47
48
__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_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];
49
#endif
50

51
52
53
54
#if __PO_HI_NB_PROTOCOLS > 0
extern __po_hi_protocol_t        __po_hi_ports_protocols[__PO_HI_NB_PORTS][__PO_HI_NB_PORTS];
#endif

55
56
57
58
59
60
61
62
63
64
#ifdef XM3_RTEMS_MODE

#include <deployment.h>
#include <po_hi_types.h>
#include <po_hi_transport.h>
#include <xm.h>
int                           __po_hi_xtratum_port[__PO_HI_NB_PORTS];
#endif


jdelange's avatar
jdelange committed
65
int __po_hi_transport_send (__po_hi_task_id id, __po_hi_port_t port)
66
{
67
68
69
70
71
   __po_hi_msg_t         msg;
   __po_hi_request_t*    request;
   __po_hi_uint8_t       ndest;
   __po_hi_uint8_t       i;
   __po_hi_local_port_t  local_port;
72
73
   __po_hi_port_t        destination_port; 
   __po_hi_entity_t      destination_entity;
74

75
   local_port  = __po_hi_get_local_port_from_global_port (port);
76
   request     = __po_hi_gqueue_get_most_recent_value (id, local_port);
77
78
79

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

84
   ndest          = __po_hi_gqueue_get_destinations_number (id, local_port);
julien.delange's avatar
julien.delange committed
85

julien.delange's avatar
julien.delange committed
86
   __PO_HI_DEBUG_DEBUG ("Send value, emitter task %d, emitter port %d, emitter entity %d, destination ports :\n", id,  port, __po_hi_port_global_to_entity[port]);
87

julien.delange's avatar
julien.delange committed
88
#if __PO_HI_DEBUG_LEVEL >= __PO_HI_DEBUG_LEVEL_INFO
89
90
91
92
93
94
95
96
97
   __DEBUGMSG ("SENT Value: |");
   {
         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
98
            __DEBUGMSG("%x", *tmp);
99
100
101
102
103
104
105
            tmp++;
            fflush (stdout);
         }
   }
   __DEBUGMSG ("|\n");
#endif

106
   for (i=0 ; i < __po_hi_gqueue_get_destinations_number (id, local_port) ; i++)
107
   {
108
109
      destination_port     = __po_hi_gqueue_get_destination (id, local_port, i);
      destination_entity   = __po_hi_get_entity_from_global_port (destination_port);
julien.delange's avatar
julien.delange committed
110
      __PO_HI_DEBUG_DEBUG ("\t%d (entity=%d)", destination_port, destination_entity);
julien.delange's avatar
julien.delange committed
111
      __po_hi_msg_reallocate (&msg);
112

113
      request->port = destination_port;
114

115
      if (__po_hi_transport_get_node_from_entity (__po_hi_get_entity_from_global_port (port)) ==
116
          __po_hi_transport_get_node_from_entity (__po_hi_get_entity_from_global_port (destination_port)))
117
      {
julien.delange's avatar
julien.delange committed
118
            __PO_HI_DEBUG_DEBUG (" [deliver locally]\n");
119
120
            __po_hi_main_deliver (request);
      }
jdelange's avatar
jdelange committed
121
122
123
124
125
126
127
#ifndef XM3_RTEMS_MODE
      else
      {
            __PO_HI_DEBUG_DEBUG (" [deliver remotely]\n");
            __po_hi_transport_call_sending_func_by_port (id, port);
      }
#else /* for XTratuM */
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
      else
      {
         __po_hi_port_kind_t pkind = __po_hi_transport_get_port_kind (port);
         int ret;
         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));
         }

         if (ret < 0)
         {
            __PO_HI_DEBUG_DEBUG ("[GQUEUE] Cannot deliver the data using inter-partitions ports, return=%d\n", ret);
         }
         else
         {
            __PO_HI_DEBUG_DEBUG ("[GQUEUE] Data delivered using inter-partitions ports, return=%d\n", ret);
         }
      }
#endif
153
154
   }
   request->port = __PO_HI_GQUEUE_INVALID_PORT;
julien.delange's avatar
julien.delange committed
155
156

#ifdef __PO_HI_DEBUG
julien.delange's avatar
julien.delange committed
157
   __PO_HI_DEBUG_DEBUG ("\n");
158
#endif
julien.delange's avatar
julien.delange committed
159

160
   return __PO_HI_SUCCESS;
julien.delange's avatar
julien.delange committed
161
162
}

163
__po_hi_node_t __po_hi_transport_get_node_from_entity (const __po_hi_entity_t entity)
julien.delange's avatar
julien.delange committed
164
{
165
   return __po_hi_entity_table[entity];
166
}
167

168
169
170
171
172
173
174
__po_hi_node_t __po_hi_transport_get_mynode (void)
{
   extern __po_hi_node_t __po_hi_mynode;
   return (__po_hi_mynode);
}


175
176
177
178
__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];
}
179

180
char* __po_hi_get_port_name (const __po_hi_port_t port)
181
182
183
184
185
{
      return (__po_hi_port_global_names[port]);
}


186
char* __po_hi_get_port_model_name (const __po_hi_port_t port)
187
188
189
190
{
      return (__po_hi_port_global_model_names[port]);
}

191
192
193
194
__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]);
}
195
196
197
198
199

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

201
#if __PO_HI_NB_DEVICES > 0
jdelange's avatar
jdelange committed
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
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;
}


jdelange's avatar
jdelange committed
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
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
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
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
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
__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];

}

352
char* __po_hi_get_device_naming (const __po_hi_device_id dev)
353
{
354
      return __po_hi_devices_naming[dev];
355
356
357
358
359
360
}

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

julien.delange's avatar
julien.delange committed
362
363
364
365
366
367
368
369
370
__po_hi_uint32_t* __po_hi_get_device_configuration (const __po_hi_device_id dev)
{
   if (dev > __PO_HI_NB_DEVICES)
   {
      return NULL;
   }
   return __po_hi_devices_configuration_values[dev];
}

jdelange's avatar
jdelange committed
371
372
373
374
__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
375
376
377
378
379
380
#else
int __po_hi_transport_call_sending_func_by_port (__po_hi_task_id task_id, __po_hi_port_t port)
{
   return __PO_HI_UNAVAILABLE;
}
#endif /* __PO_HI_NB_DEVICES > 0 */
381

382
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
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443

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
444
445
__po_hi_protocol_t __po_hi_transport_get_protocol (const __po_hi_port_t src, const __po_hi_port_t dst)
{
446
#if __PO_HI_NB_PROTOCOLS > 0
jdelange's avatar
jdelange committed
447
   return (__po_hi_ports_protocols[src][dst]);
448
449
450
451
#else
   return invalid_protocol;
#endif

jdelange's avatar
jdelange committed
452
453
454
455
}

__po_hi_protocol_conf_t*    __po_hi_transport_get_protocol_configuration (const __po_hi_protocol_t p)
{
456
#if __PO_HI_NB_PROTOCOLS > 0
jdelange's avatar
jdelange committed
457
458
459
460
461
   if (p == invalid_protocol)
   {
      return NULL;
   }
   return &(__po_hi_protocols_configuration[p]);
462
463
#else
   return NULL;
464
#endif
465
}
jdelange's avatar
jdelange committed
466

467
468
469
470
471
472
473
474
475
476
477
478
479
#ifdef XM3_RTEMS_MODE
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