Preserve POSIX thread identity after TLS errors

TLS setup failures cannot be recovered without misclassifying FreeRTOS-owned pthreads. Fail fast after cleaning up the per-thread marker, and retain key-creation status across pthread_once callers.

Constraint: Thread identity has no recoverable fallback when POSIX TLS setup fails
Rejected: Free and continue | leaves FreeRTOS-owned pthreads misclassified
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep fatal handling unless a recoverable status path is added end to end
Tested: WSL GCC -Wall -Wextra -Werror compile; success path; injected pthread_once, pthread_key_create, malloc, and pthread_setspecific failures
Not-tested: Full FreeRTOS POSIX scheduler test suite
Related: FreeRTOS/FreeRTOS-Kernel#1447
This commit is contained in:
yi chen 2026-07-13 04:46:08 +08:00
parent 9db704cd3b
commit defa802e95

View file

@ -112,6 +112,7 @@ static pthread_t hTimerTickThread;
static bool xTimerTickThreadShouldRun; static bool xTimerTickThreadShouldRun;
static uint64_t prvStartTimeNs; static uint64_t prvStartTimeNs;
static pthread_key_t xThreadKey = 0; static pthread_key_t xThreadKey = 0;
static int iThreadKeyCreateResult = 0;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvSetupSignalsAndSchedulerPolicy( void ); static void prvSetupSignalsAndSchedulerPolicy( void );
@ -129,6 +130,8 @@ static void prvInitThreadKey( void );
static void prvMarkAsFreeRTOSThread( void ); static void prvMarkAsFreeRTOSThread( void );
static BaseType_t prvIsFreeRTOSThread( void ); static BaseType_t prvIsFreeRTOSThread( void );
static void prvDestroyThreadKey( void ); static void prvDestroyThreadKey( void );
static void prvFatalError( const char * pcCall,
int iErrno ) __attribute__( ( __noreturn__ ) );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvThreadKeyDestructor( void * pvData ) static void prvThreadKeyDestructor( void * pvData )
@ -139,24 +142,49 @@ static void prvThreadKeyDestructor( void * pvData )
static void prvInitThreadKey( void ) static void prvInitThreadKey( void )
{ {
pthread_key_create( &xThreadKey, prvThreadKeyDestructor ); iThreadKeyCreateResult = pthread_key_create( &xThreadKey, prvThreadKeyDestructor );
/* Destroy xThreadKey when the process exits. */
atexit( prvDestroyThreadKey ); if( iThreadKeyCreateResult == 0 )
{
/* Destroy xThreadKey when the process exits. */
atexit( prvDestroyThreadKey );
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvMarkAsFreeRTOSThread( void ) static void prvMarkAsFreeRTOSThread( void )
{ {
uint8_t * pucThreadData = NULL; uint8_t * pucThreadData = NULL;
int iRet;
( void ) pthread_once( &hThreadKeyOnce, prvInitThreadKey ); iRet = pthread_once( &hThreadKeyOnce, prvInitThreadKey );
if( iRet != 0 )
{
prvFatalError( "pthread_once", iRet );
}
if( iThreadKeyCreateResult != 0 )
{
prvFatalError( "pthread_key_create", iThreadKeyCreateResult );
}
pucThreadData = malloc( 1 ); pucThreadData = malloc( 1 );
configASSERT( pucThreadData != NULL );
if( pucThreadData == NULL )
{
prvFatalError( "malloc", ENOMEM );
}
*pucThreadData = 1; *pucThreadData = 1;
pthread_setspecific( xThreadKey, pucThreadData ); iRet = pthread_setspecific( xThreadKey, pucThreadData );
if( iRet != 0 )
{
free( pucThreadData );
prvFatalError( "pthread_setspecific", iRet );
}
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -164,8 +192,19 @@ static BaseType_t prvIsFreeRTOSThread( void )
{ {
uint8_t * pucThreadData = NULL; uint8_t * pucThreadData = NULL;
BaseType_t xRet = pdFALSE; BaseType_t xRet = pdFALSE;
int iRet;
( void ) pthread_once( &hThreadKeyOnce, prvInitThreadKey ); iRet = pthread_once( &hThreadKeyOnce, prvInitThreadKey );
if( iRet != 0 )
{
prvFatalError( "pthread_once", iRet );
}
if( iThreadKeyCreateResult != 0 )
{
prvFatalError( "pthread_key_create", iThreadKeyCreateResult );
}
pucThreadData = ( uint8_t * ) pthread_getspecific( xThreadKey ); pucThreadData = ( uint8_t * ) pthread_getspecific( xThreadKey );
@ -184,9 +223,6 @@ static void prvDestroyThreadKey( void )
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvFatalError( const char * pcCall,
int iErrno ) __attribute__( ( __noreturn__ ) );
void prvFatalError( const char * pcCall, void prvFatalError( const char * pcCall,
int iErrno ) int iErrno )
{ {