Skip to content

Commit

Permalink
POSIX Simulator: Handle pthreads not created by FreeRTOS differently (
Browse files Browse the repository at this point in the history
  • Loading branch information
johnboiles authored Jan 25, 2025
1 parent 72bb476 commit 2b35979
Showing 1 changed file with 79 additions and 17 deletions.
96 changes: 79 additions & 17 deletions portable/ThirdParty/GCC/Posix/port.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ static BaseType_t xSchedulerEnd = pdFALSE;
static pthread_t hTimerTickThread;
static bool xTimerTickThreadShouldRun;
static uint64_t prvStartTimeNs;
static pthread_mutex_t xThreadMutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_key_t xThreadKey = 0;
/*-----------------------------------------------------------*/

static void prvSetupSignalsAndSchedulerPolicy( void );
Expand All @@ -119,6 +121,45 @@ static void vPortStartFirstTask( void );
static void prvPortYieldFromISR( void );
/*-----------------------------------------------------------*/

void prvThreadKeyDestructor( void * data )
{
free( data );
}

static void prvInitThreadKey()
{
pthread_mutex_lock( &xThreadMutex );

if( xThreadKey == 0 )
{
pthread_key_create( &xThreadKey, prvThreadKeyDestructor );
}

pthread_mutex_unlock( &xThreadMutex );
}

static void prvMarkAsFreeRTOSThread( pthread_t thread )
{
prvInitThreadKey();
uint8_t * thread_data = malloc( 1 );
configASSERT( thread_data != NULL );
*thread_data = 1;
pthread_setspecific( xThreadKey, thread_data );
}

static BaseType_t prvIsFreeRTOSThread( pthread_t thread )
{
uint8_t * thread_data = ( uint8_t * ) pthread_getspecific( xThreadKey );

return thread_data != NULL && *thread_data == 1;
}

static void prvDestroyThreadKey()
{
pthread_key_delete( xThreadKey );
}
/*-----------------------------------------------------------*/

static void prvFatalError( const char * pcCall,
int iErrno ) __attribute__( ( __noreturn__ ) );

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

prvDestroyThreadKey();

return 0;
}
/*-----------------------------------------------------------*/
Expand All @@ -266,8 +309,12 @@ void vPortEndScheduler( void )
( void ) pthread_kill( hMainThread, SIG_RESUME );

/* Waiting to be deleted here. */
pxCurrentThread = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() );
event_wait( pxCurrentThread->ev );
if( prvIsFreeRTOSThread( pthread_self() ) == pdTRUE )
{
pxCurrentThread = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() );
event_wait( pxCurrentThread->ev );
}

pthread_testcancel();
}
/*-----------------------------------------------------------*/
Expand Down Expand Up @@ -322,13 +369,19 @@ void vPortYield( void )

void vPortDisableInterrupts( void )
{
pthread_sigmask( SIG_BLOCK, &xAllSignals, NULL );
if( prvIsFreeRTOSThread( pthread_self() ) == pdTRUE )
{
pthread_sigmask(SIG_BLOCK, &xAllSignals, NULL);
}
}
/*-----------------------------------------------------------*/

void vPortEnableInterrupts( void )
{
pthread_sigmask( SIG_UNBLOCK, &xAllSignals, NULL );
if( prvIsFreeRTOSThread( pthread_self() ) == pdTRUE )
{
pthread_sigmask(SIG_UNBLOCK, &xAllSignals, NULL);
}
}
/*-----------------------------------------------------------*/

Expand Down Expand Up @@ -364,6 +417,8 @@ static void * prvTimerTickHandler( void * arg )
{
( void ) arg;

prvMarkAsFreeRTOSThread( pthread_self() );

prvPortSetCurrentThreadName("Scheduler timer");

while( xTimerTickThreadShouldRun )
Expand Down Expand Up @@ -396,26 +451,31 @@ void prvSetupTimerInterrupt( void )

static void vPortSystemTickHandler( int sig )
{
Thread_t * pxThreadToSuspend;
Thread_t * pxThreadToResume;
if( prvIsFreeRTOSThread( pthread_self() ) == pdTRUE )
{
Thread_t * pxThreadToSuspend;
Thread_t * pxThreadToResume;

( void ) sig;
( void ) sig;

uxCriticalNesting++; /* Signals are blocked in this signal handler. */
uxCriticalNesting++; /* Signals are blocked in this signal handler. */

pxThreadToSuspend = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() );
pxThreadToSuspend = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() );

if( xTaskIncrementTick() != pdFALSE )
{
/* Select Next Task. */
vTaskSwitchContext();
if( xTaskIncrementTick() != pdFALSE )
{
/* Select Next Task. */
vTaskSwitchContext();

pxThreadToResume = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() );
pxThreadToResume = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() );

prvSwitchThread( pxThreadToResume, pxThreadToSuspend );
}
prvSwitchThread( pxThreadToResume, pxThreadToSuspend );
}

uxCriticalNesting--;
uxCriticalNesting--;
} else {
fprintf( stderr, "vPortSystemTickHandler called from non-FreeRTOS thread\n" );
}
}
/*-----------------------------------------------------------*/

Expand Down Expand Up @@ -448,6 +508,8 @@ static void * prvWaitForStart( void * pvParams )
{
Thread_t * pxThread = pvParams;

prvMarkAsFreeRTOSThread( pthread_self() );

prvSuspendSelf( pxThread );

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

0 comments on commit 2b35979

Please sign in to comment.