[rtems commit] score: Fix priority message queue insert

Sebastian Huber sebh at rtems.org
Thu Apr 23 07:05:26 UTC 2015


Module:    rtems
Branch:    master
Commit:    d349e8a439d022bda3f9637fff013cfc8e55743d
Changeset: http://git.rtems.org/rtems/commit/?id=d349e8a439d022bda3f9637fff013cfc8e55743d

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Tue Apr 21 09:21:29 2015 +0200

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.

---

 cpukit/score/include/rtems/score/coremsgimpl.h |  32 +-------
 cpukit/score/src/coremsginsert.c               | 107 ++++++++++---------------
 2 files changed, 44 insertions(+), 95 deletions(-)

diff --git a/cpukit/score/include/rtems/score/coremsgimpl.h b/cpukit/score/include/rtems/score/coremsgimpl.h
index 52796ad..cedf276 100644
--- a/cpukit/score/include/rtems/score/coremsgimpl.h
+++ b/cpukit/score/include/rtems/score/coremsgimpl.h
@@ -443,7 +443,7 @@ RTEMS_INLINE_ROUTINE void _CORE_message_queue_Free_message_buffer (
  *       disabled if no API requires it.
  */
 RTEMS_INLINE_ROUTINE int _CORE_message_queue_Get_message_priority (
-  CORE_message_queue_Buffer_control *the_message
+  const CORE_message_queue_Buffer_control *the_message
 )
 {
   #if defined(RTEMS_SCORE_COREMSG_ENABLE_MESSAGE_PRIORITY)
@@ -494,36 +494,6 @@ RTEMS_INLINE_ROUTINE bool _CORE_message_queue_Is_priority(
     (the_attribute->discipline == CORE_MESSAGE_QUEUE_DISCIPLINES_PRIORITY);
 }
 
-/**
- * This routine places the_message at the rear of the outstanding
- * messages on the_message_queue.
- */
-RTEMS_INLINE_ROUTINE void _CORE_message_queue_Append_unprotected (
-  CORE_message_queue_Control        *the_message_queue,
-  CORE_message_queue_Buffer_control *the_message
-)
-{
-  _Chain_Append_unprotected(
-    &the_message_queue->Pending_messages,
-    &the_message->Node
-  );
-}
-
-/**
- * This routine places the_message at the front of the outstanding
- * messages on the_message_queue.
- */
-RTEMS_INLINE_ROUTINE void _CORE_message_queue_Prepend_unprotected (
-  CORE_message_queue_Control        *the_message_queue,
-  CORE_message_queue_Buffer_control *the_message
-)
-{
-  _Chain_Prepend_unprotected(
-    &the_message_queue->Pending_messages,
-    &the_message->Node
-  );
-}
-
 #if defined(RTEMS_SCORE_COREMSG_ENABLE_NOTIFICATION)
   /**
    * This function returns true if notification is enabled on this message
diff --git a/cpukit/score/src/coremsginsert.c b/cpukit/score/src/coremsginsert.c
index 2e42349..28407ba 100644
--- a/cpukit/score/src/coremsginsert.c
+++ b/cpukit/score/src/coremsginsert.c
@@ -18,12 +18,25 @@
 #include "config.h"
 #endif
 
-#include <rtems/system.h>
-#include <rtems/score/chain.h>
-#include <rtems/score/isr.h>
 #include <rtems/score/coremsgimpl.h>
-#include <rtems/score/thread.h>
-#include <rtems/score/wkspace.h>
+#include <rtems/score/isrlevel.h>
+
+#if defined(RTEMS_SCORE_COREMSG_ENABLE_MESSAGE_PRIORITY)
+static bool _CORE_message_queue_Order(
+  const Chain_Node *left,
+  const Chain_Node *right
+)
+{
+   const CORE_message_queue_Buffer_control *left_message;
+   const CORE_message_queue_Buffer_control *right_message;
+
+   left_message = (const CORE_message_queue_Buffer_control *) left;
+   right_message = (const CORE_message_queue_Buffer_control *) right;
+
+   return _CORE_message_queue_Get_message_priority( left_message ) <
+     _CORE_message_queue_Get_message_priority( right_message );
+}
+#endif
 
 void _CORE_message_queue_Insert_message(
   CORE_message_queue_Control        *the_message_queue,
@@ -31,71 +44,37 @@ void _CORE_message_queue_Insert_message(
   CORE_message_queue_Submit_types    submit_type
 )
 {
-  ISR_Level  level;
-  #if defined(RTEMS_SCORE_COREMSG_ENABLE_NOTIFICATION)
-    bool    notify = false;
-    #define SET_NOTIFY() \
-      do { \
-        if ( the_message_queue->number_of_pending_messages == 0 ) \
-          notify = true; \
-      } while (0)
-  #else
-    #define SET_NOTIFY()
-  #endif
+  Chain_Control *pending_messages;
+  ISR_Level      level;
+#if defined(RTEMS_SCORE_COREMSG_ENABLE_NOTIFICATION)
+  bool           notify;
+#endif
 
   _CORE_message_queue_Set_message_priority( the_message, submit_type );
+  pending_messages = &the_message_queue->Pending_messages;
 
-  #if !defined(RTEMS_SCORE_COREMSG_ENABLE_MESSAGE_PRIORITY)
-    _ISR_Disable( level );
-      SET_NOTIFY();
-      the_message_queue->number_of_pending_messages++;
-      if ( submit_type == CORE_MESSAGE_QUEUE_SEND_REQUEST )
-        _CORE_message_queue_Append_unprotected(the_message_queue, the_message);
-      else
-        _CORE_message_queue_Prepend_unprotected(the_message_queue, the_message);
-    _ISR_Enable( level );
-  #else
-    if ( submit_type == CORE_MESSAGE_QUEUE_SEND_REQUEST ) {
-      _ISR_Disable( level );
-        SET_NOTIFY();
-        the_message_queue->number_of_pending_messages++;
-        _CORE_message_queue_Append_unprotected(the_message_queue, the_message);
-      _ISR_Enable( level );
-    } else if ( submit_type == CORE_MESSAGE_QUEUE_URGENT_REQUEST ) {
-      _ISR_Disable( level );
-        SET_NOTIFY();
-        the_message_queue->number_of_pending_messages++;
-        _CORE_message_queue_Prepend_unprotected(the_message_queue, the_message);
-      _ISR_Enable( level );
-    } else {
-      CORE_message_queue_Buffer_control *this_message;
-      Chain_Node                        *the_node;
-      Chain_Control                     *the_header;
-      int                                the_priority;
-
-      the_priority = _CORE_message_queue_Get_message_priority(the_message);
-      the_header = &the_message_queue->Pending_messages;
-      the_node = _Chain_First( the_header );
-      while ( !_Chain_Is_tail( the_header, the_node ) ) {
-        int this_priority;
+  _ISR_Disable( level );
 
-        this_message = (CORE_message_queue_Buffer_control *) the_node;
+#if defined(RTEMS_SCORE_COREMSG_ENABLE_NOTIFICATION)
+  notify = ( the_message_queue->number_of_pending_messages == 0 );
+#endif
+  ++the_message_queue->number_of_pending_messages;
 
-        this_priority = _CORE_message_queue_Get_message_priority(this_message);
+  if ( submit_type == CORE_MESSAGE_QUEUE_SEND_REQUEST ) {
+    _Chain_Append_unprotected( pending_messages, &the_message->Node );
+#if defined(RTEMS_SCORE_COREMSG_ENABLE_MESSAGE_PRIORITY)
+  } else  if ( submit_type != CORE_MESSAGE_QUEUE_URGENT_REQUEST ) {
+    _Chain_Insert_ordered_unprotected(
+      pending_messages,
+      &the_message->Node,
+      _CORE_message_queue_Order
+    );
+#endif
+  } else {
+    _Chain_Prepend_unprotected( pending_messages, &the_message->Node );
+  }
 
-        if ( this_priority <= the_priority ) {
-          the_node = the_node->next;
-          continue;
-        }
-        break;
-      }
-      _ISR_Disable( level );
-        SET_NOTIFY();
-        the_message_queue->number_of_pending_messages++;
-        _Chain_Insert_unprotected( the_node->previous, &the_message->Node );
-      _ISR_Enable( level );
-    }
-  #endif
+  _ISR_Enable( level );
 
   #if defined(RTEMS_SCORE_COREMSG_ENABLE_NOTIFICATION)
     /*




More information about the vc mailing list