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
RevLine 
[4c90eb4]1/**
2 * @file
[ac7d5ef0]3 *
[4c90eb4]4 * @brief Multiprocessing Support for the Message Queue Manager
5 * @ingroup ClassicMsgMP Message Queue MP Support
6 */
7
8/*
[6c06288]9 *  COPYRIGHT (c) 1989-2008.
[ac7d5ef0]10 *  On-Line Applications Research Corporation (OAR).
11 *
[98e4ebf5]12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
[c499856]14 *  http://www.rtems.org/license/LICENSE.
[ac7d5ef0]15 */
16
[1095ec1]17#if HAVE_CONFIG_H
18#include "config.h"
19#endif
20
[993a888]21#include <rtems/rtems/messageimpl.h>
[caab339]22#include <rtems/rtems/optionsimpl.h>
[dce48791]23#include <rtems/rtems/statusimpl.h>
[7f04cb18]24#include <rtems/score/coremsgimpl.h>
[fe6c170c]25#include <rtems/score/statesimpl.h>
[5618c37a]26#include <rtems/score/threadimpl.h>
[453bb4b]27#include <rtems/sysinit.h>
[ac7d5ef0]28
[d689de0]29RTEMS_STATIC_ASSERT(
30  MESSAGE_QUEUE_MP_PACKET_SIZE <= MP_PACKET_MINIMUM_PACKET_SIZE,
31  Message_queue_MP_Packet
32);
33
[e38a92b]34static Message_queue_MP_Packet *_Message_queue_MP_Get_packet( void )
35{
36  return (Message_queue_MP_Packet *) _MPCI_Get_packet();
37}
38
39
[64adc13]40/*
[ac7d5ef0]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,
[3235ad9]48  rtems_name                          name,
[ac7d5ef0]49  Objects_Id                          proxy_id
50)
51{
52  Message_queue_MP_Packet *the_packet;
[1d496f6]53  uint32_t                 node;
[ac7d5ef0]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();
[3a4ae6c]62      the_packet->Prefix.the_class  = MP_PACKET_MESSAGE_QUEUE;
[75025a6]63      the_packet->Prefix.length     = MESSAGE_QUEUE_MP_PACKET_SIZE;
64      the_packet->Prefix.to_convert = MESSAGE_QUEUE_MP_PACKET_SIZE;
[ac7d5ef0]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 )
[6c06288]71         node = _Objects_Get_node( message_queue_id );
[ac7d5ef0]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:
[e7d8b58]88    case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_REQUEST:
89    case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_RESPONSE:
[ac7d5ef0]90      break;
91
92  }
93}
94
[64adc13]95/*
[ac7d5ef0]96 *  _Message_queue_MP_Send_request_packet
97 *
98 */
99
[641b44c2]100static rtems_status_code _Message_queue_MP_Send_request_packet (
[ac7d5ef0]101  Objects_Id                          message_queue_id,
[f773c012]102  const void                         *buffer,
[6703e491]103  size_t                             *size_p,
[3b438fa]104  rtems_option                        option_set,
[641b44c2]105  rtems_interval                      timeout,
106  Message_queue_MP_Remote_operations  operation
[ac7d5ef0]107)
108{
109  Message_queue_MP_Packet *the_packet;
[dce48791]110  Status_Control           status;
[ac7d5ef0]111
[641b44c2]112  if ( !_Message_queue_MP_Is_remote( message_queue_id ) ) {
113    return RTEMS_INVALID_ID;
114  }
115
[ac7d5ef0]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:
[e7d8b58]122    case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_REQUEST:
[ac7d5ef0]123
124      the_packet                    = _Message_queue_MP_Get_packet();
[3a4ae6c]125      the_packet->Prefix.the_class  = MP_PACKET_MESSAGE_QUEUE;
[fd1661f2]126      the_packet->Prefix.length     = MESSAGE_QUEUE_MP_PACKET_SIZE;
[3b438fa]127      if ( size_p )
[3a4ae6c]128        the_packet->Prefix.length     += *size_p;
[fd1661f2]129      the_packet->Prefix.to_convert = MESSAGE_QUEUE_MP_PACKET_SIZE;
[3b438fa]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
[3a4ae6c]137      if (the_packet->Prefix.length > _MPCI_table->maximum_packet_size) {
[3b438fa]138          return RTEMS_INVALID_SIZE;
139      }
140
[e7d8b58]141      if (! _Options_Is_no_wait(option_set))
[ac7d5ef0]142          the_packet->Prefix.timeout = timeout;
143
[3b438fa]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       */
[50f32b11]151
[3a4ae6c]152      if (buffer) {
[3b438fa]153          the_packet->Buffer.size = *size_p;
[3652ad35]154          _CORE_message_queue_Copy_buffer(
155            buffer,
156            the_packet->Buffer.buffer,
157            *size_p
158          );
[3b438fa]159      }
160
[dce48791]161      status = _MPCI_Send_request_packet(
[6c06288]162        _Objects_Get_node(message_queue_id),
[ffe316d]163        &the_packet->Prefix,
[dce48791]164        STATES_WAITING_FOR_MESSAGE
[ffe316d]165      );
[dce48791]166      return _Status_Get( status );
[ac7d5ef0]167
[3b438fa]168    case MESSAGE_QUEUE_MP_RECEIVE_REQUEST:
[ac7d5ef0]169
[3b438fa]170      the_packet                    = _Message_queue_MP_Get_packet();
[3a4ae6c]171      the_packet->Prefix.the_class  = MP_PACKET_MESSAGE_QUEUE;
[fd1661f2]172      the_packet->Prefix.length     = MESSAGE_QUEUE_MP_PACKET_SIZE;
173      the_packet->Prefix.to_convert = MESSAGE_QUEUE_MP_PACKET_SIZE;
[3b438fa]174
[e7d8b58]175      if (! _Options_Is_no_wait(option_set))
[3b438fa]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
[f773c012]183      _Thread_Executing->Wait.return_argument_second.immutable_object = buffer;
184      _Thread_Executing->Wait.return_argument = size_p;
[50f32b11]185
[dce48791]186      status = _MPCI_Send_request_packet(
[6c06288]187        _Objects_Get_node(message_queue_id),
[ffe316d]188        &the_packet->Prefix,
[dce48791]189        STATES_WAITING_FOR_MESSAGE
[ffe316d]190      );
[dce48791]191      return _Status_Get( status );
[ac7d5ef0]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:
[e7d8b58]201    case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_RESPONSE:
[ac7d5ef0]202      break;
203  }
[3b438fa]204
[ac7d5ef0]205  return RTEMS_SUCCESSFUL;
206}
207
[641b44c2]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
[64adc13]308/*
[ac7d5ef0]309 *  _Message_queue_MP_Send_response_packet
310 *
311 */
312
[c506158c]313static void _Message_queue_MP_Send_response_packet (
[ac7d5ef0]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:
[e7d8b58]328    case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_RESPONSE:
[ac7d5ef0]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.
[3b438fa]335 *
336 *  Exception: MESSAGE_QUEUE_MP_RECEIVE_RESPONSE needs payload length
337 *             added to 'length'
[ac7d5ef0]338 */
339      the_packet->operation = operation;
340      the_packet->Prefix.id = the_packet->Prefix.source_tid;
341
[3b438fa]342      if (operation == MESSAGE_QUEUE_MP_RECEIVE_RESPONSE)
343          the_packet->Prefix.length += the_packet->size;
[50f32b11]344
[ac7d5ef0]345      _MPCI_Send_response_packet(
[6c06288]346        _Objects_Get_node( the_packet->Prefix.source_tid ),
[ac7d5ef0]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:
[e7d8b58]359    case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_REQUEST:
[ac7d5ef0]360      break;
361
362  }
363}
364
[453bb4b]365static void _Message_queue_MP_Process_packet (
[ac7d5ef0]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
[081d03d]378      _Objects_MP_Allocate_and_open(
379        &_Message_queue_Information,
380        the_packet->name,
381        the_packet->Prefix.id,
382        true
383      );
[ac7d5ef0]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
[e7d8b58]399      if (! _Thread_Is_null( the_thread ) )
[22788bc]400         _Thread_queue_Extract( the_thread );
[ac7d5ef0]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,
[3b438fa]409        the_packet->Buffer.buffer,
410        &the_packet->size,
[ac7d5ef0]411        the_packet->option_set,
412        the_packet->Prefix.timeout
413      );
414
[dd1a460e]415      if ( the_packet->Prefix.return_code != RTEMS_PROXY_BLOCKING )
[ac7d5ef0]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
[3b438fa]427      if (the_packet->Prefix.return_code == RTEMS_SUCCESSFUL) {
[f773c012]428        *(size_t *) the_thread->Wait.return_argument =
[3a4ae6c]429           the_packet->size;
[3b438fa]430
[3652ad35]431        _CORE_message_queue_Copy_buffer(
[3b438fa]432          the_packet->Buffer.buffer,
[f773c012]433          the_thread->Wait.return_argument_second.mutable_object,
[3b438fa]434          the_packet->size
435        );
436      }
[ac7d5ef0]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,
[3b438fa]445        the_packet->Buffer.buffer,
446        the_packet->Buffer.size
[ac7d5ef0]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,
[3b438fa]468        the_packet->Buffer.buffer,
469        the_packet->Buffer.size
[ac7d5ef0]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,
[3b438fa]483        the_packet->Buffer.buffer,
484        the_packet->Buffer.size,
[ac7d5ef0]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:
[e7d8b58]497    case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_RESPONSE:
[ac7d5ef0]498
499      the_thread = _MPCI_Process_response( the_packet_prefix );
500
[f773c012]501      *(uint32_t *) the_thread->Wait.return_argument = the_packet->count;
[ac7d5ef0]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
[e7d8b58]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
[ac7d5ef0]534  }
535}
536
[64adc13]537/*
[ac7d5ef0]538 *  _Message_queue_MP_Send_object_was_deleted
539 *
540 */
541
542void _Message_queue_MP_Send_object_was_deleted (
[9809d6e0]543  Thread_Control *the_proxy,
544  Objects_Id      mp_id
[ac7d5ef0]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,
[9809d6e0]551    mp_id,
[ac7d5ef0]552    the_proxy
553  );
554}
555
[64adc13]556/*
[ac7d5ef0]557 *  _Message_queue_MP_Send_extract_proxy
558 *
559 */
560
561void _Message_queue_MP_Send_extract_proxy (
[9d9b6b56]562  Thread_Control *the_thread,
563  Objects_Id      id
[ac7d5ef0]564)
565{
566  _Message_queue_MP_Send_process_packet(
567    MESSAGE_QUEUE_MP_EXTRACT_PROXY,
[9d9b6b56]568    id,
[3235ad9]569    (rtems_name) 0,
[ac7d5ef0]570    the_thread->Object.id
571  );
572}
573
[631b3c8]574void  _Message_queue_Core_message_queue_mp_support(
[ef22ab2]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
[453bb4b]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.