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

4.104.114.84.95
Last change on this file since f26145b was 1095ec1, checked in by Ralf Corsepius <ralf.corsepius@…>, on 01/18/05 at 09:03:45

Include config.h.

  • Property mode set to 100644
File size: 13.4 KB
Line 
1/*
2 *  Multiprocessing Support for the Message Queue Manager
3 *
4 *
5 *  COPYRIGHT (c) 1989-1999.
6 *  On-Line Applications Research Corporation (OAR).
7 *
8 *  The license and distribution terms for this file may be
9 *  found in the file LICENSE in this distribution or at
10 *  http://www.rtems.com/license/LICENSE.
11 *
12 *  $Id$
13 */
14
15#if HAVE_CONFIG_H
16#include "config.h"
17#endif
18
19#include <rtems/system.h>
20#include <rtems/rtems/status.h>
21#include <rtems/rtems/message.h>
22#include <rtems/score/mpci.h>
23#include <rtems/rtems/msgmp.h>
24#include <rtems/score/object.h>
25#include <rtems/rtems/options.h>
26#include <rtems/score/thread.h>
27#include <rtems/score/watchdog.h>
28#include <rtems/rtems/support.h>
29
30/*PAGE
31 *
32 *  _Message_queue_MP_Send_process_packet
33 *
34 */
35
36void _Message_queue_MP_Send_process_packet (
37  Message_queue_MP_Remote_operations  operation,
38  Objects_Id                          message_queue_id,
39  rtems_name                          name,
40  Objects_Id                          proxy_id
41)
42{
43  Message_queue_MP_Packet *the_packet;
44  uint32_t                 node;
45
46  switch ( operation ) {
47
48    case MESSAGE_QUEUE_MP_ANNOUNCE_CREATE:
49    case MESSAGE_QUEUE_MP_ANNOUNCE_DELETE:
50    case MESSAGE_QUEUE_MP_EXTRACT_PROXY:
51
52      the_packet                    = _Message_queue_MP_Get_packet();
53      the_packet->Prefix.the_class  = MP_PACKET_MESSAGE_QUEUE;
54      the_packet->Prefix.length     = sizeof ( Message_queue_MP_Packet );
55      the_packet->Prefix.to_convert = sizeof ( Message_queue_MP_Packet );
56      the_packet->operation         = operation;
57      the_packet->Prefix.id         = message_queue_id;
58      the_packet->name              = name;
59      the_packet->proxy_id          = proxy_id;
60
61      if ( operation == MESSAGE_QUEUE_MP_EXTRACT_PROXY )
62         node = rtems_get_node( message_queue_id );
63      else
64         node = MPCI_ALL_NODES;
65
66      _MPCI_Send_process_packet( node, &the_packet->Prefix );
67      break;
68
69    case MESSAGE_QUEUE_MP_RECEIVE_REQUEST:
70    case MESSAGE_QUEUE_MP_RECEIVE_RESPONSE:
71    case MESSAGE_QUEUE_MP_SEND_REQUEST:
72    case MESSAGE_QUEUE_MP_SEND_RESPONSE:
73    case MESSAGE_QUEUE_MP_URGENT_REQUEST:
74    case MESSAGE_QUEUE_MP_URGENT_RESPONSE:
75    case MESSAGE_QUEUE_MP_BROADCAST_REQUEST:
76    case MESSAGE_QUEUE_MP_BROADCAST_RESPONSE:
77    case MESSAGE_QUEUE_MP_FLUSH_REQUEST:
78    case MESSAGE_QUEUE_MP_FLUSH_RESPONSE:
79    case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_REQUEST:
80    case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_RESPONSE:
81      break;
82
83  }
84}
85
86/*PAGE
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  void                               *buffer,
96  uint32_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     = sizeof(Message_queue_MP_Packet);
114      if ( size_p )
115        the_packet->Prefix.length     += *size_p;
116      the_packet->Prefix.to_convert = sizeof(Message_queue_MP_Packet);
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          _Thread_Enable_dispatch();
126          return RTEMS_INVALID_SIZE;
127      }
128
129      if (! _Options_Is_no_wait(option_set))
130          the_packet->Prefix.timeout = timeout;
131
132      the_packet->operation  = operation;
133      the_packet->Prefix.id  = message_queue_id;
134      the_packet->option_set = option_set;
135
136      /*
137       * Copy the data into place if needed
138       */
139
140      if (buffer) {
141          the_packet->Buffer.size = *size_p;
142          _CORE_message_queue_Copy_buffer(
143            buffer,
144            the_packet->Buffer.buffer,
145            *size_p
146          );
147      }
148
149      return (rtems_status_code) _MPCI_Send_request_packet(
150        rtems_get_node(message_queue_id),
151        &the_packet->Prefix,
152        STATES_WAITING_FOR_MESSAGE
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     = sizeof(Message_queue_MP_Packet);
161      the_packet->Prefix.to_convert = sizeof(Message_queue_MP_Packet);
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   = (uint32_t   *)buffer;
172      _Thread_Executing->Wait.return_argument_1 = size_p;
173
174      return (rtems_status_code) _MPCI_Send_request_packet(
175        rtems_get_node(message_queue_id),
176        &the_packet->Prefix,
177        STATES_WAITING_FOR_MESSAGE
178      );
179      break;
180
181    case MESSAGE_QUEUE_MP_ANNOUNCE_CREATE:
182    case MESSAGE_QUEUE_MP_ANNOUNCE_DELETE:
183    case MESSAGE_QUEUE_MP_EXTRACT_PROXY:
184    case MESSAGE_QUEUE_MP_RECEIVE_RESPONSE:
185    case MESSAGE_QUEUE_MP_SEND_RESPONSE:
186    case MESSAGE_QUEUE_MP_URGENT_RESPONSE:
187    case MESSAGE_QUEUE_MP_BROADCAST_RESPONSE:
188    case MESSAGE_QUEUE_MP_FLUSH_RESPONSE:
189    case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_RESPONSE:
190      break;
191  }
192
193  return RTEMS_SUCCESSFUL;
194}
195
196/*PAGE
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        rtems_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/*PAGE
255 *
256 *
257 *  _Message_queue_MP_Process_packet
258 *
259 */
260
261void _Message_queue_MP_Process_packet (
262  rtems_packet_prefix   *the_packet_prefix
263)
264{
265  Message_queue_MP_Packet *the_packet;
266  Thread_Control          *the_thread;
267  boolean                  ignored;
268
269  the_packet = (Message_queue_MP_Packet *) the_packet_prefix;
270
271  switch ( the_packet->operation ) {
272
273    case MESSAGE_QUEUE_MP_ANNOUNCE_CREATE:
274
275      ignored = _Objects_MP_Allocate_and_open(
276                  &_Message_queue_Information,
277                  the_packet->name,
278                  the_packet->Prefix.id,
279                  TRUE
280                );
281
282      _MPCI_Return_packet( the_packet_prefix );
283      break;
284
285    case MESSAGE_QUEUE_MP_ANNOUNCE_DELETE:
286
287      _Objects_MP_Close( &_Message_queue_Information, the_packet->Prefix.id );
288
289      _MPCI_Return_packet( the_packet_prefix );
290      break;
291
292    case MESSAGE_QUEUE_MP_EXTRACT_PROXY:
293
294      the_thread = _Thread_MP_Find_proxy( the_packet->proxy_id );
295
296      if (! _Thread_Is_null( the_thread ) )
297         _Thread_queue_Extract( the_thread->Wait.queue, the_thread );
298
299      _MPCI_Return_packet( the_packet_prefix );
300      break;
301
302    case MESSAGE_QUEUE_MP_RECEIVE_REQUEST:
303
304      the_packet->Prefix.return_code = rtems_message_queue_receive(
305        the_packet->Prefix.id,
306        the_packet->Buffer.buffer,
307        &the_packet->size,
308        the_packet->option_set,
309        the_packet->Prefix.timeout
310      );
311
312      if (! _Thread_Is_proxy_blocking( the_packet->Prefix.return_code ) )
313        _Message_queue_MP_Send_response_packet(
314          MESSAGE_QUEUE_MP_RECEIVE_RESPONSE,
315          the_packet->Prefix.id,
316          _Thread_Executing
317        );
318      break;
319
320    case MESSAGE_QUEUE_MP_RECEIVE_RESPONSE:
321
322      the_thread = _MPCI_Process_response( the_packet_prefix );
323
324      if (the_packet->Prefix.return_code == RTEMS_SUCCESSFUL) {
325        *(uint32_t   *)the_thread->Wait.return_argument_1 =
326           the_packet->size;
327
328        _CORE_message_queue_Copy_buffer(
329          the_packet->Buffer.buffer,
330          the_thread->Wait.return_argument,
331          the_packet->size
332        );
333      }
334
335      _MPCI_Return_packet( the_packet_prefix );
336      break;
337
338    case MESSAGE_QUEUE_MP_SEND_REQUEST:
339
340      the_packet->Prefix.return_code = rtems_message_queue_send(
341        the_packet->Prefix.id,
342        the_packet->Buffer.buffer,
343        the_packet->Buffer.size
344      );
345
346      _Message_queue_MP_Send_response_packet(
347        MESSAGE_QUEUE_MP_SEND_RESPONSE,
348        the_packet->Prefix.id,
349        _Thread_Executing
350      );
351      break;
352
353    case MESSAGE_QUEUE_MP_SEND_RESPONSE:
354    case MESSAGE_QUEUE_MP_URGENT_RESPONSE:
355
356      the_thread = _MPCI_Process_response( the_packet_prefix );
357
358      _MPCI_Return_packet( the_packet_prefix );
359      break;
360
361    case MESSAGE_QUEUE_MP_URGENT_REQUEST:
362
363      the_packet->Prefix.return_code = rtems_message_queue_urgent(
364        the_packet->Prefix.id,
365        the_packet->Buffer.buffer,
366        the_packet->Buffer.size
367      );
368
369      _Message_queue_MP_Send_response_packet(
370        MESSAGE_QUEUE_MP_URGENT_RESPONSE,
371        the_packet->Prefix.id,
372        _Thread_Executing
373      );
374      break;
375
376    case MESSAGE_QUEUE_MP_BROADCAST_REQUEST:
377
378      the_packet->Prefix.return_code = rtems_message_queue_broadcast(
379        the_packet->Prefix.id,
380        the_packet->Buffer.buffer,
381        the_packet->Buffer.size,
382        &the_packet->count
383      );
384
385      _Message_queue_MP_Send_response_packet(
386        MESSAGE_QUEUE_MP_BROADCAST_RESPONSE,
387        the_packet->Prefix.id,
388        _Thread_Executing
389      );
390      break;
391
392    case MESSAGE_QUEUE_MP_BROADCAST_RESPONSE:
393    case MESSAGE_QUEUE_MP_FLUSH_RESPONSE:
394    case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_RESPONSE:
395
396      the_thread = _MPCI_Process_response( the_packet_prefix );
397
398      *(uint32_t   *)the_thread->Wait.return_argument = the_packet->count;
399
400      _MPCI_Return_packet( the_packet_prefix );
401      break;
402
403    case MESSAGE_QUEUE_MP_FLUSH_REQUEST:
404
405      the_packet->Prefix.return_code = rtems_message_queue_flush(
406        the_packet->Prefix.id,
407        &the_packet->count
408      );
409
410      _Message_queue_MP_Send_response_packet(
411        MESSAGE_QUEUE_MP_FLUSH_RESPONSE,
412        the_packet->Prefix.id,
413        _Thread_Executing
414      );
415      break;
416
417    case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_REQUEST:
418
419      the_packet->Prefix.return_code = rtems_message_queue_get_number_pending(
420        the_packet->Prefix.id,
421        &the_packet->count
422      );
423
424      _Message_queue_MP_Send_response_packet(
425        MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_RESPONSE,
426        the_packet->Prefix.id,
427        _Thread_Executing
428      );
429      break;
430
431  }
432}
433
434/*PAGE
435 *
436 *  _Message_queue_MP_Send_object_was_deleted
437 *
438 */
439
440void _Message_queue_MP_Send_object_was_deleted (
441  Thread_Control  *the_proxy
442)
443{
444  the_proxy->receive_packet->return_code = RTEMS_OBJECT_WAS_DELETED;
445
446  _Message_queue_MP_Send_response_packet(
447    MESSAGE_QUEUE_MP_RECEIVE_RESPONSE,
448    the_proxy->Wait.id,
449    the_proxy
450  );
451}
452
453/*PAGE
454 *
455 *  _Message_queue_MP_Send_extract_proxy
456 *
457 */
458
459void _Message_queue_MP_Send_extract_proxy (
460  void           *argument
461)
462{
463  Thread_Control *the_thread = (Thread_Control *)argument;
464
465  _Message_queue_MP_Send_process_packet(
466    MESSAGE_QUEUE_MP_EXTRACT_PROXY,
467    the_thread->Wait.id,
468    (rtems_name) 0,
469    the_thread->Object.id
470  );
471}
472
473/*PAGE
474 *
475 *  _Message_queue_MP_Get_packet
476 *
477 */
478
479Message_queue_MP_Packet *_Message_queue_MP_Get_packet ( void )
480{
481  return ( (Message_queue_MP_Packet *) _MPCI_Get_packet() );
482}
483
484
485/*PAGE
486 *
487 *  _Message_queue_Core_message_queue_mp_support
488 *
489 *  Input parameters:
490 *    the_thread - the remote thread the message was submitted to
491 *    id         - id of the message queue
492 *
493 *  Output parameters: NONE
494 */
495
496void  _Message_queue_Core_message_queue_mp_support (
497  Thread_Control *the_thread,
498  Objects_Id      id
499)
500{
501  the_thread->receive_packet->return_code = RTEMS_SUCCESSFUL;
502
503  _Message_queue_MP_Send_response_packet(
504    MESSAGE_QUEUE_MP_RECEIVE_RESPONSE,
505    id,
506    the_thread
507  );
508}
509
510/* end of file */
Note: See TracBrowser for help on using the repository browser.