Changeset a7a8ec03 in rtems


Ignore:
Timestamp:
Oct 12, 2016, 7:55:34 AM (3 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
master
Children:
edb020c
Parents:
07a32d19
git-author:
Sebastian Huber <sebastian.huber@…> (10/12/16 07:55:34)
git-committer:
Sebastian Huber <sebastian.huber@…> (11/02/16 09:05:42)
Message:

score: Protect thread scheduler state changes

Update #2556.

Location:
cpukit/score/include/rtems/score
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • cpukit/score/include/rtems/score/schedulerimpl.h

    r07a32d19 ra7a8ec03  
    2222
    2323#include <rtems/score/scheduler.h>
     24#include <rtems/score/assert.h>
    2425#include <rtems/score/cpusetimpl.h>
    2526#include <rtems/score/priorityimpl.h>
     
    868869      [ the_thread->Scheduler.state ][ new_state ]
    869870  );
     871  _Assert(
     872    _ISR_lock_Is_owner( &the_thread->Scheduler.Lock )
     873      || the_thread->Scheduler.state == THREAD_SCHEDULER_BLOCKED
     874      || !_System_state_Is_up( _System_state_Get() )
     875  );
    870876
    871877  the_thread->Scheduler.state = new_state;
     
    984990)
    985991{
    986   Scheduler_Try_to_schedule_action action;
    987   Thread_Control *owner;
    988   Thread_Control *user;
     992  ISR_lock_Context                  lock_context;
     993  Scheduler_Try_to_schedule_action  action;
     994  Thread_Control                   *owner;
     995  Thread_Control                   *user;
    989996
    990997  action = SCHEDULER_TRY_TO_SCHEDULE_DO_SCHEDULE;
     998  user = _Scheduler_Node_get_user( node );
     999
     1000  _Thread_Scheduler_acquire_critical( user, &lock_context );
    9911001
    9921002  if ( node->help_state == SCHEDULER_HELP_YOURSELF ) {
     1003    _Scheduler_Thread_change_state( user, THREAD_SCHEDULER_SCHEDULED );
     1004    _Thread_Scheduler_release_critical( user, &lock_context );
    9931005    return action;
    9941006  }
    9951007
    9961008  owner = _Scheduler_Node_get_owner( node );
    997   user = _Scheduler_Node_get_user( node );
    9981009
    9991010  if ( node->help_state == SCHEDULER_HELP_ACTIVE_RIVAL) {
     
    10271038  }
    10281039
     1040  if ( action == SCHEDULER_TRY_TO_SCHEDULE_DO_SCHEDULE ) {
     1041    _Scheduler_Thread_change_state( user, THREAD_SCHEDULER_SCHEDULED );
     1042  }
     1043
     1044  _Thread_Scheduler_release_critical( user, &lock_context );
    10291045  return action;
    10301046}
     
    10981114)
    10991115{
    1100   Thread_Control *old_user;
    1101   Thread_Control *new_user;
    1102 
     1116  ISR_lock_Context  lock_context;
     1117  Thread_Control   *old_user;
     1118  Thread_Control   *new_user;
     1119
     1120  _Thread_Scheduler_acquire_critical( thread, &lock_context );
    11031121  _Scheduler_Thread_change_state( thread, THREAD_SCHEDULER_BLOCKED );
     1122  _Thread_Scheduler_release_critical( thread, &lock_context );
    11041123
    11051124  if ( node->help_state == SCHEDULER_HELP_YOURSELF ) {
  • cpukit/score/include/rtems/score/schedulersmpimpl.h

    r07a32d19 ra7a8ec03  
    527527  Scheduler_Context                *context,
    528528  Scheduler_Node                   *scheduled,
     529  Thread_Control                   *victim_thread,
     530  Scheduler_SMP_Allocate_processor  allocate_processor
     531)
     532{
     533  Thread_Control *scheduled_thread = _Scheduler_Node_get_user( scheduled );
     534
     535  _Scheduler_SMP_Node_change_state( scheduled, SCHEDULER_SMP_NODE_SCHEDULED );
     536
     537  ( *allocate_processor )( context, scheduled_thread, victim_thread );
     538}
     539
     540static inline Thread_Control *_Scheduler_SMP_Preempt(
     541  Scheduler_Context                *context,
     542  Scheduler_Node                   *scheduled,
    529543  Scheduler_Node                   *victim,
    530544  Scheduler_SMP_Allocate_processor  allocate_processor
    531545)
    532546{
    533   Thread_Control *scheduled_thread = _Scheduler_Node_get_user( scheduled );
    534   Thread_Control *victim_thread = _Scheduler_Node_get_user( victim );
    535 
    536   _Scheduler_SMP_Node_change_state( scheduled, SCHEDULER_SMP_NODE_SCHEDULED );
    537   _Scheduler_Thread_change_state(
    538     scheduled_thread,
    539     THREAD_SCHEDULER_SCHEDULED
     547  Thread_Control   *victim_thread;
     548  ISR_lock_Context  lock_context;
     549
     550  victim_thread = _Scheduler_Node_get_user( victim );
     551  _Scheduler_SMP_Node_change_state( victim, SCHEDULER_SMP_NODE_READY );
     552
     553  _Thread_Scheduler_acquire_critical( victim_thread, &lock_context );
     554  _Scheduler_Thread_change_state( victim_thread, THREAD_SCHEDULER_READY );
     555  _Thread_Scheduler_release_critical( victim_thread, &lock_context );
     556
     557  _Scheduler_SMP_Allocate_processor(
     558    context,
     559    scheduled,
     560    victim_thread,
     561    allocate_processor
    540562  );
    541563
    542   ( *allocate_processor )( context, scheduled_thread, victim_thread );
     564  return victim_thread;
    543565}
    544566
     
    582604
    583605  if ( action == SCHEDULER_TRY_TO_SCHEDULE_DO_SCHEDULE ) {
    584     Thread_Control *lowest_scheduled_user =
    585       _Scheduler_Node_get_user( lowest_scheduled );
     606    Thread_Control *lowest_scheduled_user;
    586607    Thread_Control *idle;
    587608
    588     _Scheduler_SMP_Node_change_state(
    589       lowest_scheduled,
    590       SCHEDULER_SMP_NODE_READY
    591     );
    592     _Scheduler_Thread_change_state(
    593       lowest_scheduled_user,
    594       THREAD_SCHEDULER_READY
    595     );
    596 
    597     _Scheduler_SMP_Allocate_processor(
     609    lowest_scheduled_user = _Scheduler_SMP_Preempt(
    598610      context,
    599611      node,
     
    749761
    750762    if ( action == SCHEDULER_TRY_TO_SCHEDULE_DO_SCHEDULE ) {
    751       Thread_Control *user = _Scheduler_Node_get_user( node );
     763      Thread_Control *user;
    752764      Thread_Control *idle;
    753765
    754       _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_READY );
    755       _Scheduler_Thread_change_state( user, THREAD_SCHEDULER_READY );
    756 
    757       _Scheduler_SMP_Allocate_processor(
     766      user = _Scheduler_SMP_Preempt(
    758767        context,
    759768        highest_ready,
     
    837846        context,
    838847        highest_ready,
    839         victim,
     848        _Scheduler_Node_get_user( victim ),
    840849        allocate_processor
    841850      );
Note: See TracChangeset for help on using the changeset viewer.