diff options
Diffstat (limited to 'c')
-rw-r--r-- | c/src/exec/score/ChangeLog | 21 | ||||
-rw-r--r-- | c/src/exec/score/src/threaddispatch.c | 22 | ||||
-rw-r--r-- | c/src/exec/score/src/threadhandler.c | 11 |
3 files changed, 45 insertions, 9 deletions
diff --git a/c/src/exec/score/ChangeLog b/c/src/exec/score/ChangeLog index e84a79a7e1..64fd0a00d4 100644 --- a/c/src/exec/score/ChangeLog +++ b/c/src/exec/score/ChangeLog @@ -1,3 +1,24 @@ +2001-05-14 Till Straumann <strauman@slac.stanford.edu> + + * src/threaddispatch.c, src/threadhandler.c: Per PR211 fix + saving/restoring floating point context. The fpsave and fprestore + routines are only used in a executing context which _is_ fp and hence + has the FPU enabled. The current behavior required the FPU always to + be on which is very dangerous if lazy context switching is used. + [Joel Note: Some ports explicitly enabled the FPU in the FP save and + restore routines to avoid this.] + + The patch also makes sure (on powerpc only) that the FPU is disabled + for integer tasks. Note that this is crucial if deferred fp context + switching is used. Otherwise, fp context corruption may go undetected! + Also note that even tasks which merely push/pop FP registers to/from + the stack without modifying them still MUST be FP tasks - otherwise + (if lazy FP context switching is used), FP register corruption (of + other, FP, tasks may occur)! + + Furthermore, (on PPC) by default, lazy FP context save/restore + is _disabled_. + 2001-04-26 Joel Sherrill <joel@OARcorp.com> * src/objectcomparenamestring.c: Fix typos. diff --git a/c/src/exec/score/src/threaddispatch.c b/c/src/exec/score/src/threaddispatch.c index 66a8996a12..18953ae596 100644 --- a/c/src/exec/score/src/threaddispatch.c +++ b/c/src/exec/score/src/threaddispatch.c @@ -93,24 +93,28 @@ void _Thread_Dispatch( void ) */ #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE ) +#if ( CPU_USE_DEFERRED_FP_SWITCH != TRUE ) + if ( executing->fp_context != NULL ) + _Context_Save_fp( &executing->fp_context ); +#endif +#endif + + _Context_Switch( &executing->Registers, &heir->Registers ); + +#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE ) #if ( CPU_USE_DEFERRED_FP_SWITCH == TRUE ) - if ( (heir->fp_context != NULL) && !_Thread_Is_allocated_fp( heir ) ) { + if ( (executing->fp_context != NULL) && !_Thread_Is_allocated_fp( executing ) ) { if ( _Thread_Allocated_fp != NULL ) _Context_Save_fp( &_Thread_Allocated_fp->fp_context ); - _Context_Restore_fp( &heir->fp_context ); - _Thread_Allocated_fp = heir; + _Context_Restore_fp( &executing->fp_context ); + _Thread_Allocated_fp = executing; } #else if ( executing->fp_context != NULL ) - _Context_Save_fp( &executing->fp_context ); - - if ( heir->fp_context != NULL ) - _Context_Restore_fp( &heir->fp_context ); + _Context_Restore_fp( &executing->fp_context ); #endif #endif - _Context_Switch( &executing->Registers, &heir->Registers ); - executing = _Thread_Executing; _ISR_Disable( level ); diff --git a/c/src/exec/score/src/threadhandler.c b/c/src/exec/score/src/threadhandler.c index e23667c32f..ec09654c5a 100644 --- a/c/src/exec/score/src/threadhandler.c +++ b/c/src/exec/score/src/threadhandler.c @@ -78,6 +78,17 @@ void _Thread_Handler( void ) doneConstructors = 1; #endif +#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE ) +#if ( CPU_USE_DEFERRED_FP_SWITCH == TRUE ) + if ( (executing->fp_context != NULL) && !_Thread_Is_allocated_fp( executing ) ) { + if ( _Thread_Allocated_fp != NULL ) + _Context_Save_fp( &_Thread_Allocated_fp->fp_context ); + _Thread_Allocated_fp = executing; + } +#endif +#endif + + /* * Take care that 'begin' extensions get to complete before * 'switch' extensions can run. This means must keep dispatch |