source: rtems/cpukit/score/src/coremsgsubmit.c @ 88e09b98

5
Last change on this file since 88e09b98 was 88e09b98, checked in by Sebastian Huber <sebastian.huber@…>, on 04/29/16 at 08:41:36

score: _CORE_message_queue_Insert_message()

Move common code into _CORE_message_queue_Insert_message().

  • Property mode set to 100644
File size: 3.7 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/statesimpl.h>
26#include <rtems/score/wkspace.h>
27
28CORE_message_queue_Status _CORE_message_queue_Do_submit(
29  CORE_message_queue_Control       *the_message_queue,
30  Thread_Control                   *executing,
31  const void                       *buffer,
32  size_t                            size,
33#if defined(RTEMS_MULTIPROCESSING)
34  Thread_queue_MP_callout           mp_callout,
35  Objects_Id                        mp_id,
36#endif
37  CORE_message_queue_Submit_types   submit_type,
38  bool                              wait,
39  Watchdog_Interval                 timeout,
40  ISR_lock_Context                 *lock_context
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    _CORE_message_queue_Release( the_message_queue, lock_context );
48    return CORE_MESSAGE_QUEUE_STATUS_INVALID_SIZE;
49  }
50
51  /*
52   *  Is there a thread currently waiting on this message queue?
53   */
54
55  the_thread = _CORE_message_queue_Dequeue_receiver(
56    the_message_queue,
57    buffer,
58    size,
59    mp_callout,
60    mp_id,
61    submit_type,
62    lock_context
63  );
64  if ( the_thread != NULL ) {
65    return CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
66  }
67
68  /*
69   *  No one waiting on the message queue at this time, so attempt to
70   *  queue the message up for a future receive.
71   */
72  the_message =
73      _CORE_message_queue_Allocate_message_buffer( the_message_queue );
74  if ( the_message ) {
75    _CORE_message_queue_Insert_message(
76      the_message_queue,
77      the_message,
78      buffer,
79      size,
80      submit_type
81    );
82    _CORE_message_queue_Release( the_message_queue, lock_context );
83    return CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
84  }
85
86  #if !defined(RTEMS_SCORE_COREMSG_ENABLE_BLOCKING_SEND)
87    _CORE_message_queue_Release( the_message_queue, lock_context );
88    return CORE_MESSAGE_QUEUE_STATUS_TOO_MANY;
89  #else
90    /*
91     *  No message buffers were available so we may need to return an
92     *  overflow error or block the sender until the message is placed
93     *  on the queue.
94     */
95    if ( !wait ) {
96      _CORE_message_queue_Release( the_message_queue, lock_context );
97      return CORE_MESSAGE_QUEUE_STATUS_TOO_MANY;
98    }
99
100    /*
101     *  Do NOT block on a send if the caller is in an ISR.  It is
102     *  deadly to block in an ISR.
103     */
104    if ( _ISR_Is_in_progress() ) {
105      _CORE_message_queue_Release( the_message_queue, lock_context );
106      return CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED;
107    }
108
109    /*
110     *  WARNING!! executing should NOT be used prior to this point.
111     *  Thus the unusual choice to open a new scope and declare
112     *  it as a variable.  Doing this emphasizes how dangerous it
113     *  would be to use this variable prior to here.
114     */
115    executing->Wait.return_argument_second.immutable_object = buffer;
116    executing->Wait.option = (uint32_t) size;
117    executing->Wait.count = submit_type;
118
119    _Thread_queue_Enqueue_critical(
120      &the_message_queue->Wait_queue.Queue,
121      the_message_queue->operations,
122      executing,
123      STATES_WAITING_FOR_MESSAGE,
124      timeout,
125      CORE_MESSAGE_QUEUE_STATUS_TIMEOUT,
126      lock_context
127    );
128    return CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_WAIT;
129  #endif
130}
Note: See TracBrowser for help on using the repository browser.