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

4.104.114.84.95
Last change on this file since bb322a0 was 3b438fa, checked in by Joel Sherrill <joel.sherrill@…>, on 08/17/95 at 19:39:31

variable length messages

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