forked from epagris/FreeRTOS-Kernel
		
	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>
 | 
			
		||||
#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
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										18
									
								
								tasks.c
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								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();
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user