Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FreeRTOS/FreeRTOS-Kernel.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--portable/ThirdParty/GCC/Posix/port.c41
1 files changed, 33 insertions, 8 deletions
diff --git a/portable/ThirdParty/GCC/Posix/port.c b/portable/ThirdParty/GCC/Posix/port.c
index d312aa48d..c5864f823 100644
--- a/portable/ThirdParty/GCC/Posix/port.c
+++ b/portable/ThirdParty/GCC/Posix/port.c
@@ -69,6 +69,7 @@
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
+#include "list.h"
#include "timers.h"
#include "utils/wait_for_event.h"
/*-----------------------------------------------------------*/
@@ -82,6 +83,7 @@ typedef struct THREAD
void * pvParams;
BaseType_t xDying;
struct event * ev;
+ ListItem_t xThreadListItem;
} Thread_t;
/*
@@ -102,6 +104,7 @@ static sigset_t xAllSignals;
static sigset_t xSchedulerOriginalSignalMask;
static pthread_t hMainThread = ( pthread_t ) NULL;
static volatile BaseType_t uxCriticalNesting;
+static List_t xThreadList;
/*-----------------------------------------------------------*/
static pthread_t hTimerTickThread;
@@ -178,6 +181,11 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
thread->ev = event_create();
+ /* Add the new thread in xThreadList. */
+ vListInitialiseItem( &thread->xThreadListItem );
+ listSET_LIST_ITEM_OWNER( &thread->xThreadListItem, thread );
+ vListInsertEnd( &xThreadList, &thread->xThreadListItem );
+
vPortEnterCritical();
iRet = pthread_create( &thread->pthread, &xThreadAttributes,
@@ -210,6 +218,8 @@ BaseType_t xPortStartScheduler( void )
{
int iSignal;
sigset_t xSignals;
+ ListItem_t * pxIterator;
+ const ListItem_t * pxEndMarker;
hMainThread = pthread_self();
@@ -239,15 +249,23 @@ BaseType_t xPortStartScheduler( void )
xTimerTickThreadShouldRun = false;
pthread_join( hTimerTickThread, NULL );
- /* Cancel the Idle task and free its resources */
- #if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )
- vPortCancelThread( xTaskGetIdleTaskHandle() );
- #endif
+ /*
+ * cancel and join any remaining pthreads
+ * to ensure their resources are freed
+ *
+ * https://stackoverflow.com/a/5612424
+ */
+ pxEndMarker = listGET_END_MARKER( &xThreadList );
+ for( pxIterator = listGET_HEAD_ENTRY( &xThreadList ); pxIterator != pxEndMarker; pxIterator = listGET_NEXT( pxIterator ) )
+ {
+ Thread_t *pxThread = ( Thread_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
+
+ pthread_cancel( pxThread->pthread );
+ event_signal( pxThread->ev );
- #if ( configUSE_TIMERS == 1 )
- /* Cancel the Timer task and free its resources */
- vPortCancelThread( xTimerGetTimerDaemonTaskHandle() );
- #endif /* configUSE_TIMERS */
+ pthread_join( pxThread->pthread, NULL );
+ event_delete( pxThread->ev );
+ }
/* Restore original signal mask. */
( void ) pthread_sigmask( SIG_SETMASK, &xSchedulerOriginalSignalMask, NULL );
@@ -444,10 +462,14 @@ void vPortCancelThread( void * pxTaskToDelete )
{
Thread_t * pxThreadToCancel = prvGetThreadFromTask( pxTaskToDelete );
+ /* Remove the thread from xThreadList. */
+ uxListRemove( &pxThreadToCancel->xThreadListItem );
+
/*
* The thread has already been suspended so it can be safely cancelled.
*/
pthread_cancel( pxThreadToCancel->pthread );
+ event_signal( pxThreadToCancel->ev );
pthread_join( pxThreadToCancel->pthread, NULL );
event_delete( pxThreadToCancel->ev );
}
@@ -543,6 +565,9 @@ static void prvSetupSignalsAndSchedulerPolicy( void )
hMainThread = pthread_self();
+ /* Setup thread list to record all the task which are not deleted. */
+ vListInitialise( &xThreadList );
+
/* Initialise common signal masks. */
sigfillset( &xAllSignals );