Index: cpukit/score/include/rtems/score/mrspimpl.h
===================================================================
--- cpukit/score/include/rtems/score/mrspimpl.h	(revision 40dcafaf80a29c20d74594853a8ff04441eabd9c)
+++ cpukit/score/include/rtems/score/mrspimpl.h	(revision 864d3475a5b6fa9f4c93ee68953074dabf5177b2)
@@ -37,10 +37,4 @@
  */
 
-#define MRSP_RIVAL_STATE_WAITING 0x0U
-
-#define MRSP_RIVAL_STATE_NEW_OWNER 0x1U
-
-#define MRSP_RIVAL_STATE_TIMEOUT 0x2U
-
 RTEMS_INLINE_ROUTINE void _MRSP_Elevate_priority(
   MRSP_Control     *mrsp,
@@ -53,7 +47,6 @@
 
 RTEMS_INLINE_ROUTINE void _MRSP_Restore_priority(
-  const MRSP_Control *mrsp,
-  Thread_Control     *thread,
-  Priority_Control    initial_priority
+  Thread_Control   *thread,
+  Priority_Control  initial_priority
 )
 {
@@ -135,12 +128,4 @@
 }
 
-RTEMS_INLINE_ROUTINE void _MRSP_Add_state(
-  MRSP_Rival   *rival,
-  unsigned int  state
-)
-{
-  _Atomic_Fetch_or_uint( &rival->state, state, ATOMIC_ORDER_RELEASE );
-}
-
 RTEMS_INLINE_ROUTINE void _MRSP_Timeout(
   Objects_Id  id,
@@ -149,8 +134,26 @@
 {
   MRSP_Rival *rival = arg;
+  Thread_Control *thread = rival->thread;
+  ISR_Level level;
 
   (void) id;
 
-  _MRSP_Add_state( rival, MRSP_RIVAL_STATE_TIMEOUT );
+  _ISR_Disable( level );
+
+  if ( rival->status == MRSP_WAIT_FOR_OWNERSHIP ) {
+    _Chain_Extract_unprotected( &rival->Node );
+
+    _ISR_Enable( level );
+
+    rival->status = MRSP_TIMEOUT;
+
+    _Resource_Node_extract( &thread->Resource_node );
+    _Resource_Node_set_dependency( &thread->Resource_node, NULL );
+    _Scheduler_Thread_change_help_state( thread, rival->initial_help_state );
+    _Scheduler_Thread_change_resource_root( thread, thread );
+    _MRSP_Restore_priority( thread, rival->initial_priority );
+  } else {
+    _ISR_Enable( level );
+  }
 }
 
@@ -166,17 +169,21 @@
   MRSP_Status status;
   MRSP_Rival rival;
-  bool previous_life_protection;
-  unsigned int state;
-  Scheduler_Help_state previous_help_state;
+  bool initial_life_protection;
+  ISR_Level level;
+
+  rival.thread = executing;
+  rival.initial_priority = initial_priority;
+  rival.initial_help_state =
+    _Scheduler_Thread_change_help_state( executing, SCHEDULER_HELP_ACTIVE_RIVAL );
+  rival.status = MRSP_WAIT_FOR_OWNERSHIP;
 
   _MRSP_Elevate_priority( mrsp, executing, ceiling_priority );
 
-  rival.thread = executing;
-  _Atomic_Init_uint( &rival.state, MRSP_RIVAL_STATE_WAITING );
+  _ISR_Disable( level );
   _Chain_Append_unprotected( &mrsp->Rivals, &rival.Node );
+  _ISR_Enable( level );
+
   _Resource_Add_rival( &mrsp->Resource, &executing->Resource_node );
   _Resource_Node_set_dependency( &executing->Resource_node, &mrsp->Resource );
-  previous_help_state =
-    _Scheduler_Thread_change_help_state( executing, SCHEDULER_HELP_ACTIVE_RIVAL );
 
   _Scheduler_Thread_change_resource_root(
@@ -195,37 +202,19 @@
   }
 
-  previous_life_protection = _Thread_Set_life_protection( true );
+  initial_life_protection = _Thread_Set_life_protection( true );
   _Thread_Enable_dispatch();
 
   _Assert( _Debug_Is_thread_dispatching_allowed() );
 
-  while (
-    _Atomic_Load_uint( &rival.state, ATOMIC_ORDER_ACQUIRE )
-      == MRSP_RIVAL_STATE_WAITING
-  ) {
-    /* Wait for state change */
-  }
+  /* Wait for state change */
+  do {
+    status = rival.status;
+  } while ( status == MRSP_WAIT_FOR_OWNERSHIP );
 
   _Thread_Disable_dispatch();
-  _Thread_Set_life_protection( previous_life_protection );
+  _Thread_Set_life_protection( initial_life_protection );
 
   if ( timeout > 0 ) {
     _Watchdog_Remove( &executing->Timer );
-  }
-
-  _Chain_Extract_unprotected( &rival.Node );
-  state = _Atomic_Load_uint( &rival.state, ATOMIC_ORDER_RELAXED );
-
-  if ( ( state & MRSP_RIVAL_STATE_NEW_OWNER ) != 0 ) {
-    mrsp->initial_priority_of_owner = initial_priority;
-    status = MRSP_SUCCESSFUL;
-  } else {
-    _Resource_Node_extract( &executing->Resource_node );
-    _Resource_Node_set_dependency( &executing->Resource_node, NULL );
-    _Scheduler_Thread_change_help_state( executing, previous_help_state );
-    _Scheduler_Thread_change_resource_root( executing, executing );
-    _MRSP_Restore_priority( mrsp, executing, initial_priority );
-
-    status = MRSP_TIMEOUT;
   }
 
@@ -290,4 +279,6 @@
 )
 {
+  ISR_Level level;
+
   if ( _Resource_Get_owner( &mrsp->Resource ) != &executing->Resource_node ) {
     return MRSP_NOT_OWNER_OF_RESOURCE;
@@ -304,12 +295,27 @@
 
   _Resource_Extract( &mrsp->Resource );
-  _MRSP_Restore_priority( mrsp, executing, mrsp->initial_priority_of_owner );
+  _MRSP_Restore_priority( executing, mrsp->initial_priority_of_owner );
+
+  _ISR_Disable( level );
 
   if ( _Chain_Is_empty( &mrsp->Rivals ) ) {
+    _ISR_Enable( level );
+
     _Resource_Set_owner( &mrsp->Resource, NULL );
   } else {
-    MRSP_Rival *rival = (MRSP_Rival *) _Chain_First( &mrsp->Rivals );
-    Thread_Control *new_owner = rival->thread;
-
+    MRSP_Rival *rival = (MRSP_Rival *)
+      _Chain_Get_first_unprotected( &mrsp->Rivals );
+    Thread_Control *new_owner;
+
+    /*
+     * This must be inside the critical section since the status prevents a
+     * potential double extraction in _MRSP_Timeout().
+     */
+    rival->status = MRSP_SUCCESSFUL;
+
+    _ISR_Enable( level );
+
+    new_owner = rival->thread;
+    mrsp->initial_priority_of_owner = rival->initial_priority;
     _Resource_Node_extract( &new_owner->Resource_node );
     _Resource_Node_set_dependency( &new_owner->Resource_node, NULL );
@@ -318,5 +324,4 @@
     _Scheduler_Thread_change_help_state( new_owner, SCHEDULER_HELP_ACTIVE_OWNER );
     _Scheduler_Thread_change_resource_root( new_owner, new_owner );
-    _MRSP_Add_state( rival, MRSP_RIVAL_STATE_NEW_OWNER );
   }
 
