Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FreeRTOS/FreeRTOS-Kernel.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarian <32921628+Dazza0@users.noreply.github.com>2022-06-01 02:11:02 +0300
committerGitHub <noreply@github.com>2022-06-01 02:11:02 +0300
commit34b8e24d7ccdbe25af8ad96dfd3154aeb302a8d6 (patch)
tree29183cfe6adccf47346302fb7950b914aee29c63
parenta97741a08d36ac08d913b8bc86abf128df627e85 (diff)
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
-rw-r--r--include/FreeRTOS.h8
-rw-r--r--tasks.c18
2 files changed, 20 insertions, 6 deletions
diff --git a/include/FreeRTOS.h b/include/FreeRTOS.h
index 6aa3b803c..60abd75b6 100644
--- a/include/FreeRTOS.h
+++ b/include/FreeRTOS.h
@@ -72,6 +72,14 @@
#include <reent.h>
#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.
* These macros are application specific and (as downloaded) are defined
diff --git a/tasks.c b/tasks.c
index 4296e300b..7eb1409aa 100644
--- a/tasks.c
+++ b/tasks.c
@@ -2854,15 +2854,18 @@ void vTaskStartScheduler( void )
* starts to run. */
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
* structure specific to the task that will run first.
* 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 );
}
- #endif /* configUSE_NEWLIB_REENTRANT */
+ #endif /* ( configUSE_NEWLIB_REENTRANT == 1 ) && ( configNEWLIB_REENTRANT_IS_DYNAMIC == 0 ) */
xNextTaskUnblockTime = portMAX_DELAY;
xSchedulerRunning = pdTRUE;
@@ -3945,15 +3948,18 @@ void vTaskSwitchContext( BaseType_t xCoreID )
}
#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
* structure specific to this task.
* 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 );
}
- #endif /* configUSE_NEWLIB_REENTRANT */
+ #endif /* ( configUSE_NEWLIB_REENTRANT == 1 ) && ( configNEWLIB_REENTRANT_IS_DYNAMIC == 0 ) */
}
}
portRELEASE_ISR_LOCK();