mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-19 13:01:57 -04:00
POSIX Simulator: Handle pthread
s 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…
Reference in a new issue