source: rtems/cpukit/rtems/src/msg.c @ 5250ff39

4.104.114.84.95
Last change on this file since 5250ff39 was 5250ff39, checked in by Joel Sherrill <joel.sherrill@…>, on 08/23/95 at 21:06:31

Moved _Thread_Information -> _RTEMS_tasks_Information.

Added a table of object information control blocks.

Modified _Thread_Get so it looks up a thread regardless of which
thread management "entity" (manager, internal, etc) actually "owns" it.

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