Skip to content

Commit 2b35979

Browse files
authored
POSIX Simulator: Handle pthreads not created by FreeRTOS differently (#1223)
1 parent 72bb476 commit 2b35979

File tree

1 file changed

+79
-17
lines changed
  • portable/ThirdParty/GCC/Posix

1 file changed

+79
-17
lines changed

portable/ThirdParty/GCC/Posix/port.c

Lines changed: 79 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ static BaseType_t xSchedulerEnd = pdFALSE;
105105
static pthread_t hTimerTickThread;
106106
static bool xTimerTickThreadShouldRun;
107107
static uint64_t prvStartTimeNs;
108+
static pthread_mutex_t xThreadMutex = PTHREAD_MUTEX_INITIALIZER;
109+
static pthread_key_t xThreadKey = 0;
108110
/*-----------------------------------------------------------*/
109111

110112
static void prvSetupSignalsAndSchedulerPolicy( void );
@@ -119,6 +121,45 @@ static void vPortStartFirstTask( void );
119121
static void prvPortYieldFromISR( void );
120122
/*-----------------------------------------------------------*/
121123

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

@@ -249,6 +290,8 @@ BaseType_t xPortStartScheduler( void )
249290
/* Restore original signal mask. */
250291
( void ) pthread_sigmask( SIG_SETMASK, &xSchedulerOriginalSignalMask, NULL );
251292

293+
prvDestroyThreadKey();
294+
252295
return 0;
253296
}
254297
/*-----------------------------------------------------------*/
@@ -266,8 +309,12 @@ void vPortEndScheduler( void )
266309
( void ) pthread_kill( hMainThread, SIG_RESUME );
267310

268311
/* Waiting to be deleted here. */
269-
pxCurrentThread = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() );
270-
event_wait( pxCurrentThread->ev );
312+
if( prvIsFreeRTOSThread( pthread_self() ) == pdTRUE )
313+
{
314+
pxCurrentThread = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() );
315+
event_wait( pxCurrentThread->ev );
316+
}
317+
271318
pthread_testcancel();
272319
}
273320
/*-----------------------------------------------------------*/
@@ -322,13 +369,19 @@ void vPortYield( void )
322369

323370
void vPortDisableInterrupts( void )
324371
{
325-
pthread_sigmask( SIG_BLOCK, &xAllSignals, NULL );
372+
if( prvIsFreeRTOSThread( pthread_self() ) == pdTRUE )
373+
{
374+
pthread_sigmask(SIG_BLOCK, &xAllSignals, NULL);
375+
}
326376
}
327377
/*-----------------------------------------------------------*/
328378

329379
void vPortEnableInterrupts( void )
330380
{
331-
pthread_sigmask( SIG_UNBLOCK, &xAllSignals, NULL );
381+
if( prvIsFreeRTOSThread( pthread_self() ) == pdTRUE )
382+
{
383+
pthread_sigmask(SIG_UNBLOCK, &xAllSignals, NULL);
384+
}
332385
}
333386
/*-----------------------------------------------------------*/
334387

@@ -364,6 +417,8 @@ static void * prvTimerTickHandler( void * arg )
364417
{
365418
( void ) arg;
366419

420+
prvMarkAsFreeRTOSThread( pthread_self() );
421+
367422
prvPortSetCurrentThreadName("Scheduler timer");
368423

369424
while( xTimerTickThreadShouldRun )
@@ -396,26 +451,31 @@ void prvSetupTimerInterrupt( void )
396451

397452
static void vPortSystemTickHandler( int sig )
398453
{
399-
Thread_t * pxThreadToSuspend;
400-
Thread_t * pxThreadToResume;
454+
if( prvIsFreeRTOSThread( pthread_self() ) == pdTRUE )
455+
{
456+
Thread_t * pxThreadToSuspend;
457+
Thread_t * pxThreadToResume;
401458

402-
( void ) sig;
459+
( void ) sig;
403460

404-
uxCriticalNesting++; /* Signals are blocked in this signal handler. */
461+
uxCriticalNesting++; /* Signals are blocked in this signal handler. */
405462

406-
pxThreadToSuspend = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() );
463+
pxThreadToSuspend = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() );
407464

408-
if( xTaskIncrementTick() != pdFALSE )
409-
{
410-
/* Select Next Task. */
411-
vTaskSwitchContext();
465+
if( xTaskIncrementTick() != pdFALSE )
466+
{
467+
/* Select Next Task. */
468+
vTaskSwitchContext();
412469

413-
pxThreadToResume = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() );
470+
pxThreadToResume = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() );
414471

415-
prvSwitchThread( pxThreadToResume, pxThreadToSuspend );
416-
}
472+
prvSwitchThread( pxThreadToResume, pxThreadToSuspend );
473+
}
417474

418-
uxCriticalNesting--;
475+
uxCriticalNesting--;
476+
} else {
477+
fprintf( stderr, "vPortSystemTickHandler called from non-FreeRTOS thread\n" );
478+
}
419479
}
420480
/*-----------------------------------------------------------*/
421481

@@ -448,6 +508,8 @@ static void * prvWaitForStart( void * pvParams )
448508
{
449509
Thread_t * pxThread = pvParams;
450510

511+
prvMarkAsFreeRTOSThread( pthread_self() );
512+
451513
prvSuspendSelf( pxThread );
452514

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

0 commit comments

Comments
 (0)