Index: cpukit/score/include/rtems/score/schedulerimpl.h
===================================================================
--- cpukit/score/include/rtems/score/schedulerimpl.h	(revision 07a32d193257f150e5237970a7fa864ab71817b3)
+++ cpukit/score/include/rtems/score/schedulerimpl.h	(revision a7a8ec03258a7e59a300919485cbbd5f37782416)
@@ -22,4 +22,5 @@
 
 #include <rtems/score/scheduler.h>
+#include <rtems/score/assert.h>
 #include <rtems/score/cpusetimpl.h>
 #include <rtems/score/priorityimpl.h>
@@ -868,4 +869,9 @@
       [ the_thread->Scheduler.state ][ new_state ]
   );
+  _Assert(
+    _ISR_lock_Is_owner( &the_thread->Scheduler.Lock )
+      || the_thread->Scheduler.state == THREAD_SCHEDULER_BLOCKED
+      || !_System_state_Is_up( _System_state_Get() )
+  );
 
   the_thread->Scheduler.state = new_state;
@@ -984,16 +990,21 @@
 )
 {
-  Scheduler_Try_to_schedule_action action;
-  Thread_Control *owner;
-  Thread_Control *user;
+  ISR_lock_Context                  lock_context;
+  Scheduler_Try_to_schedule_action  action;
+  Thread_Control                   *owner;
+  Thread_Control                   *user;
 
   action = SCHEDULER_TRY_TO_SCHEDULE_DO_SCHEDULE;
+  user = _Scheduler_Node_get_user( node );
+
+  _Thread_Scheduler_acquire_critical( user, &lock_context );
 
   if ( node->help_state == SCHEDULER_HELP_YOURSELF ) {
+    _Scheduler_Thread_change_state( user, THREAD_SCHEDULER_SCHEDULED );
+    _Thread_Scheduler_release_critical( user, &lock_context );
     return action;
   }
 
   owner = _Scheduler_Node_get_owner( node );
-  user = _Scheduler_Node_get_user( node );
 
   if ( node->help_state == SCHEDULER_HELP_ACTIVE_RIVAL) {
@@ -1027,4 +1038,9 @@
   }
 
+  if ( action == SCHEDULER_TRY_TO_SCHEDULE_DO_SCHEDULE ) {
+    _Scheduler_Thread_change_state( user, THREAD_SCHEDULER_SCHEDULED );
+  }
+
+  _Thread_Scheduler_release_critical( user, &lock_context );
   return action;
 }
@@ -1098,8 +1114,11 @@
 )
 {
-  Thread_Control *old_user;
-  Thread_Control *new_user;
-
+  ISR_lock_Context  lock_context;
+  Thread_Control   *old_user;
+  Thread_Control   *new_user;
+
+  _Thread_Scheduler_acquire_critical( thread, &lock_context );
   _Scheduler_Thread_change_state( thread, THREAD_SCHEDULER_BLOCKED );
+  _Thread_Scheduler_release_critical( thread, &lock_context );
 
   if ( node->help_state == SCHEDULER_HELP_YOURSELF ) {
Index: cpukit/score/include/rtems/score/schedulersmpimpl.h
===================================================================
--- cpukit/score/include/rtems/score/schedulersmpimpl.h	(revision 07a32d193257f150e5237970a7fa864ab71817b3)
+++ cpukit/score/include/rtems/score/schedulersmpimpl.h	(revision a7a8ec03258a7e59a300919485cbbd5f37782416)
@@ -527,18 +527,40 @@
   Scheduler_Context                *context,
   Scheduler_Node                   *scheduled,
+  Thread_Control                   *victim_thread,
+  Scheduler_SMP_Allocate_processor  allocate_processor
+)
+{
+  Thread_Control *scheduled_thread = _Scheduler_Node_get_user( scheduled );
+
+  _Scheduler_SMP_Node_change_state( scheduled, SCHEDULER_SMP_NODE_SCHEDULED );
+
+  ( *allocate_processor )( context, scheduled_thread, victim_thread );
+}
+
+static inline Thread_Control *_Scheduler_SMP_Preempt(
+  Scheduler_Context                *context,
+  Scheduler_Node                   *scheduled,
   Scheduler_Node                   *victim,
   Scheduler_SMP_Allocate_processor  allocate_processor
 )
 {
-  Thread_Control *scheduled_thread = _Scheduler_Node_get_user( scheduled );
-  Thread_Control *victim_thread = _Scheduler_Node_get_user( victim );
-
-  _Scheduler_SMP_Node_change_state( scheduled, SCHEDULER_SMP_NODE_SCHEDULED );
-  _Scheduler_Thread_change_state(
-    scheduled_thread,
-    THREAD_SCHEDULER_SCHEDULED
+  Thread_Control   *victim_thread;
+  ISR_lock_Context  lock_context;
+
+  victim_thread = _Scheduler_Node_get_user( victim );
+  _Scheduler_SMP_Node_change_state( victim, SCHEDULER_SMP_NODE_READY );
+
+  _Thread_Scheduler_acquire_critical( victim_thread, &lock_context );
+  _Scheduler_Thread_change_state( victim_thread, THREAD_SCHEDULER_READY );
+  _Thread_Scheduler_release_critical( victim_thread, &lock_context );
+
+  _Scheduler_SMP_Allocate_processor(
+    context,
+    scheduled,
+    victim_thread,
+    allocate_processor
   );
 
-  ( *allocate_processor )( context, scheduled_thread, victim_thread );
+  return victim_thread;
 }
 
@@ -582,18 +604,8 @@
 
   if ( action == SCHEDULER_TRY_TO_SCHEDULE_DO_SCHEDULE ) {
-    Thread_Control *lowest_scheduled_user =
-      _Scheduler_Node_get_user( lowest_scheduled );
+    Thread_Control *lowest_scheduled_user;
     Thread_Control *idle;
 
-    _Scheduler_SMP_Node_change_state(
-      lowest_scheduled,
-      SCHEDULER_SMP_NODE_READY
-    );
-    _Scheduler_Thread_change_state(
-      lowest_scheduled_user,
-      THREAD_SCHEDULER_READY
-    );
-
-    _Scheduler_SMP_Allocate_processor(
+    lowest_scheduled_user = _Scheduler_SMP_Preempt(
       context,
       node,
@@ -749,11 +761,8 @@
 
     if ( action == SCHEDULER_TRY_TO_SCHEDULE_DO_SCHEDULE ) {
-      Thread_Control *user = _Scheduler_Node_get_user( node );
+      Thread_Control *user;
       Thread_Control *idle;
 
-      _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_READY );
-      _Scheduler_Thread_change_state( user, THREAD_SCHEDULER_READY );
-
-      _Scheduler_SMP_Allocate_processor(
+      user = _Scheduler_SMP_Preempt(
         context,
         highest_ready,
@@ -837,5 +846,5 @@
         context,
         highest_ready,
-        victim,
+        _Scheduler_Node_get_user( victim ),
         allocate_processor
       );
