Skip to content

Commit 6f630dc

Browse files
committed
Avoid using pthread_sigmask on pthreads not created by FreeRTOS
1 parent f31787d commit 6f630dc

File tree

1 file changed

+68
-4
lines changed
  • portable/ThirdParty/GCC/Posix

1 file changed

+68
-4
lines changed

portable/ThirdParty/GCC/Posix/port.c

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ static BaseType_t xSchedulerEnd = pdFALSE;
109109
static pthread_t hTimerTickThread;
110110
static bool xTimerTickThreadShouldRun;
111111
static uint64_t prvStartTimeNs;
112+
static pthread_mutex_t xThreadMutex = PTHREAD_MUTEX_INITIALIZER;
113+
static pthread_key_t xThreadKey = 0;
112114
/*-----------------------------------------------------------*/
113115

114116
static void prvSetupSignalsAndSchedulerPolicy( void );
@@ -123,6 +125,44 @@ static void vPortStartFirstTask( void );
123125
static void prvPortYieldFromISR( void );
124126
/*-----------------------------------------------------------*/
125127

128+
void prvThreadKeyDestructor( void * data )
129+
{
130+
free( data );
131+
}
132+
133+
static void prvInitThreadKey()
134+
{
135+
pthread_mutex_lock( &xThreadMutex );
136+
137+
if( xThreadKey == 0 )
138+
{
139+
pthread_key_create( &xThreadKey, prvThreadKeyDestructor );
140+
}
141+
142+
pthread_mutex_unlock( &xThreadMutex );
143+
}
144+
145+
static void prvMarkAsFreeRTOSThread( pthread_t thread )
146+
{
147+
prvInitThreadKey();
148+
uint8_t * thread_data = malloc( 1 );
149+
*thread_data = 1;
150+
pthread_setspecific( xThreadKey, thread_data );
151+
}
152+
153+
static BaseType_t prvIsFreeRTOSThread( pthread_t thread )
154+
{
155+
uint8_t * thread_data = ( uint8_t * ) pthread_getspecific( xThreadKey );
156+
157+
return thread_data != NULL && *thread_data == 1;
158+
}
159+
160+
static void prvDestroyThreadKey()
161+
{
162+
pthread_key_delete( xThreadKey );
163+
}
164+
/*-----------------------------------------------------------*/
165+
126166
static void prvFatalError( const char * pcCall,
127167
int iErrno ) __attribute__( ( __noreturn__ ) );
128168

@@ -253,6 +293,8 @@ BaseType_t xPortStartScheduler( void )
253293
/* Restore original signal mask. */
254294
( void ) pthread_sigmask( SIG_SETMASK, &xSchedulerOriginalSignalMask, NULL );
255295

296+
prvDestroyThreadKey();
297+
256298
return 0;
257299
}
258300
/*-----------------------------------------------------------*/
@@ -270,8 +312,12 @@ void vPortEndScheduler( void )
270312
( void ) pthread_kill( hMainThread, SIG_RESUME );
271313

272314
/* Waiting to be deleted here. */
273-
pxCurrentThread = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() );
274-
event_wait( pxCurrentThread->ev );
315+
if( prvIsFreeRTOSThread( pthread_self() ) == pdTRUE )
316+
{
317+
pxCurrentThread = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() );
318+
event_wait( pxCurrentThread->ev );
319+
}
320+
275321
pthread_testcancel();
276322
}
277323
/*-----------------------------------------------------------*/
@@ -326,13 +372,21 @@ void vPortYield( void )
326372

327373
void vPortDisableInterrupts( void )
328374
{
329-
pthread_sigmask( SIG_BLOCK, &xAllSignals, NULL );
375+
if( prvIsFreeRTOSThread( pthread_self() ) == pdFALSE )
376+
{
377+
return;
378+
}
379+
pthread_sigmask(SIG_BLOCK, &xAllSignals, NULL);
330380
}
331381
/*-----------------------------------------------------------*/
332382

333383
void vPortEnableInterrupts( void )
334384
{
335-
pthread_sigmask( SIG_UNBLOCK, &xAllSignals, NULL );
385+
if( prvIsFreeRTOSThread( pthread_self() ) == pdFALSE )
386+
{
387+
return;
388+
}
389+
pthread_sigmask(SIG_UNBLOCK, &xAllSignals, NULL);
336390
}
337391
/*-----------------------------------------------------------*/
338392

@@ -368,6 +422,8 @@ static void * prvTimerTickHandler( void * arg )
368422
{
369423
( void ) arg;
370424

425+
prvMarkAsFreeRTOSThread( pthread_self() );
426+
371427
prvPortSetCurrentThreadName("Scheduler timer");
372428

373429
while( xTimerTickThreadShouldRun )
@@ -400,6 +456,12 @@ void prvSetupTimerInterrupt( void )
400456

401457
static void vPortSystemTickHandler( int sig )
402458
{
459+
if( prvIsFreeRTOSThread( pthread_self() ) == pdFALSE )
460+
{
461+
fprintf( stderr, "vPortSystemTickHandler called from non-FreeRTOS thread\n" );
462+
return;
463+
}
464+
403465
Thread_t * pxThreadToSuspend;
404466
Thread_t * pxThreadToResume;
405467

@@ -452,6 +514,8 @@ static void * prvWaitForStart( void * pvParams )
452514
{
453515
Thread_t * pxThread = pvParams;
454516

517+
prvMarkAsFreeRTOSThread( pthread_self() );
518+
455519
prvSuspendSelf( pxThread );
456520

457521
/* Resumed for the first time, unblocks all signals. */

0 commit comments

Comments
 (0)