source: rtems/cpukit/rtems/src/msgmp.c @ 453bb4b

5
Last change on this file since 453bb4b was 453bb4b, checked in by Sebastian Huber <sebastian.huber@…>, on 12/29/19 at 16:43:46

rtems: Fix MPCI initialization

Update #2408.

  • Property mode set to 100644
File size: 15.2 KB
Line 
1/**
2 * @file
3 *
4 * @brief Multiprocessing Support for the Message Queue Manager
5 * @ingroup ClassicMsgMP Message Queue MP Support
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-2008.
10 *  On-Line Applications Research Corporation (OAR).
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *  http://www.rtems.org/license/LICENSE.
15 */
16
17#if HAVE_CONFIG_H
18#include "config.h"
19#endif
20
21#include <rtems/rtems/messageimpl.h>
22#include <rtems/rtems/optionsimpl.h>
23#include <rtems/rtems/statusimpl.h>
24#include <rtems/score/coremsgimpl.h>
25#include <rtems/score/statesimpl.h>
26#include <rtems/score/threadimpl.h>
27#include <rtems/sysinit.h>
28
29RTEMS_STATIC_ASSERT(
30  MESSAGE_QUEUE_MP_PACKET_SIZE <= MP_PACKET_MINIMUM_PACKET_SIZE,
31  Message_queue_MP_Packet
32);
33
34static Message_queue_MP_Packet *_Message_queue_MP_Get_packet( void )
35{
36  return (Message_queue_MP_Packet *) _MPCI_Get_packet();
37}
38
39
40/*
41 *  _Message_queue_MP_Send_process_packet
42 *
43 */
44
45void _Message_queue_MP_Send_process_packet (
46  Message_queue_MP_Remote_operations  operation,
47  Objects_Id                          message_queue_id,
48  rtems_name                          name,
49  Objects_Id                          proxy_id
50)
51{
52  Message_queue_MP_Packet *the_packet;
53  uint32_t                 node;
54
55  switch ( operation ) {
56
57    case MESSAGE_QUEUE_MP_ANNOUNCE_CREATE:
58    case MESSAGE_QUEUE_MP_ANNOUNCE_DELETE:
59    case MESSAGE_QUEUE_MP_EXTRACT_PROXY:
60
61      the_packet                    = _Message_queue_MP_Get_packet();
62      the_packet->Prefix.the_class  = MP_PACKET_MESSAGE_QUEUE;
63      the_packet->Prefix.length     = MESSAGE_QUEUE_MP_PACKET_SIZE;
64      the_packet->Prefix.to_convert = MESSAGE_QUEUE_MP_PACKET_SIZE;
65      the_packet->operation         = operation;
66      the_packet->Prefix.id         = message_queue_id;
67      the_packet->name              = name;
68      the_packet->proxy_id          = proxy_id;
69
70      if ( operation == MESSAGE_QUEUE_MP_EXTRACT_PROXY )
71         node = _Objects_Get_node( message_queue_id );
72      else
73         node = MPCI_ALL_NODES;
74
75      _MPCI_Send_process_packet( node, &the_packet->Prefix );
76      break;
77
78    case MESSAGE_QUEUE_MP_RECEIVE_REQUEST:
79    case MESSAGE_QUEUE_MP_RECEIVE_RESPONSE:
80    case MESSAGE_QUEUE_MP_SEND_REQUEST:
81    case MESSAGE_QUEUE_MP_SEND_RESPONSE:
82    case MESSAGE_QUEUE_MP_URGENT_REQUEST:
83    case MESSAGE_QUEUE_MP_URGENT_RESPONSE:
84    case MESSAGE_QUEUE_MP_BROADCAST_REQUEST:
85    case MESSAGE_QUEUE_MP_BROADCAST_RESPONSE:
86    case MESSAGE_QUEUE_MP_FLUSH_REQUEST:
87    case MESSAGE_QUEUE_MP_FLUSH_RESPONSE:
88    case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_REQUEST:
89    case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_RESPONSE:
90      break;
91
92  }
93}
94
95/*
96 *  _Message_queue_MP_Send_request_packet
97 *
98 */
99
100static rtems_status_code _Message_queue_MP_Send_request_packet (
101  Objects_Id                          message_queue_id,
102  const void                         *buffer,
103  size_t                             *size_p,
104  rtems_option                        option_set,
105  rtems_interval                      timeout,
106  Message_queue_MP_Remote_operations  operation
107)
108{
109  Message_queue_MP_Packet *the_packet;
110  Status_Control           status;
111
112  if ( !_Message_queue_MP_Is_remote( message_queue_id ) ) {
113    return RTEMS_INVALID_ID;
114  }
115
116  switch ( operation ) {
117
118    case MESSAGE_QUEUE_MP_SEND_REQUEST:
119    case MESSAGE_QUEUE_MP_URGENT_REQUEST:
120    case MESSAGE_QUEUE_MP_BROADCAST_REQUEST:
121    case MESSAGE_QUEUE_MP_FLUSH_REQUEST:
122    case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_REQUEST:
123
124      the_packet                    = _Message_queue_MP_Get_packet();
125      the_packet->Prefix.the_class  = MP_PACKET_MESSAGE_QUEUE;
126      the_packet->Prefix.length     = MESSAGE_QUEUE_MP_PACKET_SIZE;
127      if ( size_p )
128        the_packet->Prefix.length     += *size_p;
129      the_packet->Prefix.to_convert = MESSAGE_QUEUE_MP_PACKET_SIZE;
130
131      /*
132       * make sure message is not too big for our MPCI driver
133       * We have to check it here instead of waiting for MPCI because
134       * we are about to slam in the payload
135       */
136
137      if (the_packet->Prefix.length > _MPCI_table->maximum_packet_size) {
138          return RTEMS_INVALID_SIZE;
139      }
140
141      if (! _Options_Is_no_wait(option_set))
142          the_packet->Prefix.timeout = timeout;
143
144      the_packet->operation  = operation;
145      the_packet->Prefix.id  = message_queue_id;
146      the_packet->option_set = option_set;
147
148      /*
149       * Copy the data into place if needed
150       */
151
152      if (buffer) {
153          the_packet->Buffer.size = *size_p;
154          _CORE_message_queue_Copy_buffer(
155            buffer,
156            the_packet->Buffer.buffer,
157            *size_p
158          );
159      }
160
161      status = _MPCI_Send_request_packet(
162        _Objects_Get_node(message_queue_id),
163        &the_packet->Prefix,
164        STATES_WAITING_FOR_MESSAGE
165      );
166      return _Status_Get( status );
167
168    case MESSAGE_QUEUE_MP_RECEIVE_REQUEST:
169
170      the_packet                    = _Message_queue_MP_Get_packet();
171      the_packet->Prefix.the_class  = MP_PACKET_MESSAGE_QUEUE;
172      the_packet->Prefix.length     = MESSAGE_QUEUE_MP_PACKET_SIZE;
173      the_packet->Prefix.to_convert = MESSAGE_QUEUE_MP_PACKET_SIZE;
174
175      if (! _Options_Is_no_wait(option_set))
176          the_packet->Prefix.timeout = timeout;
177
178      the_packet->operation  = MESSAGE_QUEUE_MP_RECEIVE_REQUEST;
179      the_packet->Prefix.id  = message_queue_id;
180      the_packet->option_set = option_set;
181      the_packet->size       = 0;        /* just in case of an error */
182
183      _Thread_Executing->Wait.return_argument_second.immutable_object = buffer;
184      _Thread_Executing->Wait.return_argument = size_p;
185
186      status = _MPCI_Send_request_packet(
187        _Objects_Get_node(message_queue_id),
188        &the_packet->Prefix,
189        STATES_WAITING_FOR_MESSAGE
190      );
191      return _Status_Get( status );
192
193    case MESSAGE_QUEUE_MP_ANNOUNCE_CREATE:
194    case MESSAGE_QUEUE_MP_ANNOUNCE_DELETE:
195    case MESSAGE_QUEUE_MP_EXTRACT_PROXY:
196    case MESSAGE_QUEUE_MP_RECEIVE_RESPONSE:
197    case MESSAGE_QUEUE_MP_SEND_RESPONSE:
198    case MESSAGE_QUEUE_MP_URGENT_RESPONSE:
199    case MESSAGE_QUEUE_MP_BROADCAST_RESPONSE:
200    case MESSAGE_QUEUE_MP_FLUSH_RESPONSE:
201    case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_RESPONSE:
202      break;
203  }
204
205  return RTEMS_SUCCESSFUL;
206}
207
208rtems_status_code _Message_queue_MP_Broadcast(
209  rtems_id    id,
210  const void *buffer,
211  size_t      size,
212  uint32_t   *count
213)
214{
215  _Thread_Get_executing()->Wait.return_argument = count;
216  return _Message_queue_MP_Send_request_packet(
217    id,
218    buffer,
219    &size,
220    0,
221    MPCI_DEFAULT_TIMEOUT,
222    MESSAGE_QUEUE_MP_BROADCAST_REQUEST
223  );
224}
225
226rtems_status_code _Message_queue_MP_Flush(
227  rtems_id  id,
228  uint32_t *count
229)
230{
231  _Thread_Get_executing()->Wait.return_argument = count;
232  return _Message_queue_MP_Send_request_packet(
233    id,
234    NULL,
235    NULL,
236    0,
237    MPCI_DEFAULT_TIMEOUT,
238    MESSAGE_QUEUE_MP_FLUSH_REQUEST
239  );
240}
241
242rtems_status_code _Message_queue_MP_Get_number_pending(
243  rtems_id  id,
244  uint32_t *count
245)
246{
247  _Thread_Get_executing()->Wait.return_argument = count;
248  return _Message_queue_MP_Send_request_packet(
249    id,
250    NULL,
251    NULL,
252    0,
253    MPCI_DEFAULT_TIMEOUT,
254    MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_REQUEST
255  );
256}
257
258rtems_status_code _Message_queue_MP_Receive(
259  rtems_id        id,
260  void           *buffer,
261  size_t         *size,
262  rtems_option    option_set,
263  rtems_interval  timeout
264)
265{
266  return _Message_queue_MP_Send_request_packet(
267    id,
268    buffer,
269    size,
270    option_set,
271    timeout,
272    MESSAGE_QUEUE_MP_RECEIVE_REQUEST
273  );
274}
275
276rtems_status_code _Message_queue_MP_Send(
277  rtems_id    id,
278  const void *buffer,
279  size_t      size
280)
281{
282  return _Message_queue_MP_Send_request_packet(
283    id,
284    buffer,
285    &size,
286    0,
287    MPCI_DEFAULT_TIMEOUT,
288    MESSAGE_QUEUE_MP_SEND_REQUEST
289  );
290}
291
292rtems_status_code _Message_queue_MP_Urgent(
293  rtems_id    id,
294  const void *buffer,
295  size_t      size
296)
297{
298  return _Message_queue_MP_Send_request_packet(
299    id,
300    buffer,
301    &size,
302    0,
303    MPCI_DEFAULT_TIMEOUT,
304    MESSAGE_QUEUE_MP_URGENT_REQUEST
305  );
306}
307
308/*
309 *  _Message_queue_MP_Send_response_packet
310 *
311 */
312
313static void _Message_queue_MP_Send_response_packet (
314  Message_queue_MP_Remote_operations  operation,
315  Objects_Id                          message_queue_id,
316  Thread_Control                     *the_thread
317)
318{
319  Message_queue_MP_Packet *the_packet;
320
321  switch ( operation ) {
322
323    case MESSAGE_QUEUE_MP_RECEIVE_RESPONSE:
324    case MESSAGE_QUEUE_MP_SEND_RESPONSE:
325    case MESSAGE_QUEUE_MP_URGENT_RESPONSE:
326    case MESSAGE_QUEUE_MP_BROADCAST_RESPONSE:
327    case MESSAGE_QUEUE_MP_FLUSH_RESPONSE:
328    case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_RESPONSE:
329
330      the_packet = ( Message_queue_MP_Packet *) the_thread->receive_packet;
331
332/*
333 *  The packet being returned already contains the class, length, and
334 *  to_convert fields, therefore they are not set in this routine.
335 *
336 *  Exception: MESSAGE_QUEUE_MP_RECEIVE_RESPONSE needs payload length
337 *             added to 'length'
338 */
339      the_packet->operation = operation;
340      the_packet->Prefix.id = the_packet->Prefix.source_tid;
341
342      if (operation == MESSAGE_QUEUE_MP_RECEIVE_RESPONSE)
343          the_packet->Prefix.length += the_packet->size;
344
345      _MPCI_Send_response_packet(
346        _Objects_Get_node( the_packet->Prefix.source_tid ),
347        &the_packet->Prefix
348      );
349      break;
350
351    case MESSAGE_QUEUE_MP_ANNOUNCE_CREATE:
352    case MESSAGE_QUEUE_MP_ANNOUNCE_DELETE:
353    case MESSAGE_QUEUE_MP_EXTRACT_PROXY:
354    case MESSAGE_QUEUE_MP_RECEIVE_REQUEST:
355    case MESSAGE_QUEUE_MP_SEND_REQUEST:
356    case MESSAGE_QUEUE_MP_URGENT_REQUEST:
357    case MESSAGE_QUEUE_MP_BROADCAST_REQUEST:
358    case MESSAGE_QUEUE_MP_FLUSH_REQUEST:
359    case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_REQUEST:
360      break;
361
362  }
363}
364
365static void _Message_queue_MP_Process_packet (
366  rtems_packet_prefix   *the_packet_prefix
367)
368{
369  Message_queue_MP_Packet *the_packet;
370  Thread_Control          *the_thread;
371
372  the_packet = (Message_queue_MP_Packet *) the_packet_prefix;
373
374  switch ( the_packet->operation ) {
375
376    case MESSAGE_QUEUE_MP_ANNOUNCE_CREATE:
377
378      _Objects_MP_Allocate_and_open(
379        &_Message_queue_Information,
380        the_packet->name,
381        the_packet->Prefix.id,
382        true
383      );
384
385      _MPCI_Return_packet( the_packet_prefix );
386      break;
387
388    case MESSAGE_QUEUE_MP_ANNOUNCE_DELETE:
389
390      _Objects_MP_Close( &_Message_queue_Information, the_packet->Prefix.id );
391
392      _MPCI_Return_packet( the_packet_prefix );
393      break;
394
395    case MESSAGE_QUEUE_MP_EXTRACT_PROXY:
396
397      the_thread = _Thread_MP_Find_proxy( the_packet->proxy_id );
398
399      if (! _Thread_Is_null( the_thread ) )
400         _Thread_queue_Extract( the_thread );
401
402      _MPCI_Return_packet( the_packet_prefix );
403      break;
404
405    case MESSAGE_QUEUE_MP_RECEIVE_REQUEST:
406
407      the_packet->Prefix.return_code = rtems_message_queue_receive(
408        the_packet->Prefix.id,
409        the_packet->Buffer.buffer,
410        &the_packet->size,
411        the_packet->option_set,
412        the_packet->Prefix.timeout
413      );
414
415      if ( the_packet->Prefix.return_code != RTEMS_PROXY_BLOCKING )
416        _Message_queue_MP_Send_response_packet(
417          MESSAGE_QUEUE_MP_RECEIVE_RESPONSE,
418          the_packet->Prefix.id,
419          _Thread_Executing
420        );
421      break;
422
423    case MESSAGE_QUEUE_MP_RECEIVE_RESPONSE:
424
425      the_thread = _MPCI_Process_response( the_packet_prefix );
426
427      if (the_packet->Prefix.return_code == RTEMS_SUCCESSFUL) {
428        *(size_t *) the_thread->Wait.return_argument =
429           the_packet->size;
430
431        _CORE_message_queue_Copy_buffer(
432          the_packet->Buffer.buffer,
433          the_thread->Wait.return_argument_second.mutable_object,
434          the_packet->size
435        );
436      }
437
438      _MPCI_Return_packet( the_packet_prefix );
439      break;
440
441    case MESSAGE_QUEUE_MP_SEND_REQUEST:
442
443      the_packet->Prefix.return_code = rtems_message_queue_send(
444        the_packet->Prefix.id,
445        the_packet->Buffer.buffer,
446        the_packet->Buffer.size
447      );
448
449      _Message_queue_MP_Send_response_packet(
450        MESSAGE_QUEUE_MP_SEND_RESPONSE,
451        the_packet->Prefix.id,
452        _Thread_Executing
453      );
454      break;
455
456    case MESSAGE_QUEUE_MP_SEND_RESPONSE:
457    case MESSAGE_QUEUE_MP_URGENT_RESPONSE:
458
459      the_thread = _MPCI_Process_response( the_packet_prefix );
460
461      _MPCI_Return_packet( the_packet_prefix );
462      break;
463
464    case MESSAGE_QUEUE_MP_URGENT_REQUEST:
465
466      the_packet->Prefix.return_code = rtems_message_queue_urgent(
467        the_packet->Prefix.id,
468        the_packet->Buffer.buffer,
469        the_packet->Buffer.size
470      );
471
472      _Message_queue_MP_Send_response_packet(
473        MESSAGE_QUEUE_MP_URGENT_RESPONSE,
474        the_packet->Prefix.id,
475        _Thread_Executing
476      );
477      break;
478
479    case MESSAGE_QUEUE_MP_BROADCAST_REQUEST:
480
481      the_packet->Prefix.return_code = rtems_message_queue_broadcast(
482        the_packet->Prefix.id,
483        the_packet->Buffer.buffer,
484        the_packet->Buffer.size,
485        &the_packet->count
486      );
487
488      _Message_queue_MP_Send_response_packet(
489        MESSAGE_QUEUE_MP_BROADCAST_RESPONSE,
490        the_packet->Prefix.id,
491        _Thread_Executing
492      );
493      break;
494
495    case MESSAGE_QUEUE_MP_BROADCAST_RESPONSE:
496    case MESSAGE_QUEUE_MP_FLUSH_RESPONSE:
497    case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_RESPONSE:
498
499      the_thread = _MPCI_Process_response( the_packet_prefix );
500
501      *(uint32_t *) the_thread->Wait.return_argument = the_packet->count;
502
503      _MPCI_Return_packet( the_packet_prefix );
504      break;
505
506    case MESSAGE_QUEUE_MP_FLUSH_REQUEST:
507
508      the_packet->Prefix.return_code = rtems_message_queue_flush(
509        the_packet->Prefix.id,
510        &the_packet->count
511      );
512
513      _Message_queue_MP_Send_response_packet(
514        MESSAGE_QUEUE_MP_FLUSH_RESPONSE,
515        the_packet->Prefix.id,
516        _Thread_Executing
517      );
518      break;
519
520    case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_REQUEST:
521
522      the_packet->Prefix.return_code = rtems_message_queue_get_number_pending(
523        the_packet->Prefix.id,
524        &the_packet->count
525      );
526
527      _Message_queue_MP_Send_response_packet(
528        MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_RESPONSE,
529        the_packet->Prefix.id,
530        _Thread_Executing
531      );
532      break;
533
534  }
535}
536
537/*
538 *  _Message_queue_MP_Send_object_was_deleted
539 *
540 */
541
542void _Message_queue_MP_Send_object_was_deleted (
543  Thread_Control *the_proxy,
544  Objects_Id      mp_id
545)
546{
547  the_proxy->receive_packet->return_code = RTEMS_OBJECT_WAS_DELETED;
548
549  _Message_queue_MP_Send_response_packet(
550    MESSAGE_QUEUE_MP_RECEIVE_RESPONSE,
551    mp_id,
552    the_proxy
553  );
554}
555
556/*
557 *  _Message_queue_MP_Send_extract_proxy
558 *
559 */
560
561void _Message_queue_MP_Send_extract_proxy (
562  Thread_Control *the_thread,
563  Objects_Id      id
564)
565{
566  _Message_queue_MP_Send_process_packet(
567    MESSAGE_QUEUE_MP_EXTRACT_PROXY,
568    id,
569    (rtems_name) 0,
570    the_thread->Object.id
571  );
572}
573
574void  _Message_queue_Core_message_queue_mp_support(
575  Thread_Control *the_thread,
576  Objects_Id      id
577)
578{
579  the_thread->receive_packet->return_code = RTEMS_SUCCESSFUL;
580
581  _Message_queue_MP_Send_response_packet(
582    MESSAGE_QUEUE_MP_RECEIVE_RESPONSE,
583    id,
584    the_thread
585  );
586}
587
588static void _Message_queue_MP_Initialize( void )
589{
590  _MPCI_Register_packet_processor(
591    MP_PACKET_MESSAGE_QUEUE,
592    _Message_queue_MP_Process_packet
593  );
594}
595
596RTEMS_SYSINIT_ITEM(
597  _Message_queue_MP_Initialize,
598  RTEMS_SYSINIT_CLASSIC_MESSAGE_QUEUE_MP,
599  RTEMS_SYSINIT_ORDER_MIDDLE
600);
Note: See TracBrowser for help on using the repository browser.