source: rtems/c/src/exec/rtems/src/msg.c @ 7f6a24ab

4.104.114.84.95
Last change on this file since 7f6a24ab was 7f6a24ab, checked in by Joel Sherrill <joel.sherrill@…>, on 08/28/95 at 15:30:29

Added unused priority ceiling parameter to rtems_semaphore_create.

Rearranged code to created thread handler routines to initialize,
start, restart, and "close/delete" a thread.

Made internal threads their own object class. This now uses the
thread support routines for starting and initializing a thread.

Insured deleted tasks are freed to the Inactive pool associated with the
correct Information block.

Added an RTEMS API specific data area to the thread control block.

Beginnings of removing the word "rtems" from the core.

  • Property mode set to 100644
File size: 22.0 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_Allocate_and_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(
199    &the_message_queue->Wait_queue,
200    OBJECTS_RTEMS_MESSAGE_QUEUES,
201    _Attributes_Is_priority( attribute_set ) ?
202       THREAD_QUEUE_DISCIPLINE_PRIORITY : THREAD_QUEUE_DISCIPLINE_FIFO,
203    STATES_WAITING_FOR_MESSAGE,
204    _Message_queue_MP_Send_extract_proxy
205  );
206
207  _Objects_Open(
208    &_Message_queue_Information,
209    &the_message_queue->Object,
210    &name
211  );
212
213  *id = the_message_queue->Object.id;
214
215  if ( _Attributes_Is_global( attribute_set ) )
216    _Message_queue_MP_Send_process_packet(
217      MESSAGE_QUEUE_MP_ANNOUNCE_CREATE,
218      the_message_queue->Object.id,
219      name,
220      0
221    );
222
223  _Thread_Enable_dispatch();
224  return( RTEMS_SUCCESSFUL );
225}
226
227/*PAGE
228 *
229 *  rtems_message_queue_ident
230 *
231 *  This directive returns the system ID associated with
232 *  the message queue name.
233 *
234 *  Input parameters:
235 *    name - user defined message queue name
236 *    node - node(s) to be searched
237 *    id   - pointer to message queue id
238 *
239 *  Output parameters:
240 *    *id               - message queue id
241 *    RTEMS_SUCCESSFUL - if successful
242 *    error code        - if unsuccessful
243 */
244
245rtems_status_code rtems_message_queue_ident(
246  rtems_name    name,
247  unsigned32    node,
248  Objects_Id   *id
249)
250{
251  return _Objects_Name_to_id(
252    &_Message_queue_Information,
253    &name,
254    node,
255    id
256  );
257}
258
259/*PAGE
260 *
261 *  rtems_message_queue_delete
262 *
263 *  This directive allows a thread to delete the message queue specified
264 *  by the given queue identifier.
265 *
266 *  Input parameters:
267 *    id - queue id
268 *
269 *  Output parameters:
270 *    RTEMS_SUCCESSFUL - if successful
271 *    error code        - if unsuccessful
272 */
273
274rtems_status_code rtems_message_queue_delete(
275  Objects_Id id
276)
277{
278  register Message_queue_Control *the_message_queue;
279  Objects_Locations               location;
280
281  the_message_queue = _Message_queue_Get( id, &location );
282  switch ( location ) {
283    case OBJECTS_ERROR:
284      return( RTEMS_INVALID_ID );
285    case OBJECTS_REMOTE:
286      _Thread_Dispatch();
287      return( RTEMS_ILLEGAL_ON_REMOTE_OBJECT );
288    case OBJECTS_LOCAL:
289      _Objects_Close( &_Message_queue_Information,
290                      &the_message_queue->Object );
291
292      if ( the_message_queue->number_of_pending_messages != 0 )
293        (void) _Message_queue_Flush_support( the_message_queue );
294      else
295        _Thread_queue_Flush(
296          &the_message_queue->Wait_queue,
297          _Message_queue_MP_Send_object_was_deleted
298        );
299
300      _Message_queue_Free( the_message_queue );
301
302      if ( _Attributes_Is_global( the_message_queue->attribute_set ) ) {
303        _Objects_MP_Close(
304          &_Message_queue_Information,
305          the_message_queue->Object.id
306        );
307
308        _Message_queue_MP_Send_process_packet(
309          MESSAGE_QUEUE_MP_ANNOUNCE_DELETE,
310          the_message_queue->Object.id,
311          0,                                 /* Not used */
312          0
313        );
314      }
315
316      _Thread_Enable_dispatch();
317      return( RTEMS_SUCCESSFUL );
318  }
319
320  return( RTEMS_INTERNAL_ERROR );   /* unreached - only to remove warnings */
321}
322
323/*PAGE
324 *
325 *  rtems_message_queue_send
326 *
327 *  This routine implements the directives q_send.  It sends a
328 *  message to the specified message queue.
329 *
330 *  Input parameters:
331 *    id     - pointer to message queue
332 *    buffer - pointer to message buffer
333 *
334 *  Output parameters:
335 *    RTEMS_SUCCESSFUL - if successful
336 *    error code        - if unsuccessful
337 */
338
339rtems_status_code rtems_message_queue_send(
340  Objects_Id            id,
341  void                 *buffer,
342  unsigned32            size
343)
344{
345  return _Message_queue_Submit(id, buffer, size, MESSAGE_QUEUE_SEND_REQUEST);
346}
347
348/*PAGE
349 *
350 *  rtems_message_queue_urgent
351 *
352 *  This routine implements the directives q_urgent.  It urgents a
353 *  message to the specified message queue.
354 *
355 *  Input parameters:
356 *    id     - pointer to message queue
357 *    buffer - pointer to message buffer
358 *
359 *  Output parameters:
360 *    RTEMS_SUCCESSFUL - if successful
361 *    error code - if unsuccessful
362 */
363
364rtems_status_code rtems_message_queue_urgent(
365  Objects_Id            id,
366  void                 *buffer,
367  unsigned32            size
368)
369{
370  return _Message_queue_Submit(id, buffer, size, MESSAGE_QUEUE_URGENT_REQUEST);
371}
372
373/*PAGE
374 *
375 *  rtems_message_queue_broadcast
376 *
377 *  This directive sends a message for every thread waiting on the queue
378 *  designated by id.
379 *
380 *  Input parameters:
381 *    id     - pointer to message queue
382 *    buffer - pointer to message buffer
383 *    count  - pointer to area to store number of threads made ready
384 *
385 *  Output parameters:
386 *    count             - number of threads made ready
387 *    RTEMS_SUCCESSFUL - if successful
388 *    error code        - if unsuccessful
389 */
390
391rtems_status_code rtems_message_queue_broadcast(
392  Objects_Id            id,
393  void                 *buffer,
394  unsigned32            size,
395  unsigned32           *count
396)
397{
398  register Message_queue_Control *the_message_queue;
399  Objects_Locations               location;
400  Thread_Control                 *the_thread;
401  unsigned32                      number_broadcasted;
402
403  the_message_queue = _Message_queue_Get( id, &location );
404  switch ( location ) {
405    case OBJECTS_ERROR:
406      return( RTEMS_INVALID_ID );
407    case OBJECTS_REMOTE:
408      _Thread_Executing->Wait.return_argument = count;
409
410      return
411        _Message_queue_MP_Send_request_packet(
412          MESSAGE_QUEUE_MP_BROADCAST_REQUEST,
413          id,
414          buffer,
415          &size,
416          0,                               /* option_set not used */
417          MPCI_DEFAULT_TIMEOUT
418        );
419
420    case OBJECTS_LOCAL:
421    {
422      Thread_Wait_information *waitp;
423      unsigned32 constrained_size;
424
425      number_broadcasted = 0;
426      while ( (the_thread =
427                 _Thread_queue_Dequeue(&the_message_queue->Wait_queue)) ) {
428        waitp = &the_thread->Wait;
429        number_broadcasted += 1;
430
431        constrained_size = size;
432        if (size > the_message_queue->maximum_message_size)
433            constrained_size = the_message_queue->maximum_message_size;
434
435        _Message_queue_Copy_buffer(buffer,
436                                   waitp->return_argument,
437                                   constrained_size);
438
439        *waitp->Extra.message_size_p = constrained_size;
440       
441        if ( !_Objects_Is_local_id( the_thread->Object.id ) ) {
442          the_thread->receive_packet->return_code = RTEMS_SUCCESSFUL;
443
444          _Message_queue_MP_Send_response_packet(
445            MESSAGE_QUEUE_MP_RECEIVE_RESPONSE,
446            id,
447            the_thread
448          );
449        }
450      }
451      _Thread_Enable_dispatch();
452      *count = number_broadcasted;
453      return( RTEMS_SUCCESSFUL );
454    }
455
456    default:
457      return RTEMS_INTERNAL_ERROR;
458  }
459}
460
461/*PAGE
462 *
463 *  rtems_message_queue_receive
464 *
465 *  This directive dequeues a message from the designated message queue
466 *  and copies it into the requesting thread's buffer.
467 *
468 *  Input parameters:
469 *    id         - queue id
470 *    buffer     - pointer to message buffer
471 *    option_set - options on receive
472 *    timeout    - number of ticks to wait
473 *
474 *  Output parameters:
475 *    RTEMS_SUCCESSFUL - if successful
476 *    error code        - if unsuccessful
477 */
478
479rtems_status_code rtems_message_queue_receive(
480  Objects_Id            id,
481  void                 *buffer,
482  unsigned32           *size_p,
483  unsigned32            option_set,
484  rtems_interval        timeout
485)
486{
487  register Message_queue_Control *the_message_queue;
488  Objects_Locations               location;
489
490  the_message_queue = _Message_queue_Get( id, &location );
491  switch ( location ) {
492
493    case OBJECTS_ERROR:
494      return( RTEMS_INVALID_ID );
495
496    case OBJECTS_REMOTE:
497      _Thread_Executing->Wait.return_argument = buffer;
498     
499      return _Message_queue_MP_Send_request_packet(
500          MESSAGE_QUEUE_MP_RECEIVE_REQUEST,
501          id,
502          buffer,
503          size_p,
504          option_set,
505          timeout
506        );
507
508    case OBJECTS_LOCAL:
509      if ( ! _Message_queue_Seize(the_message_queue,
510                                  option_set,
511                                  buffer,
512                                  size_p))
513      {
514        _Thread_queue_Enqueue( &the_message_queue->Wait_queue, timeout );
515      }
516      _Thread_Enable_dispatch();
517      return _Thread_Executing->Wait.return_code;
518  }
519
520  return( RTEMS_INTERNAL_ERROR );   /* unreached - only to remove warnings */
521}
522
523/*PAGE
524 *
525 *  rtems_message_queue_flush
526 *
527 *  This directive removes all pending messages from a queue and returns
528 *  the number of messages removed.  If no messages were present then
529 *  a count of zero is returned.
530 *
531 *  Input parameters:
532 *    id    - queue id
533 *    count - return area for count
534 *
535 *  Output parameters:
536 *    count             - number of messages removed ( 0 = empty queue )
537 *    RTEMS_SUCCESSFUL - if successful
538 *    error code        - if unsuccessful
539 */
540
541rtems_status_code rtems_message_queue_flush(
542  Objects_Id  id,
543  unsigned32 *count
544)
545{
546  register Message_queue_Control *the_message_queue;
547  Objects_Locations               location;
548
549  the_message_queue = _Message_queue_Get( id, &location );
550  switch ( location ) {
551    case OBJECTS_ERROR:
552      return( RTEMS_INVALID_ID );
553    case OBJECTS_REMOTE:
554      _Thread_Executing->Wait.return_argument = count;
555
556      return
557        _Message_queue_MP_Send_request_packet(
558          MESSAGE_QUEUE_MP_FLUSH_REQUEST,
559          id,
560          0,                               /* buffer not used */
561          0,                               /* size_p */
562          0,                               /* option_set not used */
563          MPCI_DEFAULT_TIMEOUT
564        );
565
566    case OBJECTS_LOCAL:
567      if ( the_message_queue->number_of_pending_messages != 0 )
568        *count = _Message_queue_Flush_support( the_message_queue );
569      else
570        *count = 0;
571      _Thread_Enable_dispatch();
572      return( RTEMS_SUCCESSFUL );
573  }
574
575  return( RTEMS_INTERNAL_ERROR );   /* unreached - only to remove warnings */
576}
577
578/*PAGE
579 *
580 *  _Message_queue_Seize
581 *
582 *  This kernel routine dequeues a message, copies the message buffer to
583 *  a given destination buffer, and frees the message buffer to the
584 *  inactive message pool.
585 *
586 *  Input parameters:
587 *    the_message_queue - pointer to message queue
588 *    option_set        - options on receive
589 *    the_buffer        - pointer to message buffer to be filled
590 *
591 *  Output parameters:
592 *    TRUE  - if message received or RTEMS_NO_WAIT and no message
593 *    FALSE - if thread is to block
594 *
595 *  NOTE: Dependent on BUFFER_LENGTH
596 *
597 *  INTERRUPT LATENCY:
598 *    available
599 *    wait
600 */
601
602boolean _Message_queue_Seize(
603  Message_queue_Control  *the_message_queue,
604  rtems_option            option_set,
605  void                   *buffer,
606  unsigned32             *size_p
607)
608{
609  ISR_Level                     level;
610  Message_queue_Buffer_control *the_message;
611  Thread_Control               *executing;
612
613  executing = _Thread_Executing;
614  executing->Wait.return_code = RTEMS_SUCCESSFUL;
615  _ISR_Disable( level );
616  if ( the_message_queue->number_of_pending_messages != 0 ) {
617    the_message_queue->number_of_pending_messages -= 1;
618
619    the_message = _Message_queue_Get_pending_message( the_message_queue );
620    _ISR_Enable( level );
621    *size_p = the_message->Contents.size;
622    _Message_queue_Copy_buffer( the_message->Contents.buffer, buffer, *size_p );
623    _Message_queue_Free_message_buffer(the_message_queue, the_message );
624    return( TRUE );
625  }
626
627  if ( _Options_Is_no_wait( option_set ) ) {
628    _ISR_Enable( level );
629    executing->Wait.return_code = RTEMS_UNSATISFIED;
630    return( TRUE );
631  }
632
633  the_message_queue->Wait_queue.sync = TRUE;
634  executing->Wait.queue              = &the_message_queue->Wait_queue;
635  executing->Wait.id                 = the_message_queue->Object.id;
636  executing->Wait.option_set         = option_set;
637  executing->Wait.return_argument    = (unsigned32 *)buffer;
638  executing->Wait.Extra.message_size_p = size_p;
639  _ISR_Enable( level );
640  return FALSE;
641}
642
643/*PAGE
644 *
645 *  _Message_queue_Flush_support
646 *
647 *  This message manager routine removes all messages from a message queue
648 *  and returns them to the inactive message pool.
649 *
650 *  Input parameters:
651 *    the_message_queue - pointer to message queue
652 *
653 *  Output parameters:
654 *    returns - number of messages placed on inactive chain
655 *
656 *  INTERRUPT LATENCY:
657 *    only case
658 */
659
660unsigned32 _Message_queue_Flush_support(
661  Message_queue_Control *the_message_queue
662)
663{
664  ISR_Level   level;
665  Chain_Node *inactive_first;
666  Chain_Node *message_queue_first;
667  Chain_Node *message_queue_last;
668  unsigned32  count;
669
670  _ISR_Disable( level );
671    inactive_first      = the_message_queue->Inactive_messages.first;
672    message_queue_first = the_message_queue->Pending_messages.first;
673    message_queue_last  = the_message_queue->Pending_messages.last;
674
675    the_message_queue->Inactive_messages.first = message_queue_first;
676    message_queue_last->next = inactive_first;
677    inactive_first->previous = message_queue_last;
678    message_queue_first->previous          =
679               _Chain_Head( &the_message_queue->Inactive_messages );
680
681    _Chain_Initialize_empty( &the_message_queue->Pending_messages );
682
683    count = the_message_queue->number_of_pending_messages;
684    the_message_queue->number_of_pending_messages = 0;
685  _ISR_Enable( level );
686  return count;
687}
688
689/*PAGE
690 *
691 *  _Message_queue_Submit
692 *
693 *  This routine implements the directives q_send and q_urgent.  It
694 *  processes a message that is to be submitted to the designated
695 *  message queue.  The message will either be processed as a send
696 *  send message which it will be inserted at the rear of the queue
697 *  or it will be processed as an urgent message which will be inserted
698 *  at the front of the queue.
699 *
700 *  Input parameters:
701 *    id          - pointer to message queue
702 *    buffer      - pointer to message buffer
703 *    size        - size in bytes of message to send
704 *    submit_type - send or urgent message
705 *
706 *  Output parameters:
707 *    RTEMS_SUCCESSFUL - if successful
708 *    error code       - if unsuccessful
709 */
710
711rtems_status_code _Message_queue_Submit(
712  Objects_Id                  id,
713  void                       *buffer,
714  unsigned32                  size,
715  Message_queue_Submit_types  submit_type
716)
717{
718  register Message_queue_Control *the_message_queue;
719  Objects_Locations               location;
720  Thread_Control                 *the_thread;
721  Message_queue_Buffer_control   *the_message;
722
723  the_message_queue = _Message_queue_Get( id, &location );
724  switch ( location )
725  {
726    case OBJECTS_ERROR:
727      return( RTEMS_INVALID_ID );
728
729    case OBJECTS_REMOTE:
730      switch ( submit_type ) {
731        case MESSAGE_QUEUE_SEND_REQUEST:
732          return
733            _Message_queue_MP_Send_request_packet(
734              MESSAGE_QUEUE_MP_SEND_REQUEST,
735              id,
736              buffer,
737              &size,
738              0,                               /* option_set */
739              MPCI_DEFAULT_TIMEOUT
740            );
741
742        case MESSAGE_QUEUE_URGENT_REQUEST:
743          return
744            _Message_queue_MP_Send_request_packet(
745              MESSAGE_QUEUE_MP_URGENT_REQUEST,
746              id,
747              buffer,
748              &size,
749              0,                               /* option_set */
750              MPCI_DEFAULT_TIMEOUT
751            );
752      }
753
754    case OBJECTS_LOCAL:
755      if (size > the_message_queue->maximum_message_size)
756      {
757          _Thread_Enable_dispatch();
758          return RTEMS_INVALID_SIZE;
759      }
760
761      /*
762       * Is there a thread currently waiting on this message queue?
763       */
764     
765      the_thread = _Thread_queue_Dequeue( &the_message_queue->Wait_queue );
766      if ( the_thread )
767      {
768        _Message_queue_Copy_buffer(
769          buffer,
770          the_thread->Wait.return_argument,
771          size
772        );
773        *the_thread->Wait.Extra.message_size_p = size;
774       
775        if ( !_Objects_Is_local_id( the_thread->Object.id ) ) {
776          the_thread->receive_packet->return_code = RTEMS_SUCCESSFUL;
777
778          _Message_queue_MP_Send_response_packet(
779            MESSAGE_QUEUE_MP_RECEIVE_RESPONSE,
780            id,
781            the_thread
782          );
783
784        }
785        _Thread_Enable_dispatch();
786        return( RTEMS_SUCCESSFUL );
787      }
788
789      /*
790       * No one waiting on this one currently.
791       * Allocate a message buffer and store it away
792       */
793
794      if ( the_message_queue->number_of_pending_messages ==
795           the_message_queue->maximum_pending_messages ) {
796        _Thread_Enable_dispatch();
797        return( RTEMS_TOO_MANY );
798      }
799
800      the_message = _Message_queue_Allocate_message_buffer(the_message_queue);
801      if ( the_message == 0) {
802        _Thread_Enable_dispatch();
803        return( RTEMS_UNSATISFIED );
804      }
805
806      _Message_queue_Copy_buffer( buffer, the_message->Contents.buffer, size );
807      the_message->Contents.size = size;
808     
809      the_message_queue->number_of_pending_messages += 1;
810
811      switch ( submit_type ) {
812        case MESSAGE_QUEUE_SEND_REQUEST:
813          _Message_queue_Append( the_message_queue, the_message );
814          break;
815        case MESSAGE_QUEUE_URGENT_REQUEST:
816          _Message_queue_Prepend( the_message_queue, the_message );
817          break;
818      }
819
820      _Thread_Enable_dispatch();
821      return( RTEMS_SUCCESSFUL );
822         
823    default:
824      return RTEMS_INTERNAL_ERROR;       /* And they were such nice boys, too! */
825  }
826}
Note: See TracBrowser for help on using the repository browser.