source: rtems/c/src/exec/rtems/src/msg.c @ b06e68ef

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