source: rtems/cpukit/rtems/src/msgmp.c @ 3972085

Last change on this file since 3972085 was 3972085, checked in by Sebastian Huber <sebastian.huber@…>, on 10/13/20 at 11:47:06

Remove *_Is_null() inline functions

Simply compare the values against NULL.

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