From 3daf236d07fb3ddec5edc57aaa139eba95b35510 Mon Sep 17 00:00:00 2001 From: Thomas Pedersen Date: Mon, 15 Feb 2021 11:07:26 -0800 Subject: [PATCH] Posix: use thread local storage for critical section counter This commit allows non-FreeRTOS pthreads to safely call vPortEnterCritical()/vPortExitCritical() Non-FreeRTOS Task pthreads may need to enter a critical section (for eg. printf()). In this case a single global uxCriticalNesting is bogus since it is not copied and restored on pthread scheduling. GCC Thread-Local Storage to the rescue. See https://gcc.gnu.org/onlinedocs/gcc/Thread-Local.html --- portable/ThirdParty/GCC/Posix/port.c | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/portable/ThirdParty/GCC/Posix/port.c b/portable/ThirdParty/GCC/Posix/port.c index 012e8b0a7..fdcbb848c 100644 --- a/portable/ThirdParty/GCC/Posix/port.c +++ b/portable/ThirdParty/GCC/Posix/port.c @@ -94,7 +94,7 @@ static sigset_t xResumeSignals; static sigset_t xAllSignals; static sigset_t xSchedulerOriginalSignalMask; static pthread_t hMainThread = ( pthread_t )NULL; -static volatile portBASE_TYPE uxCriticalNesting; +static volatile __thread portBASE_TYPE uxCriticalNesting = 0; /*-----------------------------------------------------------*/ static portBASE_TYPE xSchedulerEnd = pdFALSE; @@ -428,7 +428,6 @@ Thread_t *pxThread = pvParams; prvSuspendSelf(pxThread); /* Resumed for the first time, unblocks all signals. */ - uxCriticalNesting = 0; vPortEnableInterrupts(); /* Call the task's entry point. */ @@ -448,27 +447,14 @@ Thread_t *pxThread = pvParams; static void prvSwitchThread( Thread_t *pxThreadToResume, Thread_t *pxThreadToSuspend ) { -BaseType_t uxSavedCriticalNesting; - if ( pxThreadToSuspend != pxThreadToResume ) { - /* - * Switch tasks. - * - * The critical section nesting is per-task, so save it on the - * stack of the current (suspending thread), restoring it when - * we switch back to this task. - */ - uxSavedCriticalNesting = uxCriticalNesting; - prvResumeThread( pxThreadToResume ); if ( pxThreadToSuspend->xDying ) { pthread_exit( NULL ); } prvSuspendSelf( pxThreadToSuspend ); - - uxCriticalNesting = uxSavedCriticalNesting; } } /*-----------------------------------------------------------*/