source: rtems/c/src/exec/rtems/src/msgmp.c @ 03f2154e

4.104.114.84.95
Last change on this file since 03f2154e was 03f2154e, checked in by Joel Sherrill <joel.sherrill@…>, on Apr 22, 1997 at 5:20:27 PM

headers updated to reflect new style copyright notice as part
of switching to the modified GNU GPL.

  • Property mode set to 100644
File size: 12.2 KB
Line 
1/*
2 *  Multiprocessing Support for the Message Queue Manager
3 *
4 *
5 *  COPYRIGHT (c) 1989-1997.
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 in
10 *  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      break;
77
78  }
79}
80
81/*PAGE
82 *
83 *  _Message_queue_MP_Send_request_packet
84 *
85 */
86
87rtems_status_code _Message_queue_MP_Send_request_packet (
88  Message_queue_MP_Remote_operations  operation,
89  Objects_Id                          message_queue_id,
90  void                               *buffer,
91  unsigned32                         *size_p,
92  rtems_option                        option_set,
93  rtems_interval                      timeout
94)
95{
96  Message_queue_MP_Packet *the_packet;
97
98  switch ( operation ) {
99
100    case MESSAGE_QUEUE_MP_SEND_REQUEST:
101    case MESSAGE_QUEUE_MP_URGENT_REQUEST:
102    case MESSAGE_QUEUE_MP_BROADCAST_REQUEST:
103    case MESSAGE_QUEUE_MP_FLUSH_REQUEST:
104
105      the_packet                    = _Message_queue_MP_Get_packet();
106      the_packet->Prefix.the_class  = MP_PACKET_MESSAGE_QUEUE;
107      the_packet->Prefix.length     = sizeof(Message_queue_MP_Packet);
108      if ( size_p )
109        the_packet->Prefix.length     += *size_p;
110      the_packet->Prefix.to_convert = sizeof(Message_queue_MP_Packet);
111
112      /*
113       * make sure message is not too big for our MPCI driver
114       * We have to check it here instead of waiting for MPCI because
115       * we are about to slam in the payload
116       */
117
118      if (the_packet->Prefix.length > _MPCI_table->maximum_packet_size) {
119          _Thread_Enable_dispatch();
120          return RTEMS_INVALID_SIZE;
121      }
122
123      if ( ! _Options_Is_no_wait(option_set))
124          the_packet->Prefix.timeout = timeout;
125
126      the_packet->operation  = operation;
127      the_packet->Prefix.id  = message_queue_id;
128      the_packet->option_set = option_set;
129
130      /*
131       * Copy the data into place if needed
132       */
133     
134      if (buffer) {
135          the_packet->Buffer.size = *size_p;
136          _CORE_message_queue_Copy_buffer(
137            buffer,
138            the_packet->Buffer.buffer,
139            *size_p
140          );
141      }
142
143      return (rtems_status_code) _MPCI_Send_request_packet(
144        rtems_get_node(message_queue_id),
145        &the_packet->Prefix,
146        STATES_WAITING_FOR_MESSAGE
147      );
148      break;
149
150    case MESSAGE_QUEUE_MP_RECEIVE_REQUEST:
151
152      the_packet                    = _Message_queue_MP_Get_packet();
153      the_packet->Prefix.the_class  = MP_PACKET_MESSAGE_QUEUE;
154      the_packet->Prefix.length     = sizeof(Message_queue_MP_Packet);
155      the_packet->Prefix.to_convert = sizeof(Message_queue_MP_Packet);
156
157      if ( ! _Options_Is_no_wait(option_set))
158          the_packet->Prefix.timeout = timeout;
159
160      the_packet->operation  = MESSAGE_QUEUE_MP_RECEIVE_REQUEST;
161      the_packet->Prefix.id  = message_queue_id;
162      the_packet->option_set = option_set;
163      the_packet->size       = 0;        /* just in case of an error */
164
165      _Thread_Executing->Wait.return_argument   = (unsigned32 *)buffer;
166      _Thread_Executing->Wait.return_argument_1 = size_p;
167     
168      return (rtems_status_code) _MPCI_Send_request_packet(
169        rtems_get_node(message_queue_id),
170        &the_packet->Prefix,
171        STATES_WAITING_FOR_MESSAGE
172      );
173      break;
174
175    case MESSAGE_QUEUE_MP_ANNOUNCE_CREATE:
176    case MESSAGE_QUEUE_MP_ANNOUNCE_DELETE:
177    case MESSAGE_QUEUE_MP_EXTRACT_PROXY:
178    case MESSAGE_QUEUE_MP_RECEIVE_RESPONSE:
179    case MESSAGE_QUEUE_MP_SEND_RESPONSE:
180    case MESSAGE_QUEUE_MP_URGENT_RESPONSE:
181    case MESSAGE_QUEUE_MP_BROADCAST_RESPONSE:
182    case MESSAGE_QUEUE_MP_FLUSH_RESPONSE:
183      break;
184  }
185
186  return RTEMS_SUCCESSFUL;
187}
188
189/*PAGE
190 *
191 *  _Message_queue_MP_Send_response_packet
192 *
193 */
194
195void _Message_queue_MP_Send_response_packet (
196  Message_queue_MP_Remote_operations  operation,
197  Objects_Id                          message_queue_id,
198  Thread_Control                     *the_thread
199)
200{
201  Message_queue_MP_Packet *the_packet;
202
203  switch ( operation ) {
204
205    case MESSAGE_QUEUE_MP_RECEIVE_RESPONSE:
206    case MESSAGE_QUEUE_MP_SEND_RESPONSE:
207    case MESSAGE_QUEUE_MP_URGENT_RESPONSE:
208    case MESSAGE_QUEUE_MP_BROADCAST_RESPONSE:
209    case MESSAGE_QUEUE_MP_FLUSH_RESPONSE:
210
211      the_packet = ( Message_queue_MP_Packet *) the_thread->receive_packet;
212
213/*
214 *  The packet being returned already contains the class, length, and
215 *  to_convert fields, therefore they are not set in this routine.
216 *
217 *  Exception: MESSAGE_QUEUE_MP_RECEIVE_RESPONSE needs payload length
218 *             added to 'length'
219 */
220      the_packet->operation = operation;
221      the_packet->Prefix.id = the_packet->Prefix.source_tid;
222
223      if (operation == MESSAGE_QUEUE_MP_RECEIVE_RESPONSE)
224          the_packet->Prefix.length += the_packet->size;
225     
226      _MPCI_Send_response_packet(
227        rtems_get_node( the_packet->Prefix.source_tid ),
228        &the_packet->Prefix
229      );
230      break;
231
232    case MESSAGE_QUEUE_MP_ANNOUNCE_CREATE:
233    case MESSAGE_QUEUE_MP_ANNOUNCE_DELETE:
234    case MESSAGE_QUEUE_MP_EXTRACT_PROXY:
235    case MESSAGE_QUEUE_MP_RECEIVE_REQUEST:
236    case MESSAGE_QUEUE_MP_SEND_REQUEST:
237    case MESSAGE_QUEUE_MP_URGENT_REQUEST:
238    case MESSAGE_QUEUE_MP_BROADCAST_REQUEST:
239    case MESSAGE_QUEUE_MP_FLUSH_REQUEST:
240      break;
241
242  }
243}
244
245/*PAGE
246 *
247 *
248 *  _Message_queue_MP_Process_packet
249 *
250 */
251
252void _Message_queue_MP_Process_packet (
253  rtems_packet_prefix   *the_packet_prefix
254)
255{
256  Message_queue_MP_Packet *the_packet;
257  Thread_Control          *the_thread;
258  boolean                  ignored;
259
260  the_packet = (Message_queue_MP_Packet *) the_packet_prefix;
261
262  switch ( the_packet->operation ) {
263
264    case MESSAGE_QUEUE_MP_ANNOUNCE_CREATE:
265
266      ignored = _Objects_MP_Allocate_and_open(
267                  &_Message_queue_Information,
268                  the_packet->name,
269                  the_packet->Prefix.id,
270                  TRUE
271                );
272
273      _MPCI_Return_packet( the_packet_prefix );
274      break;
275
276    case MESSAGE_QUEUE_MP_ANNOUNCE_DELETE:
277
278      _Objects_MP_Close( &_Message_queue_Information, the_packet->Prefix.id );
279
280      _MPCI_Return_packet( the_packet_prefix );
281      break;
282
283    case MESSAGE_QUEUE_MP_EXTRACT_PROXY:
284
285      the_thread = _Thread_MP_Find_proxy( the_packet->proxy_id );
286
287      if ( ! _Thread_Is_null( the_thread ) )
288         _Thread_queue_Extract( the_thread->Wait.queue, the_thread );
289
290      _MPCI_Return_packet( the_packet_prefix );
291      break;
292
293    case MESSAGE_QUEUE_MP_RECEIVE_REQUEST:
294
295      the_packet->Prefix.return_code = rtems_message_queue_receive(
296        the_packet->Prefix.id,
297        the_packet->Buffer.buffer,
298        &the_packet->size,
299        the_packet->option_set,
300        the_packet->Prefix.timeout
301      );
302
303      if ( ! _Thread_Is_proxy_blocking( the_packet->Prefix.return_code ) )
304        _Message_queue_MP_Send_response_packet(
305          MESSAGE_QUEUE_MP_RECEIVE_RESPONSE,
306          the_packet->Prefix.id,
307          _Thread_Executing
308        );
309      break;
310
311    case MESSAGE_QUEUE_MP_RECEIVE_RESPONSE:
312
313      the_thread = _MPCI_Process_response( the_packet_prefix );
314
315      if (the_packet->Prefix.return_code == RTEMS_SUCCESSFUL) {
316        *(rtems_unsigned32 *)the_thread->Wait.return_argument_1 = 
317           the_packet->size;
318
319        _CORE_message_queue_Copy_buffer(
320          the_packet->Buffer.buffer,
321          the_thread->Wait.return_argument,
322          the_packet->size
323        );
324      }
325
326      _MPCI_Return_packet( the_packet_prefix );
327      break;
328
329    case MESSAGE_QUEUE_MP_SEND_REQUEST:
330
331      the_packet->Prefix.return_code = rtems_message_queue_send(
332        the_packet->Prefix.id,
333        the_packet->Buffer.buffer,
334        the_packet->Buffer.size
335      );
336
337      _Message_queue_MP_Send_response_packet(
338        MESSAGE_QUEUE_MP_SEND_RESPONSE,
339        the_packet->Prefix.id,
340        _Thread_Executing
341      );
342      break;
343
344    case MESSAGE_QUEUE_MP_SEND_RESPONSE:
345    case MESSAGE_QUEUE_MP_URGENT_RESPONSE:
346
347      the_thread = _MPCI_Process_response( the_packet_prefix );
348
349      _MPCI_Return_packet( the_packet_prefix );
350      break;
351
352    case MESSAGE_QUEUE_MP_URGENT_REQUEST:
353
354      the_packet->Prefix.return_code = rtems_message_queue_urgent(
355        the_packet->Prefix.id,
356        the_packet->Buffer.buffer,
357        the_packet->Buffer.size
358      );
359
360      _Message_queue_MP_Send_response_packet(
361        MESSAGE_QUEUE_MP_URGENT_RESPONSE,
362        the_packet->Prefix.id,
363        _Thread_Executing
364      );
365      break;
366
367    case MESSAGE_QUEUE_MP_BROADCAST_REQUEST:
368
369      the_packet->Prefix.return_code = rtems_message_queue_broadcast(
370        the_packet->Prefix.id,
371        the_packet->Buffer.buffer,
372        the_packet->Buffer.size,
373        &the_packet->count
374      );
375
376      _Message_queue_MP_Send_response_packet(
377        MESSAGE_QUEUE_MP_BROADCAST_RESPONSE,
378        the_packet->Prefix.id,
379        _Thread_Executing
380      );
381      break;
382
383    case MESSAGE_QUEUE_MP_BROADCAST_RESPONSE:
384    case MESSAGE_QUEUE_MP_FLUSH_RESPONSE:
385
386      the_thread = _MPCI_Process_response( the_packet_prefix );
387
388      *(unsigned32 *)the_thread->Wait.return_argument = the_packet->count;
389
390      _MPCI_Return_packet( the_packet_prefix );
391      break;
392
393    case MESSAGE_QUEUE_MP_FLUSH_REQUEST:
394
395      the_packet->Prefix.return_code = rtems_message_queue_flush(
396        the_packet->Prefix.id,
397        &the_packet->count
398      );
399
400      _Message_queue_MP_Send_response_packet(
401        MESSAGE_QUEUE_MP_FLUSH_RESPONSE,
402        the_packet->Prefix.id,
403        _Thread_Executing
404      );
405      break;
406
407  }
408}
409
410/*PAGE
411 *
412 *  _Message_queue_MP_Send_object_was_deleted
413 *
414 */
415
416void _Message_queue_MP_Send_object_was_deleted (
417  Thread_Control  *the_proxy
418)
419{
420  the_proxy->receive_packet->return_code = RTEMS_OBJECT_WAS_DELETED;
421
422  _Message_queue_MP_Send_response_packet(
423    MESSAGE_QUEUE_MP_RECEIVE_RESPONSE,
424    the_proxy->Wait.id,
425    the_proxy
426  );
427}
428
429/*PAGE
430 *
431 *  _Message_queue_MP_Send_extract_proxy
432 *
433 */
434
435void _Message_queue_MP_Send_extract_proxy (
436  Thread_Control  *the_thread
437)
438{
439  _Message_queue_MP_Send_process_packet(
440    MESSAGE_QUEUE_MP_EXTRACT_PROXY,
441    the_thread->Wait.id,
442    (rtems_name) 0,
443    the_thread->Object.id
444  );
445}
446
447/*PAGE
448 *
449 *  _Message_queue_MP_Get_packet
450 *
451 */
452
453Message_queue_MP_Packet *_Message_queue_MP_Get_packet ( void )
454{
455  return ( (Message_queue_MP_Packet *) _MPCI_Get_packet() );
456}
457
458/* end of file */
Note: See TracBrowser for help on using the repository browser.