Changeset 8d6e6eeb in rtems


Ignore:
Timestamp:
02/17/15 09:00:43 (9 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
4.11, 5, master
Children:
7fcb71a
Parents:
c34f94f7
git-author:
Sebastian Huber <sebastian.huber@…> (02/17/15 09:00:43)
git-committer:
Sebastian Huber <sebastian.huber@…> (02/17/15 12:42:53)
Message:

score: Fix FP context restore via _Thread_Handler

After a context switch we end up in the second part of
_Thread_Dispatch() or in _Thread_Handler() in case of new threads. Use
the same function _Thread_Restore_fp() to restore the floating-point
context. It makes no sense to do this in _Thread_Start_multitasking().
This fixes also a race condition in SMP configurations.

Update #2268.

Location:
cpukit/score
Files:
4 edited

Legend:

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

    rc34f94f7 r8d6e6eeb  
    588588#endif
    589589
     590/*
     591 *  If the CPU has hardware floating point, then we must address saving
     592 *  and restoring it as part of the context switch.
     593 *
     594 *  The second conditional compilation section selects the algorithm used
     595 *  to context switch between floating point tasks.  The deferred algorithm
     596 *  can be significantly better in a system with few floating point tasks
     597 *  because it reduces the total number of save and restore FP context
     598 *  operations.  However, this algorithm can not be used on all CPUs due
     599 *  to unpredictable use of FP registers by some compilers for integer
     600 *  operations.
     601 */
     602
     603RTEMS_INLINE_ROUTINE void _Thread_Save_fp( Thread_Control *executing )
     604{
     605#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
     606#if ( CPU_USE_DEFERRED_FP_SWITCH != TRUE )
     607  if ( executing->fp_context != NULL )
     608    _Context_Save_fp( &executing->fp_context );
     609#endif
     610#endif
     611}
     612
     613RTEMS_INLINE_ROUTINE void _Thread_Restore_fp( Thread_Control *executing )
     614{
     615#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
     616#if ( CPU_USE_DEFERRED_FP_SWITCH == TRUE )
     617  if ( (executing->fp_context != NULL) &&
     618       !_Thread_Is_allocated_fp( executing ) ) {
     619    if ( _Thread_Allocated_fp != NULL )
     620      _Context_Save_fp( &_Thread_Allocated_fp->fp_context );
     621    _Context_Restore_fp( &executing->fp_context );
     622    _Thread_Allocated_fp = executing;
     623  }
     624#else
     625  if ( executing->fp_context != NULL )
     626    _Context_Restore_fp( &executing->fp_context );
     627#endif
     628#endif
     629}
     630
    590631/**
    591632 * This routine is invoked when the currently loaded floating
  • cpukit/score/src/threaddispatch.c

    rc34f94f7 r8d6e6eeb  
    143143
    144144    _User_extensions_Thread_switch( executing, heir );
    145 
    146     /*
    147      *  If the CPU has hardware floating point, then we must address saving
    148      *  and restoring it as part of the context switch.
    149      *
    150      *  The second conditional compilation section selects the algorithm used
    151      *  to context switch between floating point tasks.  The deferred algorithm
    152      *  can be significantly better in a system with few floating point tasks
    153      *  because it reduces the total number of save and restore FP context
    154      *  operations.  However, this algorithm can not be used on all CPUs due
    155      *  to unpredictable use of FP registers by some compilers for integer
    156      *  operations.
    157      */
    158 
    159 #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
    160 #if ( CPU_USE_DEFERRED_FP_SWITCH != TRUE )
    161     if ( executing->fp_context != NULL )
    162       _Context_Save_fp( &executing->fp_context );
    163 #endif
    164 #endif
    165 
     145    _Thread_Save_fp( executing );
    166146    _Context_Switch( &executing->Registers, &heir->Registers );
    167 
    168 #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
    169 #if ( CPU_USE_DEFERRED_FP_SWITCH == TRUE )
    170     if ( (executing->fp_context != NULL) &&
    171          !_Thread_Is_allocated_fp( executing ) ) {
    172       if ( _Thread_Allocated_fp != NULL )
    173         _Context_Save_fp( &_Thread_Allocated_fp->fp_context );
    174       _Context_Restore_fp( &executing->fp_context );
    175       _Thread_Allocated_fp = executing;
    176     }
    177 #else
    178     if ( executing->fp_context != NULL )
    179       _Context_Restore_fp( &executing->fp_context );
    180 #endif
    181 #endif
     147    _Thread_Restore_fp( executing );
    182148
    183149    /*
  • cpukit/score/src/threadhandler.c

    rc34f94f7 r8d6e6eeb  
    5252   * code path for performing the FP context switch is not hit.
    5353   */
    54   #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
    55     #if ( CPU_USE_DEFERRED_FP_SWITCH == TRUE )
    56       if ( (executing->fp_context != NULL) &&
    57             !_Thread_Is_allocated_fp( executing ) ) {
    58         if ( _Thread_Allocated_fp != NULL )
    59           _Context_Save_fp( &_Thread_Allocated_fp->fp_context );
    60         _Thread_Allocated_fp = executing;
    61       }
    62     #endif
    63   #endif
     54  _Thread_Restore_fp( executing );
    6455
    6556  /*
  • cpukit/score/src/threadstartmultitasking.c

    rc34f94f7 r8d6e6eeb  
    3838  heir = _Thread_Get_heir_and_make_it_executing( cpu_self );
    3939
    40    /*
    41     * Get the init task(s) running.
    42     *
    43     * Note: Thread_Dispatch() is normally used to dispatch threads.  As
    44     *       part of its work, Thread_Dispatch() restores floating point
    45     *       state for the heir task.
    46     *
    47     *       This code avoids Thread_Dispatch(), and so we have to restore
    48     *       (actually initialize) the floating point state "by hand".
    49     *
    50     *       Ignore the CPU_USE_DEFERRED_FP_SWITCH because we must always
    51     *       switch in the first thread if it is FP.
    52     */
    53 #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
    54    /*
    55     *  don't need to worry about saving BSP's floating point state
    56     */
    57 
    58    if ( heir->fp_context != NULL )
    59      _Context_Restore_fp( &heir->fp_context );
    60 #endif
    61 
    6240  _Profiling_Thread_dispatch_disable( cpu_self, 0 );
    6341
Note: See TracChangeset for help on using the changeset viewer.