mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-19 21:11:57 -04:00
Add support for newlib dynamic reentrancy (#496)
Previously, newlib's _impure_ptr was updated on every context switch to point to the current task's _reent structure. However, this behavior is no longer valid on multi-core systems due to the fact that multiple cores can switch contexts at the same time, thus leading to the corruption of the _impure_ptr. However, Newlib can be compiled with __DYNAMIC_REENT__ enabled which will cause newlib functions to call __getreent() instead in order to obtain the required reent struct. This commit adds dynamic reentrancy support to FreeRTOS: - Added a configNEWLIB_REENTRANT_IS_DYNAMIC to enable dynamic reentrancy support - _impure_ptr is no longer updated with reentrancy is dynamic - Port must provide their own __getreent() that returns the current task's reent struct
This commit is contained in:
parent
a97741a08d
commit
34b8e24d7c
|
@ -72,6 +72,14 @@
|
||||||
#include <reent.h>
|
#include <reent.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef configNEWLIB_REENTRANT_IS_DYNAMIC
|
||||||
|
#if ( configUSE_NEWLIB_REENTRANT != 1 )
|
||||||
|
#error configUSE_NEWLIB_REENTRANT must be defined to 1 to enable configNEWLIB_REENTRANT_IS_DYNAMIC
|
||||||
|
#endif
|
||||||
|
#else /* configNEWLIB_REENTRANT_IS_DYNAMIC */
|
||||||
|
#define configNEWLIB_REENTRANT_IS_DYNAMIC 0
|
||||||
|
#endif /* configNEWLIB_REENTRANT_IS_DYNAMIC */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check all the required application specific macros have been defined.
|
* Check all the required application specific macros have been defined.
|
||||||
* These macros are application specific and (as downloaded) are defined
|
* These macros are application specific and (as downloaded) are defined
|
||||||
|
|
18
tasks.c
18
tasks.c
|
@ -2854,15 +2854,18 @@ void vTaskStartScheduler( void )
|
||||||
* starts to run. */
|
* starts to run. */
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
|
|
||||||
#if ( configUSE_NEWLIB_REENTRANT == 1 )
|
#if ( ( configUSE_NEWLIB_REENTRANT == 1 ) && ( configNEWLIB_REENTRANT_IS_DYNAMIC == 0 ) )
|
||||||
{
|
{
|
||||||
/* Switch Newlib's _impure_ptr variable to point to the _reent
|
/* Switch Newlib's _impure_ptr variable to point to the _reent
|
||||||
* structure specific to the task that will run first.
|
* structure specific to the task that will run first.
|
||||||
* See the third party link http://www.nadler.com/embedded/newlibAndFreeRTOS.html
|
* See the third party link http://www.nadler.com/embedded/newlibAndFreeRTOS.html
|
||||||
* for additional information. */
|
* for additional information.
|
||||||
|
*
|
||||||
|
* Note: Updating the _impure_ptr is not required when Newlib is compiled with
|
||||||
|
* __DYNAMIC_REENT__ enabled. The port should provide __getreent() instead. */
|
||||||
_impure_ptr = &( pxCurrentTCB->xNewLib_reent );
|
_impure_ptr = &( pxCurrentTCB->xNewLib_reent );
|
||||||
}
|
}
|
||||||
#endif /* configUSE_NEWLIB_REENTRANT */
|
#endif /* ( configUSE_NEWLIB_REENTRANT == 1 ) && ( configNEWLIB_REENTRANT_IS_DYNAMIC == 0 ) */
|
||||||
|
|
||||||
xNextTaskUnblockTime = portMAX_DELAY;
|
xNextTaskUnblockTime = portMAX_DELAY;
|
||||||
xSchedulerRunning = pdTRUE;
|
xSchedulerRunning = pdTRUE;
|
||||||
|
@ -3945,15 +3948,18 @@ void vTaskSwitchContext( BaseType_t xCoreID )
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ( configUSE_NEWLIB_REENTRANT == 1 )
|
#if ( ( configUSE_NEWLIB_REENTRANT == 1 ) && ( configNEWLIB_REENTRANT_IS_DYNAMIC == 0 ) )
|
||||||
{
|
{
|
||||||
/* Switch Newlib's _impure_ptr variable to point to the _reent
|
/* Switch Newlib's _impure_ptr variable to point to the _reent
|
||||||
* structure specific to this task.
|
* structure specific to this task.
|
||||||
* See the third party link http://www.nadler.com/embedded/newlibAndFreeRTOS.html
|
* See the third party link http://www.nadler.com/embedded/newlibAndFreeRTOS.html
|
||||||
* for additional information. */
|
* for additional information.
|
||||||
|
*
|
||||||
|
* Note: Updating the _impure_ptr is not required when Newlib is compiled with
|
||||||
|
* __DYNAMIC_REENT__ enabled. The the port should provide __getreent() instead. */
|
||||||
_impure_ptr = &( pxCurrentTCB->xNewLib_reent );
|
_impure_ptr = &( pxCurrentTCB->xNewLib_reent );
|
||||||
}
|
}
|
||||||
#endif /* configUSE_NEWLIB_REENTRANT */
|
#endif /* ( configUSE_NEWLIB_REENTRANT == 1 ) && ( configNEWLIB_REENTRANT_IS_DYNAMIC == 0 ) */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
portRELEASE_ISR_LOCK();
|
portRELEASE_ISR_LOCK();
|
||||||
|
|
Loading…
Reference in a new issue