source: rtems/cpukit/rtems/src/msg.c @ 3a4ae6c

4.104.114.84.95
Last change on this file since 3a4ae6c was 3a4ae6c, checked in by Joel Sherrill <joel.sherrill@…>, on 09/11/95 at 19:35:39

The word "RTEMS" almost completely removed from the core.

Configuration Table Template file added and all tests
modified to use this. All gvar.h and conftbl.h files
removed from test directories.

Configuration parameter maximum_devices added.

Core semaphore and mutex handlers added and RTEMS API Semaphore
Manager updated to reflect this.

Initialization sequence changed to invoke API specific initialization
routines. Initialization tasks table now owned by RTEMS Tasks Manager.

Added user extension for post-switch.

Utilized user extensions to implement API specific functionality
like signal dispatching.

Added extensions to the System Initialization Thread so that an
API can register a function to be invoked while the system
is being initialized. These are largely equivalent to the
pre-driver and post-driver hooks.

Added the Modules file oar-go32_p5, modified oar-go32, and modified
the file make/custom/go32.cfg to look at an environment varable which
determines what CPU model is being used.

All BSPs updated to reflect named devices and clock driver's IOCTL
used by the Shared Memory Driver. Also merged clock isr into
main file and removed ckisr.c where possible.

Updated spsize to reflect new and moved variables.

Makefiles for the executive source and include files updated to show
break down of files into Core, RTEMS API, and Neither.

Header and inline files installed into subdirectory based on whether
logically in the Core or a part of the RTEMS API.

  • Property mode set to 100644
