mirror of
				https://github.com/FreeRTOS/FreeRTOS-Kernel.git
				synced 2025-11-04 02:59:01 +01:00 
			
		
		
		
	POSIX Simulator: Handle pthreads not created by FreeRTOS differently (#1223)
				
					
				
			This commit is contained in:
		
							parent
							
								
									72bb476bf3
								
							
						
					
					
						commit
						2b35979a1a
					
				
							
								
								
									
										102
									
								
								portable/ThirdParty/GCC/Posix/port.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										102
									
								
								portable/ThirdParty/GCC/Posix/port.c
									
									
									
									
										vendored
									
									
								
							@ -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 );
 | 
			
		||||
@ -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__ ) );
 | 
			
		||||
 | 
			
		||||
@ -249,6 +290,8 @@ BaseType_t xPortStartScheduler( void )
 | 
			
		||||
    /* Restore original signal mask. */
 | 
			
		||||
    ( void ) pthread_sigmask( SIG_SETMASK, &xSchedulerOriginalSignalMask, NULL );
 | 
			
		||||
 | 
			
		||||
    prvDestroyThreadKey();
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
@ -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();
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
@ -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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
@ -364,6 +417,8 @@ static void * prvTimerTickHandler( void * arg )
 | 
			
		||||
{
 | 
			
		||||
    ( void ) arg;
 | 
			
		||||
 | 
			
		||||
    prvMarkAsFreeRTOSThread( pthread_self() );
 | 
			
		||||
 | 
			
		||||
    prvPortSetCurrentThreadName("Scheduler timer");
 | 
			
		||||
 | 
			
		||||
    while( xTimerTickThreadShouldRun )
 | 
			
		||||
@ -396,26 +451,31 @@ void prvSetupTimerInterrupt( void )
 | 
			
		||||
 | 
			
		||||
static void vPortSystemTickHandler( int sig )
 | 
			
		||||
{
 | 
			
		||||
    Thread_t * pxThreadToSuspend;
 | 
			
		||||
    Thread_t * pxThreadToResume;
 | 
			
		||||
 | 
			
		||||
    ( void ) sig;
 | 
			
		||||
 | 
			
		||||
    uxCriticalNesting++; /* Signals are blocked in this signal handler. */
 | 
			
		||||
 | 
			
		||||
    pxThreadToSuspend = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() );
 | 
			
		||||
 | 
			
		||||
    if( xTaskIncrementTick() != pdFALSE )
 | 
			
		||||
    if( prvIsFreeRTOSThread( pthread_self() ) == pdTRUE )
 | 
			
		||||
    {
 | 
			
		||||
        /* Select Next Task. */
 | 
			
		||||
        vTaskSwitchContext();
 | 
			
		||||
        Thread_t * pxThreadToSuspend;
 | 
			
		||||
        Thread_t * pxThreadToResume;
 | 
			
		||||
 | 
			
		||||
        pxThreadToResume = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() );
 | 
			
		||||
        ( void ) sig;
 | 
			
		||||
 | 
			
		||||
        prvSwitchThread( pxThreadToResume, pxThreadToSuspend );
 | 
			
		||||
        uxCriticalNesting++; /* Signals are blocked in this signal handler. */
 | 
			
		||||
 | 
			
		||||
        pxThreadToSuspend = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() );
 | 
			
		||||
 | 
			
		||||
        if( xTaskIncrementTick() != pdFALSE )
 | 
			
		||||
        {
 | 
			
		||||
            /* Select Next Task. */
 | 
			
		||||
            vTaskSwitchContext();
 | 
			
		||||
 | 
			
		||||
            pxThreadToResume = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() );
 | 
			
		||||
 | 
			
		||||
            prvSwitchThread( pxThreadToResume, pxThreadToSuspend );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        uxCriticalNesting--;
 | 
			
		||||
    } else {
 | 
			
		||||
        fprintf( stderr, "vPortSystemTickHandler called from non-FreeRTOS thread\n" );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    uxCriticalNesting--;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
@ -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. */
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user