source: rtems/cpukit/score/src/coremsginsert.c @ d349e8a4

4.115
Last change on this file since d349e8a4 was d349e8a4, checked in by Sebastian Huber <sebastian.huber@…>, on 04/21/15 at 07:21:29

score: Fix priority message queue insert

Move the linear search into a critical section to avoid corruption due
to higher priority interrupts. The interrupt disable time depends now
on the count of pending messages.

Close #2328.

  • Property mode set to 100644
File size: 2.6 KB
Line 
1/**
2 * @file
3 *
4 * @brief Insert a Message into the Message Queue
5 * @ingroup ScoreMessageQueue
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-2005.
10 *  On-Line Applications Research Corporation (OAR).
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *  http://www.rtems.org/license/LICENSE.
15 */
16
17#if HAVE_CONFIG_H
18#include "config.h"
19#endif
20
21#include <rtems/score/coremsgimpl.h>
22#include <rtems/score/isrlevel.h>
23
24#if defined(RTEMS_SCORE_COREMSG_ENABLE_MESSAGE_PRIORITY)
25static bool _CORE_message_queue_Order(
26  const Chain_Node *left,
27  const Chain_Node *right
28)
29{
30   const CORE_message_queue_Buffer_control *left_message;
31   const CORE_message_queue_Buffer_control *right_message;
32
33   left_message = (const CORE_message_queue_Buffer_control *) left;
34   right_message = (const CORE_message_queue_Buffer_control *) right;
35
36   return _CORE_message_queue_Get_message_priority( left_message ) <
37     _CORE_message_queue_Get_message_priority( right_message );
38}
39#endif
40
41void _CORE_message_queue_Insert_message(
42  CORE_message_queue_Control        *the_message_queue,
43  CORE_message_queue_Buffer_control *the_message,
44  CORE_message_queue_Submit_types    submit_type
45)
46{
47  Chain_Control *pending_messages;
48  ISR_Level      level;
49#if defined(RTEMS_SCORE_COREMSG_ENABLE_NOTIFICATION)
50  bool           notify;
51#endif
52
53  _CORE_message_queue_Set_message_priority( the_message, submit_type );
54  pending_messages = &the_message_queue->Pending_messages;
55
56  _ISR_Disable( level );
57
58#if defined(RTEMS_SCORE_COREMSG_ENABLE_NOTIFICATION)
59  notify = ( the_message_queue->number_of_pending_messages == 0 );
60#endif
61  ++the_message_queue->number_of_pending_messages;
62
63  if ( submit_type == CORE_MESSAGE_QUEUE_SEND_REQUEST ) {
64    _Chain_Append_unprotected( pending_messages, &the_message->Node );
65#if defined(RTEMS_SCORE_COREMSG_ENABLE_MESSAGE_PRIORITY)
66  } else  if ( submit_type != CORE_MESSAGE_QUEUE_URGENT_REQUEST ) {
67    _Chain_Insert_ordered_unprotected(
68      pending_messages,
69      &the_message->Node,
70      _CORE_message_queue_Order
71    );
72#endif
73  } else {
74    _Chain_Prepend_unprotected( pending_messages, &the_message->Node );
75  }
76
77  _ISR_Enable( level );
78
79  #if defined(RTEMS_SCORE_COREMSG_ENABLE_NOTIFICATION)
80    /*
81     *  According to POSIX, does this happen before or after the message
82     *  is actually enqueued.  It is logical to think afterwards, because
83     *  the message is actually in the queue at this point.
84     */
85    if ( notify && the_message_queue->notify_handler )
86      (*the_message_queue->notify_handler)(the_message_queue->notify_argument);
87  #endif
88}
Note: See TracBrowser for help on using the repository browser.