source: rtems/cpukit/rtems/src/msgmp.c @ 66cb142

Last change on this file since 66cb142 was dce48791, checked in by Sebastian Huber <sebastian.huber@…>, on May 23, 2016 at 11:37:59 AM

score: Add Status_Control for all APIs

Unify the status codes of the Classic and POSIX API to use the new enum
Status_Control. This eliminates the Thread_Control::Wait::timeout_code
field and the timeout parameter of _Thread_queue_Enqueue_critical() and
_MPCI_Send_request_packet(). It gets rid of the status code translation
tables and instead uses simple bit operations to get the status for a
particular API. This enables translation of status code constants at
compile time. Add _Thread_Wait_get_status() to avoid direct access of
thread internal data structures.

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