mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-09-12 17:17:44 -04:00
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
This commit is contained in:
parent
1d4d16fd54
commit
3daf236d07
1 changed files with 1 additions and 15 deletions
16
portable/ThirdParty/GCC/Posix/port.c
vendored
16
portable/ThirdParty/GCC/Posix/port.c
vendored
|
@ -94,7 +94,7 @@ static sigset_t xResumeSignals;
|
||||||
static sigset_t xAllSignals;
|
static sigset_t xAllSignals;
|
||||||
static sigset_t xSchedulerOriginalSignalMask;
|
static sigset_t xSchedulerOriginalSignalMask;
|
||||||
static pthread_t hMainThread = ( pthread_t )NULL;
|
static pthread_t hMainThread = ( pthread_t )NULL;
|
||||||
static volatile portBASE_TYPE uxCriticalNesting;
|
static volatile __thread portBASE_TYPE uxCriticalNesting = 0;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static portBASE_TYPE xSchedulerEnd = pdFALSE;
|
static portBASE_TYPE xSchedulerEnd = pdFALSE;
|
||||||
|
@ -428,7 +428,6 @@ Thread_t *pxThread = pvParams;
|
||||||
prvSuspendSelf(pxThread);
|
prvSuspendSelf(pxThread);
|
||||||
|
|
||||||
/* Resumed for the first time, unblocks all signals. */
|
/* Resumed for the first time, unblocks all signals. */
|
||||||
uxCriticalNesting = 0;
|
|
||||||
vPortEnableInterrupts();
|
vPortEnableInterrupts();
|
||||||
|
|
||||||
/* Call the task's entry point. */
|
/* Call the task's entry point. */
|
||||||
|
@ -448,27 +447,14 @@ Thread_t *pxThread = pvParams;
|
||||||
static void prvSwitchThread( Thread_t *pxThreadToResume,
|
static void prvSwitchThread( Thread_t *pxThreadToResume,
|
||||||
Thread_t *pxThreadToSuspend )
|
Thread_t *pxThreadToSuspend )
|
||||||
{
|
{
|
||||||
BaseType_t uxSavedCriticalNesting;
|
|
||||||
|
|
||||||
if ( pxThreadToSuspend != pxThreadToResume )
|
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 );
|
prvResumeThread( pxThreadToResume );
|
||||||
if ( pxThreadToSuspend->xDying )
|
if ( pxThreadToSuspend->xDying )
|
||||||
{
|
{
|
||||||
pthread_exit( NULL );
|
pthread_exit( NULL );
|
||||||
}
|
}
|
||||||
prvSuspendSelf( pxThreadToSuspend );
|
prvSuspendSelf( pxThreadToSuspend );
|
||||||
|
|
||||||
uxCriticalNesting = uxSavedCriticalNesting;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue