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

4.104.114.84.95
Last change on this file since ef22ab2 was ef22ab2, checked in by Joel Sherrill <joel.sherrill@…>, on 05/17/99 at 22:46:01

Moved an MP routine from msg.c to here.

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