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

4.104.114.84.95
Last change on this file since aefc109 was 08311cc3, checked in by Joel Sherrill <joel.sherrill@…>, on 11/17/99 at 17:51:34

Updated copyright notice.

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