source: rtems/cpukit/score/src/coremsgsubmit.c @ 25f5730f

4.115
Last change on this file since 25f5730f was c499856, checked in by Chris Johns <chrisj@…>, on 03/20/14 at 21:10:47

Change all references of rtems.com to rtems.org.

  • Property mode set to 100644
File size: 4.2 KB
Line 
1/**
2 * @file
3 *
4 * @brief CORE Message Queue Submit
5 *
6 * @ingroup ScoreMessageQueue
7 */
8
9/*
10 *  COPYRIGHT (c) 1989-2009.
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.rtems.org/license/LICENSE.
16 */
17
18#if HAVE_CONFIG_H
19#include "config.h"
20#endif
21
22#include <rtems/score/coremsgimpl.h>
23#include <rtems/score/objectimpl.h>
24#include <rtems/score/isr.h>
25#include <rtems/score/wkspace.h>
26
27CORE_message_queue_Status _CORE_message_queue_Submit(
28  CORE_message_queue_Control                *the_message_queue,
29  Thread_Control                            *executing,
30  const void                                *buffer,
31  size_t                                     size,
32  Objects_Id                                 id,
33  #if defined(RTEMS_MULTIPROCESSING)
34    CORE_message_queue_API_mp_support_callout  api_message_queue_mp_support,
35  #else
36    CORE_message_queue_API_mp_support_callout  api_message_queue_mp_support  __attribute__((unused)),
37  #endif
38  CORE_message_queue_Submit_types            submit_type,
39  bool                                       wait,
40  Watchdog_Interval                          timeout
41)
42{
43  CORE_message_queue_Buffer_control   *the_message;
44  Thread_Control                      *the_thread;
45
46  if ( size > the_message_queue->maximum_message_size ) {
47    return CORE_MESSAGE_QUEUE_STATUS_INVALID_SIZE;
48  }
49
50  /*
51   *  Is there a thread currently waiting on this message queue?
52   */
53  if ( the_message_queue->number_of_pending_messages == 0 ) {
54    the_thread = _Thread_queue_Dequeue( &the_message_queue->Wait_queue );
55    if ( the_thread ) {
56      _CORE_message_queue_Copy_buffer(
57        buffer,
58        the_thread->Wait.return_argument_second.mutable_object,
59        size
60      );
61      *(size_t *) the_thread->Wait.return_argument = size;
62      the_thread->Wait.count = (uint32_t) submit_type;
63
64      #if defined(RTEMS_MULTIPROCESSING)
65        if ( !_Objects_Is_local_id( the_thread->Object.id ) )
66          (*api_message_queue_mp_support) ( the_thread, id );
67      #endif
68      return CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
69    }
70  }
71
72  /*
73   *  No one waiting on the message queue at this time, so attempt to
74   *  queue the message up for a future receive.
75   */
76  the_message =
77      _CORE_message_queue_Allocate_message_buffer( the_message_queue );
78  if ( the_message ) {
79    _CORE_message_queue_Copy_buffer(
80      buffer,
81      the_message->Contents.buffer,
82      size
83    );
84    the_message->Contents.size = size;
85    _CORE_message_queue_Set_message_priority( the_message, submit_type );
86
87    _CORE_message_queue_Insert_message(
88       the_message_queue,
89       the_message,
90       submit_type
91    );
92    return CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
93  }
94
95  #if !defined(RTEMS_SCORE_COREMSG_ENABLE_BLOCKING_SEND)
96    return CORE_MESSAGE_QUEUE_STATUS_TOO_MANY;
97  #else
98    /*
99     *  No message buffers were available so we may need to return an
100     *  overflow error or block the sender until the message is placed
101     *  on the queue.
102     */
103    if ( !wait ) {
104      return CORE_MESSAGE_QUEUE_STATUS_TOO_MANY;
105    }
106
107    /*
108     *  Do NOT block on a send if the caller is in an ISR.  It is
109     *  deadly to block in an ISR.
110     */
111    if ( _ISR_Is_in_progress() ) {
112      return CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED;
113    }
114
115    /*
116     *  WARNING!! executing should NOT be used prior to this point.
117     *  Thus the unusual choice to open a new scope and declare
118     *  it as a variable.  Doing this emphasizes how dangerous it
119     *  would be to use this variable prior to here.
120     */
121    {
122      ISR_Level        level;
123
124      _ISR_Disable( level );
125      _Thread_queue_Enter_critical_section( &the_message_queue->Wait_queue );
126      executing->Wait.queue = &the_message_queue->Wait_queue;
127      executing->Wait.id = id;
128      executing->Wait.return_argument_second.immutable_object = buffer;
129      executing->Wait.option = (uint32_t) size;
130      executing->Wait.count = submit_type;
131      _ISR_Enable( level );
132
133      _Thread_queue_Enqueue(
134        &the_message_queue->Wait_queue,
135        executing,
136        timeout
137      );
138    }
139
140    return CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_WAIT;
141  #endif
142}
Note: See TracBrowser for help on using the repository browser.