File size: 22.3 KB
Line 
1/*
2 *  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/rtems/status.h>
18#include <rtems/rtems/attr.h>
19#include <rtems/core/chain.h>
20#include <rtems/core/isr.h>
21#include <rtems/rtems/message.h>
22#include <rtems/core/object.h>
23#include <rtems/rtems/options.h>
24#include <rtems/core/states.h>
25#include <rtems/rtems/support.h>
26#include <rtems/core/thread.h>
27#include <rtems/core/wkspace.h>
28#include <rtems/core/mpci.h>
29#include <rtems/sysstate.h>
30
31/*PAGE
32 *
33 *  _Message_queue_Manager_initialization
34 *
35 *  This routine initializes all message queue manager related
36 *  data structures.
37 *
38 *  Input parameters:
39 *    maximum_message_queues - number of message queues to initialize
40 *
41 *  Output parameters:  NONE
42 */
43
44void _Message_queue_Manager_initialization(
45  unsigned32 maximum_message_queues
46)
47{
48  _Objects_Initialize_information(
49    &_Message_queue_Information,
50    OBJECTS_RTEMS_MESSAGE_QUEUES,
51    TRUE,
52    maximum_message_queues,
53    sizeof( Message_queue_Control ),
54    FALSE,
55    RTEMS_MAXIMUM_NAME_LENGTH,
56    FALSE
57  );
58
59  /*
60   *  Register the MP Process Packet routine.
61   */
62
63  _MPCI_Register_packet_processor(
64    MP_PACKET_MESSAGE_QUEUE,
65    _Message_queue_MP_Process_packet
66  );
67
68}
69
70/*PAGE
71 *
72 *  _Message_queue_Allocate
73 *
74 *  Allocate a message queue and the space for its messages
75 */
76
77Message_queue_Control *_Message_queue_Allocate (
78  unsigned32          count,
79  unsigned32          max_message_size
80)
81{
82    Message_queue_Control *mq = 0;
83    unsigned32 message_buffering_required;
84    unsigned32 allocated_message_size;
85
86    mq =
87      (Message_queue_Control *)_Objects_Allocate(&_Message_queue_Information);
88
89    if (mq == 0)
90        goto failed;
91
92    mq->maximum_message_size = max_message_size;
93
94    /*
95     * round size up to multiple of a ptr for chain init
96     */
97   
98    allocated_message_size = max_message_size;
99    if (allocated_message_size & (sizeof(unsigned32) - 1)) {
100        allocated_message_size += sizeof(unsigned32);
101        allocated_message_size &= ~(sizeof(unsigned32) - 1);
102    }
103   
104    message_buffering_required =
105      count * (allocated_message_size + sizeof(Message_queue_Buffer_control));
106 
107    mq->message_buffers =
108      (Message_queue_Buffer *) _Workspace_Allocate(message_buffering_required);
109
110    if (mq->message_buffers == 0)
111        goto failed;
112 
113    _Chain_Initialize
114      (&mq->Inactive_messages,
115      mq->message_buffers,
116      count,
117      allocated_message_size + sizeof(Message_queue_Buffer_control)
118    );
119    return mq;
120
121failed:
122    if (mq)
123        _Message_queue_Free(mq);
124    return (Message_queue_Control *) 0;
125}
126
127/*PAGE
128 *
129 *  rtems_message_queue_create
130 *
131 *  This directive creates a message queue by allocating and initializing
132 *  a message queue data structure.
133 *
134 *  Input parameters:
135 *    name          - user defined queue name
136 *    count         - maximum message and reserved buffer count
137 *    max_message_size - maximum size of each message
138 *    attribute_set - process method
139 *    id            - pointer to queue
140 *
141 *  Output parameters:
142 *    id                - queue id
143 *    RTEMS_SUCCESSFUL - if successful
144 *    error code        - if unsuccessful
145 */
146
147rtems_status_code rtems_message_queue_create(
148  rtems_name          name,
149  unsigned32          count,
150  unsigned32          max_message_size,
151  rtems_attribute     attribute_set,
152  Objects_Id         *id
153)
154{
155  register Message_queue_Control *the_message_queue;
156
157  if ( !rtems_is_name_valid( name ) )
158    return RTEMS_INVALID_NAME;
159
160  if ( _Attributes_Is_global( attribute_set ) &&
161       !_System_state_Is_multiprocessing )
162    return RTEMS_MP_NOT_CONFIGURED;
163
164  if (count == 0)
165      return RTEMS_INVALID_NUMBER;
166
167  if (max_message_size == 0)
168      return RTEMS_INVALID_SIZE;
169
170#if 1
171  /*
172   * I am not 100% sure this should be an error.
173   * It seems reasonable to create a que with a large max size,
174   * and then just send smaller msgs from remote (or all) nodes.
175   */
176 
177  if ( _Attributes_Is_global( attribute_set ) &&
178       (_MPCI_table->maximum_packet_size < max_message_size))
179  {
180      return RTEMS_INVALID_SIZE;
181  }
182#endif
183       
184  _Thread_Disable_dispatch();              /* protects object pointer */
185
186  the_message_queue = _Message_queue_Allocate(count, max_message_size);
187
188  if ( !the_message_queue ) {
189    _Thread_Enable_dispatch();
190    return RTEMS_TOO_MANY;
191  }
192
193  if ( _Attributes_Is_global( attribute_set ) &&
194       !( _Objects_MP_Allocate_and_open( &_Message_queue_Information, name,
195                            the_message_queue->Object.id, FALSE ) ) ) {
196    _Message_queue_Free( the_message_queue );
197    _Thread_Enable_dispatch();
198    return RTEMS_TOO_MANY;
199  }
200
201  the_message_queue->maximum_pending_messages = count;
202
203  the_message_queue->attribute_set = attribute_set;
204  the_message_queue->number_of_pending_messages = 0;
205
206  _Chain_Initialize_empty( &the_message_queue->Pending_messages );
207
208  _Thread_queue_Initialize(
209    &the_message_queue->Wait_queue,
210    OBJECTS_RTEMS_MESSAGE_QUEUES,
211    _Attributes_Is_priority( attribute_set ) ?
212       THREAD_QUEUE_DISCIPLINE_PRIORITY : THREAD_QUEUE_DISCIPLINE_FIFO,
213    STATES_WAITING_FOR_MESSAGE,
214    _Message_queue_MP_Send_extract_proxy,
215    RTEMS_TIMEOUT
216  );
217
218  _Objects_Open(
219    &_Message_queue_Information,
220    &the_message_queue->Object,
221    &name
222  );
223
224  *id = the_message_queue->Object.id;
225
226  if ( _Attributes_Is_global( attribute_set ) )
227    _Message_queue_MP_Send_process_packet(
228      MESSAGE_QUEUE_MP_ANNOUNCE_CREATE,
229      the_message_queue->Object.id,
230      name,
231      0
232    );
233
234  _Thread_Enable_dispatch();
235  return RTEMS_SUCCESSFUL;
236}
237
238/*PAGE
239 *
240 *  rtems_message_queue_ident
241 *
242 *  This directive returns the system ID associated with
243 *  the message queue name.
244 *
245 *  Input parameters:
246 *    name - user defined message queue name
247 *    node - node(s) to be searched
248 *    id   - pointer to message queue id
249 *
250 *  Output parameters:
251 *    *id               - message queue id
252 *    RTEMS_SUCCESSFUL - if successful
253 *    error code        - if unsuccessful
254 */
255
256rtems_status_code rtems_message_queue_ident(
257  rtems_name    name,
258  unsigned32    node,
259  Objects_Id   *id
260)
261{
262  Objects_Name_to_id_errors  status;
263
264  status = _Objects_Name_to_id(
265    &_Message_queue_Information,
266    &name,
267    node,
268    id
269  );
270
271  return _Status_Object_name_errors_to_status[ status ];
272}
273
274/*PAGE
275 *
276 *  rtems_message_queue_delete
277 *
278 *  This directive allows a thread to delete the message queue specified
279 *  by the given queue identifier.
280 *
281 *  Input parameters:
282 *    id - queue id
283 *
284 *  Output parameters:
285 *    RTEMS_SUCCESSFUL - if successful
286 *    error code        - if unsuccessful
287 */
288
289rtems_status_code rtems_message_queue_delete(
290  Objects_Id id
291)
292{
293  register Message_queue_Control *the_message_queue;
294  Objects_Locations               location;
295
296  the_message_queue = _Message_queue_Get( id, &location );
297  switch ( location ) {
298    case OBJECTS_ERROR:
299      return RTEMS_INVALID_ID;
300    case OBJECTS_REMOTE:
301      _Thread_Dispatch();
302      return RTEMS_ILLEGAL_ON_REMOTE_OBJECT;
303    case OBJECTS_LOCAL:
304      _Objects_Close( &_Message_queue_Information,
305                      &the_message_queue->Object );
306
307      if ( the_message_queue->number_of_pending_messages != 0 )
308        (void) _Message_queue_Flush_support( the_message_queue );
309      else
310        _Thread_queue_Flush(
311          &the_message_queue->Wait_queue,
312          _Message_queue_MP_Send_object_was_deleted,
313          RTEMS_OBJECT_WAS_DELETED
314        );
315
316      _Message_queue_Free( the_message_queue );
317
318      if ( _Attributes_Is_global( the_message_queue->attribute_set ) ) {
319        _Objects_MP_Close(
320          &_Message_queue_Information,
321          the_message_queue->Object.id
322        );
323
324        _Message_queue_MP_Send_process_packet(
325          MESSAGE_QUEUE_MP_ANNOUNCE_DELETE,
326          the_message_queue->Object.id,
327          0,                                 /* Not used */
328          0
329        );
330      }
331
332      _Thread_Enable_dispatch();
333      return RTEMS_SUCCESSFUL;
334  }
335
336  return RTEMS_INTERNAL_ERROR;   /* unreached - only to remove warnings */
337}
338
339/*PAGE
340 *
341 *  rtems_message_queue_send
342 *
343 *  This routine implements the directives q_send.  It sends a
344 *  message to the specified message queue.
345 *
346 *  Input parameters:
347 *    id     - pointer to message queue
348 *    buffer - pointer to message buffer
349 *
350 *  Output parameters:
351 *    RTEMS_SUCCESSFUL - if successful
352 *    error code        - if unsuccessful
353 */
354
355rtems_status_code rtems_message_queue_send(
356  Objects_Id            id,
357  void                 *buffer,
358  unsigned32            size
359)
360{
361  return _Message_queue_Submit(id, buffer, size, MESSAGE_QUEUE_SEND_REQUEST);
362}
363
364/*PAGE
365 *
366 *  rtems_message_queue_urgent
367 *
368 *  This routine implements the directives q_urgent.  It urgents a
369 *  message to the specified message queue.
370 *
371 *  Input parameters:
372 *    id     - pointer to message queue
373 *    buffer - pointer to message buffer
374 *
375 *  Output parameters:
376 *    RTEMS_SUCCESSFUL - if successful
377 *    error code - if unsuccessful
378 */
379
380rtems_status_code rtems_message_queue_urgent(
381  Objects_Id            id,
382  void                 *buffer,
383  unsigned32            size
384)
385{
386  return _Message_queue_Submit(id, buffer, size, MESSAGE_QUEUE_URGENT_REQUEST);
387}
388
389/*PAGE
390 *
391 *  rtems_message_queue_broadcast
392 *
393 *  This directive sends a message for every thread waiting on the queue
394 *  designated by id.
395 *
396 *  Input parameters:
397 *    id     - pointer to message queue
398 *    buffer - pointer to message buffer
399 *    count  - pointer to area to store number of threads made ready
400 *
401 *  Output parameters:
402 *    count             - number of threads made ready
403 *    RTEMS_SUCCESSFUL - if successful
404 *    error code        - if unsuccessful
405 */
406
407rtems_status_code rtems_message_queue_broadcast(
408  Objects_Id            id,
409  void                 *buffer,
410  unsigned32            size,
411  unsigned32           *count
412)
413{
414  register Message_queue_Control *the_message_queue;
415  Objects_Locations               location;
416  Thread_Control                 *the_thread;
417  unsigned32                      number_broadcasted;
418
419  the_message_queue = _Message_queue_Get( id, &location );
420  switch ( location ) {
421    case OBJECTS_ERROR:
422      return RTEMS_INVALID_ID;
423    case OBJECTS_REMOTE:
424      _Thread_Executing->Wait.return_argument = count;
425
426      return
427        _Message_queue_MP_Send_request_packet(
428          MESSAGE_QUEUE_MP_BROADCAST_REQUEST,
429          id,
430          buffer,
431          &size,
432          0,                               /* option_set not used */
433          MPCI_DEFAULT_TIMEOUT
434        );
435
436    case OBJECTS_LOCAL:
437    {
438      Thread_Wait_information *waitp;
439      unsigned32 constrained_size;
440
441      number_broadcasted = 0;
442      while ( (the_thread =
443                 _Thread_queue_Dequeue(&the_message_queue->Wait_queue)) ) {
444        waitp = &the_thread->Wait;
445        number_broadcasted += 1;
446
447        constrained_size = size;
448        if (size > the_message_queue->maximum_message_size)
449            constrained_size = the_message_queue->maximum_message_size;
450
451        _Message_queue_Copy_buffer(buffer,
452                                   waitp->return_argument,
453                                   constrained_size);
454
455        *(rtems_unsigned32 *)the_thread->Wait.return_argument_1 = size;
456       
457        if ( !_Objects_Is_local_id( the_thread->Object.id ) ) {
458          the_thread->receive_packet->return_code = RTEMS_SUCCESSFUL;
459
460          _Message_queue_MP_Send_response_packet(
461            MESSAGE_QUEUE_MP_RECEIVE_RESPONSE,
462            id,
463            the_thread
464          );
465        }
466      }
467      _Thread_Enable_dispatch();
468      *count = number_broadcasted;
469      return RTEMS_SUCCESSFUL;
470    }
471
472    default:
473      return RTEMS_INTERNAL_ERROR;
474  }
475}
476
477/*PAGE
478 *
479 *  rtems_message_queue_receive
480 *
481 *  This directive dequeues a message from the designated message queue
482 *  and copies it into the requesting thread's buffer.
483 *
484 *  Input parameters:
485 *    id         - queue id
486 *    buffer     - pointer to message buffer
487 *    option_set - options on receive
488 *    timeout    - number of ticks to wait
489 *
490 *  Output parameters:
491 *    RTEMS_SUCCESSFUL - if successful
492 *    error code        - if unsuccessful
493 */
494
495rtems_status_code rtems_message_queue_receive(
496  Objects_Id            id,
497  void                 *buffer,
498  unsigned32           *size_p,
499  unsigned32            option_set,
500  rtems_interval        timeout
501)
502{
503  register Message_queue_Control *the_message_queue;
504  Objects_Locations               location;
505
506  the_message_queue = _Message_queue_Get( id, &location );
507  switch ( location ) {
508
509    case OBJECTS_ERROR:
510      return RTEMS_INVALID_ID;
511
512    case OBJECTS_REMOTE:
513      return _Message_queue_MP_Send_request_packet(
514          MESSAGE_QUEUE_MP_RECEIVE_REQUEST,
515          id,
516          buffer,
517          size_p,
518          option_set,
519          timeout
520        );
521
522    case OBJECTS_LOCAL:
523      if ( ! _Message_queue_Seize(the_message_queue,
524                                  option_set,
525                                  buffer,
526                                  size_p))
527      {
528        _Thread_queue_Enqueue( &the_message_queue->Wait_queue, timeout );
529      }
530      _Thread_Enable_dispatch();
531      return _Thread_Executing->Wait.return_code;
532  }
533
534  return RTEMS_INTERNAL_ERROR;   /* unreached - only to remove warnings */
535}
536
537/*PAGE
538 *
539 *  rtems_message_queue_flush
540 *
541 *  This directive removes all pending messages from a queue and returns
542 *  the number of messages removed.  If no messages were present then
543 *  a count of zero is returned.
544 *
545 *  Input parameters:
546 *    id    - queue id
547 *    count - return area for count
548 *
549 *  Output parameters:
550 *    count             - number of messages removed ( 0 = empty queue )
551 *    RTEMS_SUCCESSFUL - if successful
552 *    error code        - if unsuccessful
553 */
554
555rtems_status_code rtems_message_queue_flush(
556  Objects_Id  id,
557  unsigned32 *count
558)
559{
560  register Message_queue_Control *the_message_queue;
561  Objects_Locations               location;
562
563  the_message_queue = _Message_queue_Get( id, &location );
564  switch ( location ) {
565    case OBJECTS_ERROR:
566      return RTEMS_INVALID_ID;
567    case OBJECTS_REMOTE:
568      _Thread_Executing->Wait.return_argument = count;
569
570      return
571        _Message_queue_MP_Send_request_packet(
572          MESSAGE_QUEUE_MP_FLUSH_REQUEST,
573          id,
574          0,                               /* buffer not used */
575          0,                               /* size_p */
576          0,                               /* option_set not used */
577          MPCI_DEFAULT_TIMEOUT
578        );
579
580    case OBJECTS_LOCAL:
581      if ( the_message_queue->number_of_pending_messages != 0 )
582        *count = _Message_queue_Flush_support( the_message_queue );
583      else
584        *count = 0;
585      _Thread_Enable_dispatch();
586      return RTEMS_SUCCESSFUL;
587  }
588
589  return RTEMS_INTERNAL_ERROR;   /* unreached - only to remove warnings */
590}
591
592/*PAGE
593 *
594 *  _Message_queue_Seize
595 *
596 *  This kernel routine dequeues a message, copies the message buffer to
597 *  a given destination buffer, and frees the message buffer to the
598 *  inactive message pool.
599 *
600 *  Input parameters:
601 *    the_message_queue - pointer to message queue
602 *    option_set        - options on receive
603 *    the_buffer        - pointer to message buffer to be filled
604 *
605 *  Output parameters:
606 *    TRUE  - if message received or RTEMS_NO_WAIT and no message
607 *    FALSE - if thread is to block
608 *
609 *  NOTE: Dependent on BUFFER_LENGTH
610 *
611 *  INTERRUPT LATENCY:
612 *    available
613 *    wait
614 */
615
616boolean _Message_queue_Seize(
617  Message_queue_Control  *the_message_queue,
618  rtems_option            option_set,
619  void                   *buffer,
620  unsigned32             *size_p
621)
622{
623  ISR_Level                     level;
624  Message_queue_Buffer_control *the_message;
625  Thread_Control               *executing;
626
627  executing = _Thread_Executing;
628  executing->Wait.return_code = RTEMS_SUCCESSFUL;
629  _ISR_Disable( level );
630  if ( the_message_queue->number_of_pending_messages != 0 ) {
631    the_message_queue->number_of_pending_messages -= 1;
632
633    the_message = _Message_queue_Get_pending_message( the_message_queue );
634    _ISR_Enable( level );
635    *size_p = the_message->Contents.size;
636    _Message_queue_Copy_buffer( the_message->Contents.buffer, buffer, *size_p );
637    _Message_queue_Free_message_buffer(the_message_queue, the_message );
638    return( TRUE );
639  }
640
641  if ( _Options_Is_no_wait( option_set ) ) {
642    _ISR_Enable( level );
643    executing->Wait.return_code = RTEMS_UNSATISFIED;
644    return( TRUE );
645  }
646
647  the_message_queue->Wait_queue.sync = TRUE;
648  executing->Wait.queue              = &the_message_queue->Wait_queue;
649  executing->Wait.id                 = the_message_queue->Object.id;
650  executing->Wait.option             = option_set;
651  executing->Wait.return_argument    = (void *)buffer;
652  executing->Wait.return_argument_1  = (void *)size_p;
653  _ISR_Enable( level );
654  return FALSE;
655}
656
657/*PAGE
658 *
659 *  _Message_queue_Flush_support
660 *
661 *  This message manager routine removes all messages from a message queue
662 *  and returns them to the inactive message pool.
663 *
664 *  Input parameters:
665 *    the_message_queue - pointer to message queue
666 *
667 *  Output parameters:
668 *    returns - number of messages placed on inactive chain
669 *
670 *  INTERRUPT LATENCY:
671 *    only case
672 */
673
674unsigned32 _Message_queue_Flush_support(
675  Message_queue_Control *the_message_queue
676)
677{
678  ISR_Level   level;
679  Chain_Node *inactive_first;
680  Chain_Node *message_queue_first;
681  Chain_Node *message_queue_last;
682  unsigned32  count;
683
684  _ISR_Disable( level );
685    inactive_first      = the_message_queue->Inactive_messages.first;
686    message_queue_first = the_message_queue->Pending_messages.first;
687    message_queue_last  = the_message_queue->Pending_messages.last;
688
689    the_message_queue->Inactive_messages.first = message_queue_first;
690    message_queue_last->next = inactive_first;
691    inactive_first->previous = message_queue_last;
692    message_queue_first->previous          =
693               _Chain_Head( &the_message_queue->Inactive_messages );
694
695    _Chain_Initialize_empty( &the_message_queue->Pending_messages );
696
697    count = the_message_queue->number_of_pending_messages;
698    the_message_queue->number_of_pending_messages = 0;
699  _ISR_Enable( level );
700  return count;
701}
702
703/*PAGE
704 *
705 *  _Message_queue_Submit
706 *
707 *  This routine implements the directives q_send and q_urgent.  It
708 *  processes a message that is to be submitted to the designated
709 *  message queue.  The message will either be processed as a send
710 *  send message which it will be inserted at the rear of the queue
711 *  or it will be processed as an urgent message which will be inserted
712 *  at the front of the queue.
713 *
714 *  Input parameters:
715 *    id          - pointer to message queue
716 *    buffer      - pointer to message buffer
717 *    size        - size in bytes of message to send
718 *    submit_type - send or urgent message
719 *
720 *  Output parameters:
721 *    RTEMS_SUCCESSFUL - if successful
722 *    error code       - if unsuccessful
723 */
724
725rtems_status_code _Message_queue_Submit(
726  Objects_Id                  id,
727  void                       *buffer,
728  unsigned32                  size,
729  Message_queue_Submit_types  submit_type
730)
731{
732  register Message_queue_Control *the_message_queue;
733  Objects_Locations               location;
734  Thread_Control                 *the_thread;
735  Message_queue_Buffer_control   *the_message;
736
737  the_message_queue = _Message_queue_Get( id, &location );
738  switch ( location )
739  {
740    case OBJECTS_ERROR:
741      return RTEMS_INVALID_ID;
742
743    case OBJECTS_REMOTE:
744      switch ( submit_type ) {
745        case MESSAGE_QUEUE_SEND_REQUEST:
746          return
747            _Message_queue_MP_Send_request_packet(
748              MESSAGE_QUEUE_MP_SEND_REQUEST,
749              id,
750              buffer,
751              &size,
752              0,                               /* option_set */
753              MPCI_DEFAULT_TIMEOUT
754            );
755
756        case MESSAGE_QUEUE_URGENT_REQUEST:
757          return
758            _Message_queue_MP_Send_request_packet(
759              MESSAGE_QUEUE_MP_URGENT_REQUEST,
760              id,
761              buffer,
762              &size,
763              0,                               /* option_set */
764              MPCI_DEFAULT_TIMEOUT
765            );
766      }
767
768    case OBJECTS_LOCAL:
769      if (size > the_message_queue->maximum_message_size)
770      {
771          _Thread_Enable_dispatch();
772          return RTEMS_INVALID_SIZE;
773      }
774
775      /*
776       * Is there a thread currently waiting on this message queue?
777       */
778     
779      the_thread = _Thread_queue_Dequeue( &the_message_queue->Wait_queue );
780      if ( the_thread )
781      {
782        _Message_queue_Copy_buffer(
783          buffer,
784          the_thread->Wait.return_argument,
785          size
786        );
787        *(rtems_unsigned32 *)the_thread->Wait.return_argument_1 = size;
788       
789        if ( !_Objects_Is_local_id( the_thread->Object.id ) ) {
790          the_thread->receive_packet->return_code = RTEMS_SUCCESSFUL;
791
792          _Message_queue_MP_Send_response_packet(
793            MESSAGE_QUEUE_MP_RECEIVE_RESPONSE,
794            id,
795            the_thread
796          );
797
798        }
799        _Thread_Enable_dispatch();
800        return RTEMS_SUCCESSFUL;
801      }
802
803      /*
804       * No one waiting on this one currently.
805       * Allocate a message buffer and store it away
806       */
807
808      if ( the_message_queue->number_of_pending_messages ==
809           the_message_queue->maximum_pending_messages ) {
810        _Thread_Enable_dispatch();
811        return RTEMS_TOO_MANY;
812      }
813
814      the_message = _Message_queue_Allocate_message_buffer(the_message_queue);
815      if ( the_message == 0) {
816        _Thread_Enable_dispatch();
817        return RTEMS_UNSATISFIED;
818      }
819
820      _Message_queue_Copy_buffer( buffer, the_message->Contents.buffer, size );
821      the_message->Contents.size = size;
822     
823      the_message_queue->number_of_pending_messages += 1;
824
825      switch ( submit_type ) {
826        case MESSAGE_QUEUE_SEND_REQUEST:
827          _Message_queue_Append( the_message_queue, the_message );
828          break;
829        case MESSAGE_QUEUE_URGENT_REQUEST:
830          _Message_queue_Prepend( the_message_queue, the_message );
831          break;
832      }
833
834      _Thread_Enable_dispatch();
835      return RTEMS_SUCCESSFUL;
836         
837    default:
838      return RTEMS_INTERNAL_ERROR;       /* And they were such nice boys, too! */
839  }
840}
Note: See TracBrowser for help on using the repository browser.