mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-19 21:11:57 -04:00
Fix potential race condition
This commit is contained in:
parent
88d3540b54
commit
6b698ff6bc
43
portable/ThirdParty/GCC/Posix/port.c
vendored
43
portable/ThirdParty/GCC/Posix/port.c
vendored
|
@ -105,11 +105,7 @@ static sigset_t xSchedulerOriginalSignalMask;
|
||||||
static pthread_t hMainThread = ( pthread_t ) NULL;
|
static pthread_t hMainThread = ( pthread_t ) NULL;
|
||||||
static volatile BaseType_t uxCriticalNesting;
|
static volatile BaseType_t uxCriticalNesting;
|
||||||
static List_t xThreadList;
|
static List_t xThreadList;
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
static pthread_t hTimerTickThread;
|
static pthread_t hTimerTickThread;
|
||||||
static bool xTimerTickThreadShouldRun;
|
|
||||||
|
|
||||||
static BaseType_t xSchedulerEnd = pdFALSE;
|
static BaseType_t xSchedulerEnd = pdFALSE;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -181,13 +177,14 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
|
|
||||||
thread->ev = event_create();
|
thread->ev = event_create();
|
||||||
|
|
||||||
/* Add the new thread in xThreadList. */
|
|
||||||
vListInitialiseItem( &thread->xThreadListItem );
|
vListInitialiseItem( &thread->xThreadListItem );
|
||||||
listSET_LIST_ITEM_OWNER( &thread->xThreadListItem, thread );
|
listSET_LIST_ITEM_OWNER( &thread->xThreadListItem, thread );
|
||||||
vListInsertEnd( &xThreadList, &thread->xThreadListItem );
|
|
||||||
|
|
||||||
vPortEnterCritical();
|
vPortEnterCritical();
|
||||||
|
|
||||||
|
/* Add the new thread in xThreadList. */
|
||||||
|
vListInsertEnd( &xThreadList, &thread->xThreadListItem );
|
||||||
|
|
||||||
iRet = pthread_create( &thread->pthread, &xThreadAttributes,
|
iRet = pthread_create( &thread->pthread, &xThreadAttributes,
|
||||||
prvWaitForStart, thread );
|
prvWaitForStart, thread );
|
||||||
|
|
||||||
|
@ -245,10 +242,6 @@ BaseType_t xPortStartScheduler( void )
|
||||||
sigwait( &xSignals, &iSignal );
|
sigwait( &xSignals, &iSignal );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* asking timer thread to shut down */
|
|
||||||
xTimerTickThreadShouldRun = false;
|
|
||||||
pthread_join( hTimerTickThread, NULL );
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* cancel and join any remaining pthreads
|
* cancel and join any remaining pthreads
|
||||||
* to ensure their resources are freed
|
* to ensure their resources are freed
|
||||||
|
@ -261,8 +254,6 @@ BaseType_t xPortStartScheduler( void )
|
||||||
Thread_t *pxThread = ( Thread_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
|
Thread_t *pxThread = ( Thread_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
|
||||||
|
|
||||||
pthread_cancel( pxThread->pthread );
|
pthread_cancel( pxThread->pthread );
|
||||||
event_signal( pxThread->ev );
|
|
||||||
|
|
||||||
pthread_join( pxThread->pthread, NULL );
|
pthread_join( pxThread->pthread, NULL );
|
||||||
event_delete( pxThread->ev );
|
event_delete( pxThread->ev );
|
||||||
}
|
}
|
||||||
|
@ -276,14 +267,15 @@ BaseType_t xPortStartScheduler( void )
|
||||||
|
|
||||||
void vPortEndScheduler( void )
|
void vPortEndScheduler( void )
|
||||||
{
|
{
|
||||||
Thread_t * xCurrentThread;
|
/* Stop the timer tick thread. */
|
||||||
|
pthread_cancel( hTimerTickThread );
|
||||||
|
pthread_join( hTimerTickThread, NULL );
|
||||||
|
|
||||||
/* Signal the scheduler to exit its loop. */
|
/* Signal the scheduler to exit its loop. */
|
||||||
xSchedulerEnd = pdTRUE;
|
xSchedulerEnd = pdTRUE;
|
||||||
( void ) pthread_kill( hMainThread, SIG_RESUME );
|
( void ) pthread_kill( hMainThread, SIG_RESUME );
|
||||||
|
|
||||||
xCurrentThread = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() );
|
pthread_exit( NULL );
|
||||||
prvSuspendSelf( xCurrentThread );
|
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -378,19 +370,24 @@ static uint64_t prvStartTimeNs;
|
||||||
|
|
||||||
static void* prvTimerTickHandler(void *arg)
|
static void* prvTimerTickHandler(void *arg)
|
||||||
{
|
{
|
||||||
while( xTimerTickThreadShouldRun )
|
for(;;)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* signal to the active task to cause tick handling or
|
* signal to the active task to cause tick handling or
|
||||||
* preemption (if enabled)
|
* preemption (if enabled)
|
||||||
*/
|
*/
|
||||||
Thread_t * thread = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() );
|
TaskHandle_t hCurrentTask;
|
||||||
|
Thread_t * thread;
|
||||||
|
|
||||||
|
hCurrentTask = xTaskGetCurrentTaskHandle();
|
||||||
|
if( hCurrentTask != NULL )
|
||||||
|
{
|
||||||
|
thread = prvGetThreadFromTask( hCurrentTask );
|
||||||
pthread_kill( thread->pthread, SIGALRM );
|
pthread_kill( thread->pthread, SIGALRM );
|
||||||
|
|
||||||
usleep( portTICK_RATE_MICROSECONDS );
|
|
||||||
}
|
}
|
||||||
|
usleep( portTICK_RATE_MICROSECONDS );
|
||||||
return NULL;
|
pthread_testcancel();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -399,7 +396,6 @@ static void* prvTimerTickHandler(void *arg)
|
||||||
*/
|
*/
|
||||||
void prvSetupTimerInterrupt( void )
|
void prvSetupTimerInterrupt( void )
|
||||||
{
|
{
|
||||||
xTimerTickThreadShouldRun = true;
|
|
||||||
pthread_create( &hTimerTickThread, NULL, prvTimerTickHandler, NULL );
|
pthread_create( &hTimerTickThread, NULL, prvTimerTickHandler, NULL );
|
||||||
|
|
||||||
prvStartTimeNs = prvGetTimeNs();
|
prvStartTimeNs = prvGetTimeNs();
|
||||||
|
@ -463,13 +459,14 @@ void vPortCancelThread( void * pxTaskToDelete )
|
||||||
Thread_t * pxThreadToCancel = prvGetThreadFromTask( pxTaskToDelete );
|
Thread_t * pxThreadToCancel = prvGetThreadFromTask( pxTaskToDelete );
|
||||||
|
|
||||||
/* Remove the thread from xThreadList. */
|
/* Remove the thread from xThreadList. */
|
||||||
|
vPortEnterCritical();
|
||||||
uxListRemove( &pxThreadToCancel->xThreadListItem );
|
uxListRemove( &pxThreadToCancel->xThreadListItem );
|
||||||
|
vPortExitCritical();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The thread has already been suspended so it can be safely cancelled.
|
* The thread has already been suspended so it can be safely cancelled.
|
||||||
*/
|
*/
|
||||||
pthread_cancel( pxThreadToCancel->pthread );
|
pthread_cancel( pxThreadToCancel->pthread );
|
||||||
event_signal( pxThreadToCancel->ev );
|
|
||||||
pthread_join( pxThreadToCancel->pthread, NULL );
|
pthread_join( pxThreadToCancel->pthread, NULL );
|
||||||
event_delete( pxThreadToCancel->ev );
|
event_delete( pxThreadToCancel->ev );
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue