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

4.115
Last change on this file since f5d6c8b was f5d6c8b, checked in by Sebastian Huber <sebastian.huber@…>, on 04/27/15 at 14:25:52

score: Delete Thread_queue_Control::timeout_status

Use a parameter for _Thread_queue_Enqueue() instead to reduce memory
usage.

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