source: rtems/cpukit/score/src/coremsgsubmit.c @ a85d8ec

4.104.114.84.95
Last change on this file since a85d8ec was 7d741413, checked in by Joel Sherrill <joel.sherrill@…>, on 08/16/01 at 19:35:08

2001-08-16 Joel Sherrill <joel@…>

  • include/rtems/score/coremsg.h, src/coremsgsubmit.c: Add a new return status to account for blocking sends. Otherwise, the caller will think that the returned message status will have the ultimate results of the operation. If the send times out, the final status will be in the return_code of the thread.
  • Property mode set to 100644
File size: 5.3 KB
Line 
1/*
2 *  CORE Message Queue Handler
3 *
4 *  DESCRIPTION:
5 *
6 *  This package is the implementation of the CORE Message Queue Handler.
7 *  This core object provides task synchronization and communication functions
8 *  via messages passed to queue objects.
9 *
10 *  COPYRIGHT (c) 1989-1999.
11 *  On-Line Applications Research Corporation (OAR).
12 *
13 *  The license and distribution terms for this file may be
14 *  found in the file LICENSE in this distribution or at
15 *  http://www.OARcorp.com/rtems/license.html.
16 *
17 *  $Id$
18 */
19
20#include <rtems/system.h>
21#include <rtems/score/chain.h>
22#include <rtems/score/isr.h>
23#include <rtems/score/object.h>
24#include <rtems/score/coremsg.h>
25#include <rtems/score/states.h>
26#include <rtems/score/thread.h>
27#include <rtems/score/wkspace.h>
28#if defined(RTEMS_MULTIPROCESSING)
29#include <rtems/score/mpci.h>
30#endif
31
32/*PAGE
33 *
34 *  _CORE_message_queue_Submit
35 *
36 *  This routine implements the send and urgent message functions. It
37 *  processes a message that is to be submitted to the designated
38 *  message queue.  The message will either be processed as a
39 *  send message which it will be inserted at the rear of the queue
40 *  or it will be processed as an urgent message which will be inserted
41 *  at the front of the queue.
42 *
43 *  Input parameters:
44 *    the_message_queue            - message is submitted to this message queue
45 *    buffer                       - pointer to message buffer
46 *    size                         - size in bytes of message to send
47 *    id                           - id of message queue
48 *    api_message_queue_mp_support - api specific mp support callout
49 *    submit_type                  - send or urgent message
50 *
51 *  Output parameters:
52 *    CORE_MESSAGE_QUEUE_SUCCESSFUL - if successful
53 *    error code                    - if unsuccessful
54 */
55
56CORE_message_queue_Status _CORE_message_queue_Submit(
57  CORE_message_queue_Control                *the_message_queue,
58  void                                      *buffer,
59  unsigned32                                 size,
60  Objects_Id                                 id,
61  CORE_message_queue_API_mp_support_callout  api_message_queue_mp_support,
62  CORE_message_queue_Submit_types            submit_type,
63  boolean                                    wait,
64  Watchdog_Interval                          timeout
65)
66{
67  ISR_Level                            level;
68  CORE_message_queue_Buffer_control   *the_message;
69  Thread_Control                      *the_thread;
70
71  if ( size > the_message_queue->maximum_message_size ) {
72    return CORE_MESSAGE_QUEUE_STATUS_INVALID_SIZE;
73  }
74
75  /*
76   *  Is there a thread currently waiting on this message queue?
77   */
78     
79  if ( the_message_queue->number_of_pending_messages == 0 ) {
80    the_thread = _Thread_queue_Dequeue( &the_message_queue->Wait_queue );
81    if ( the_thread ) {
82      _CORE_message_queue_Copy_buffer(
83        buffer,
84        the_thread->Wait.return_argument,
85        size
86      );
87      *(unsigned32 *)the_thread->Wait.return_argument_1 = size;
88      the_thread->Wait.count = submit_type;
89   
90#if defined(RTEMS_MULTIPROCESSING)
91      if ( !_Objects_Is_local_id( the_thread->Object.id ) )
92        (*api_message_queue_mp_support) ( the_thread, id );
93#endif
94      return CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
95    }
96  }
97
98  /*
99   *  No one waiting on the message queue at this time, so attempt to
100   *  queue the message up for a future receive.
101   */
102
103  if ( the_message_queue->number_of_pending_messages <
104       the_message_queue->maximum_pending_messages ) {
105
106    the_message =
107        _CORE_message_queue_Allocate_message_buffer( the_message_queue );
108
109    /*
110     *  NOTE: If the system is consistent, this error should never occur.
111     */
112
113    if ( !the_message ) {
114      return CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED;
115    }
116
117    _CORE_message_queue_Copy_buffer(
118      buffer,
119      the_message->Contents.buffer,
120      size
121    );
122    the_message->Contents.size = size;
123    the_message->priority  = submit_type;
124
125    _CORE_message_queue_Insert_message(
126       the_message_queue,
127       the_message,
128       submit_type
129    );
130    return CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
131  }
132
133  /*
134   *  No message buffers were available so we may need to return an
135   *  overflow error or block the sender until the message is placed
136   *  on the queue.
137   */
138
139  if ( !wait ) {
140    return CORE_MESSAGE_QUEUE_STATUS_TOO_MANY;
141  }
142
143  /*
144   *  Do NOT block on a send if the caller is in an ISR.  It is
145   *  deadly to block in an ISR.
146   */
147
148  if ( _ISR_Is_in_progress() ) {
149    return CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED;
150  }
151
152  /*
153   *  WARNING!! executing should NOT be used prior to this point.
154   *  Thus the unusual choice to open a new scope and declare
155   *  it as a variable.  Doing this emphasizes how dangerous it
156   *  would be to use this variable prior to here.
157   */
158
159  {
160    Thread_Control  *executing = _Thread_Executing;
161
162    _ISR_Disable( level );
163    _Thread_queue_Enter_critical_section( &the_message_queue->Wait_queue );
164    executing->Wait.queue              = &the_message_queue->Wait_queue;
165    executing->Wait.id                 = id;
166    executing->Wait.return_argument    = (void *)buffer;
167    executing->Wait.return_argument_1  = (void *)size;
168    executing->Wait.count              = submit_type;
169    _ISR_Enable( level );
170
171    _Thread_queue_Enqueue( &the_message_queue->Wait_queue, timeout );
172  }
173
174  return CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_WAIT;
175}
Note: See TracBrowser for help on using the repository browser.