]> git.sur5r.net Git - freertos/commitdiff
Backup checking on - part way through optimising task pool.
authorrtel <rtel@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Mon, 22 Jul 2019 21:46:13 +0000 (21:46 +0000)
committerrtel <rtel@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Mon, 22 Jul 2019 21:46:13 +0000 (21:46 +0000)
git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@2693 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/taskpool/iot_taskpool.c

index 5c66bc2e2399bc4770aeeb37452eaf4963e495e5..f0826281ad6a3fd1b9932b0eebe9fa98956d0cce 100644 (file)
        #error configSUPPORT_STATIC_ALLOCATION must be set to 1 in FreeRTOSConfig.h to build this file.\r
 #endif\r
 \r
-/* Platform layer includes. */\r
-//_RB_#include "platform/iot_threads.h"\r
-//_RB_#include "platform/iot_clock.h"\r
-\r
 /* Task pool internal include. */\r
 #include "private/iot_taskpool_internal.h"\r
 \r
@@ -72,7 +68,7 @@
  * the system libraries as well. The system task pool needs to be initialized before any library is used or\r
  * before any code that posts jobs to the task pool runs.\r
  */\r
-_taskPool_t _IotSystemTaskPool = { .dispatchQueue = IOT_DEQUEUE_INITIALIZER };\r
+static _taskPool_t _IotSystemTaskPool = { .dispatchQueue = IOT_DEQUEUE_INITIALIZER };\r
 \r
 /* -------------- Convenience functions to create/recycle/destroy jobs -------------- */\r
 \r
@@ -171,12 +167,10 @@ static IotTaskPoolError_t _performTaskPoolParameterValidation( const IotTaskPool
 /**\r
  * Initializes a pre-allocated instance of a task pool.\r
  *\r
- * @param[in] pInfo The initialization information for the task pool.\r
  * @param[in] pTaskPool The pre-allocated instance of the task pool to initialize.\r
  *\r
  */\r
-static IotTaskPoolError_t _initTaskPoolControlStructures( const IotTaskPoolInfo_t * const pInfo,\r
-                                                          _taskPool_t * const pTaskPool );\r
+static void _initTaskPoolControlStructures( _taskPool_t * const pTaskPool );\r
 \r
 /**\r
  * Initializes a pre-allocated instance of a task pool.\r
@@ -196,14 +190,6 @@ static IotTaskPoolError_t _createTaskPool( const IotTaskPoolInfo_t * const pInfo
  */\r
 static void _destroyTaskPool( _taskPool_t * const pTaskPool );\r
 \r
-/**\r
- * Check for the exit condition.\r
- *\r
- * @param[in] pTaskPool The task pool to destroy.\r
- *\r
- */\r
-static bool _IsShutdownStarted( const _taskPool_t * const pTaskPool );\r
-\r
 /**\r
  * Set the exit condition.\r
  *\r
@@ -224,7 +210,6 @@ static void _signalShutdown( _taskPool_t * const pTaskPool,
  */\r
 static IotTaskPoolError_t _scheduleInternal( _taskPool_t * const pTaskPool,\r
                                              _taskPoolJob_t * const pJob );\r
-\r
 /**\r
  * Matches a deferred job in the timer queue with its timer event wrapper.\r
  *\r
@@ -249,12 +234,27 @@ static IotTaskPoolError_t _tryCancelInternal( _taskPool_t * const pTaskPool,
 \r
 /* ---------------------------------------------------------------------------------------------- */\r
 \r
-IotTaskPool_t IotTaskPool_GetSystemTaskPool( void )\r
-{\r
-    return &_IotSystemTaskPool;\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
+/*\r
+ * The full IoT Task Pool Library has many use cases, including Linux\r
+ * development.  Typical FreeRTOS use cases do not require the full\r
+ * functionality so optimised version is provided specifically for use with\r
+ * FreeRTOS.  Unlike the full version, this optimised version:\r
+ *   + Only supports a single task pool (system task pool) at a time.\r
+ *   + Does not auto-scale by dynamically adding more tasks if the number of\r
+ *   + tasks in the pool becomes exhausted.  The number of tasks in the pool\r
+ *     are fixed at compile time.  See the task pool configuration options for\r
+ *     more information.\r
+ *   + Cannot be shut down - it exists for the lifetime of the application.\r
+ *\r
+ * As such this file does not implement the following API functions:\r
+ *   + IotTaskPool_GetSystemTaskPool()\r
+ *   + IotTaskPool_Create()\r
+ *   + IotTaskPool_Destroy()\r
+ *   + IotTaskPool_SetMaxThreads()\r
+ *\r
+ * Users who are interested in the functionality of the full IoT Task Pool\r
+ * library can us it in place of this optimised version.\r
+ */\r
 \r
 IotTaskPoolError_t IotTaskPool_CreateSystemTaskPool( const IotTaskPoolInfo_t * const pInfo )\r
 {\r
@@ -278,203 +278,6 @@ IotTaskPoolError_t IotTaskPool_CreateSystemTaskPool( const IotTaskPoolInfo_t * c
 \r
     TASKPOOL_NO_FUNCTION_CLEANUP();\r
 }\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-IotTaskPoolError_t IotTaskPool_Create( const IotTaskPoolInfo_t * const pInfo,\r
-                                       IotTaskPool_t * const pTaskPool )\r
-{\r
-    TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );\r
-\r
-    _taskPool_t * pTempTaskPool = NULL;\r
-\r
-    /* Verify that the task pool storage is valid. */\r
-    TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( pTaskPool );\r
-\r
-    /* Parameter checking. */\r
-    TASKPOOL_ON_ERROR_GOTO_CLEANUP( _performTaskPoolParameterValidation( pInfo ) );\r
-\r
-    /* Allocate the memory for the task pool */\r
-    pTempTaskPool = ( _taskPool_t * ) IotTaskPool_MallocTaskPool( sizeof( _taskPool_t ) );\r
-\r
-    if( pTempTaskPool == NULL )\r
-    {\r
-        TASKPOOL_SET_AND_GOTO_CLEANUP( IOT_TASKPOOL_NO_MEMORY );\r
-    }\r
-\r
-    memset( pTempTaskPool, 0x00, sizeof( _taskPool_t ) );\r
-\r
-    TASKPOOL_SET_AND_GOTO_CLEANUP( _createTaskPool( pInfo, pTempTaskPool ) );\r
-\r
-    TASKPOOL_FUNCTION_CLEANUP();\r
-\r
-    if( TASKPOOL_FAILED( status ) )\r
-    {\r
-        if( pTempTaskPool != NULL )\r
-        {\r
-            IotTaskPool_FreeTaskPool( pTempTaskPool );\r
-        }\r
-    }\r
-    else\r
-    {\r
-        *pTaskPool = pTempTaskPool;\r
-    }\r
-\r
-    TASKPOOL_FUNCTION_CLEANUP_END();\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-IotTaskPoolError_t IotTaskPool_Destroy( IotTaskPool_t taskPoolHandle )\r
-{\r
-    TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );\r
-\r
-    uint32_t count;\r
-    bool completeShutdown = true;\r
-\r
-    _taskPool_t * pTaskPool = ( _taskPool_t * ) taskPoolHandle;\r
-\r
-    /* Track how many threads the task pool owns. */\r
-    uint32_t activeThreads;\r
-\r
-    /* Parameter checking. */\r
-    TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( pTaskPool );\r
-\r
-    /* Destroying the task pool should be safe, and therefore we will grab the task pool lock.\r
-     * No worker thread or application thread should access any data structure\r
-     * in the task pool while the task pool is being destroyed. */\r
-    taskENTER_CRITICAL();\r
-    {\r
-        IotLink_t * pItemLink;\r
-\r
-        /* Record how many active threads in the task pool. */\r
-        activeThreads = pTaskPool->activeThreads;\r
-\r
-        /* Destroying a Task pool happens in six (6) stages: First, (1) we clear the job queue and (2) the timer queue.\r
-         * Then (3) we clear the jobs cache. We will then (4) wait for all worker threads to signal exit,\r
-         * before (5) setting the exit condition and wake up all active worker threads. Finally (6) destroying\r
-         * all task pool data structures and release the associated memory.\r
-         */\r
-\r
-        /* (1) Clear the job queue. */\r
-        do\r
-        {\r
-            pItemLink = NULL;\r
-\r
-            pItemLink = IotDeQueue_DequeueHead( &pTaskPool->dispatchQueue );\r
-\r
-            if( pItemLink != NULL )\r
-            {\r
-                _taskPoolJob_t * pJob = IotLink_Container( _taskPoolJob_t, pItemLink, link );\r
-\r
-                _destroyJob( pJob );\r
-            }\r
-        } while( pItemLink );\r
-\r
-        /* (2) Clear the timer queue. */\r
-        {\r
-            _taskPoolTimerEvent_t * pTimerEvent;\r
-\r
-            /* A deferred job may have fired already. Since deferred jobs will go through the same mutex\r
-             * the shutdown sequence is holding at this stage, there is no risk for race conditions. Yet, we\r
-             * need to let the deferred job to destroy the task pool. */\r
-\r
-            pItemLink = IotListDouble_PeekHead( &pTaskPool->timerEventsList );\r
-\r
-            if( pItemLink != NULL )\r
-            {\r
-                TickType_t now = xTaskGetTickCount();\r
-\r
-                pTimerEvent = IotLink_Container( _taskPoolTimerEvent_t, pItemLink, link );\r
-\r
-                if( pTimerEvent->expirationTime <= now )\r
-                {\r
-                    IotLogDebug( "Shutdown will be deferred to the timer thread" );\r
-\r
-                    /* Timer may have fired already! Let the timer thread destroy\r
-                     * complete the taskpool destruction sequence. */\r
-                    completeShutdown = false;\r
-                }\r
-\r
-                /* Remove all timers from the timeout list. */\r
-                for( ; ; )\r
-                {\r
-                    pItemLink = IotListDouble_RemoveHead( &pTaskPool->timerEventsList );\r
-\r
-                    if( pItemLink == NULL )\r
-                    {\r
-                        break;\r
-                    }\r
-\r
-                    pTimerEvent = IotLink_Container( _taskPoolTimerEvent_t, pItemLink, link );\r
-\r
-                    _destroyJob( pTimerEvent->job );\r
-\r
-                    IotTaskPool_FreeTimerEvent( pTimerEvent );\r
-                }\r
-            }\r
-        }\r
-\r
-        /* (3) Clear the job cache. */\r
-        do\r
-        {\r
-            pItemLink = NULL;\r
-\r
-            pItemLink = IotListDouble_RemoveHead( &pTaskPool->jobsCache.freeList );\r
-\r
-            if( pItemLink != NULL )\r
-            {\r
-                _taskPoolJob_t * pJob = IotLink_Container( _taskPoolJob_t, pItemLink, link );\r
-\r
-                _destroyJob( pJob );\r
-            }\r
-        } while( pItemLink );\r
-\r
-        /* (4) Set the exit condition. */\r
-        _signalShutdown( pTaskPool, activeThreads );\r
-    }\r
-    taskEXIT_CRITICAL();\r
-\r
-    /* (5) Wait for all active threads to reach the end of their life-span. */\r
-    for( count = 0; count < activeThreads; ++count )\r
-    {\r
-        xSemaphoreTake( pTaskPool->startStopSignal, portMAX_DELAY );\r
-    }\r
-\r
-    IotTaskPool_Assert( uxSemaphoreGetCount( pTaskPool->startStopSignal ) == 0 );\r
-    IotTaskPool_Assert( pTaskPool->activeThreads == 0 );\r
-\r
-    /* (6) Destroy all signaling objects. */\r
-    if( completeShutdown == true )\r
-    {\r
-        _destroyTaskPool( pTaskPool );\r
-\r
-        /* Do not free the system task pool which is statically allocated. */\r
-        if( pTaskPool != &_IotSystemTaskPool )\r
-        {\r
-            IotTaskPool_FreeTaskPool( pTaskPool );\r
-        }\r
-    }\r
-\r
-    TASKPOOL_NO_FUNCTION_CLEANUP();\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-IotTaskPoolError_t IotTaskPool_SetMaxThreads( IotTaskPool_t taskPoolHandle,\r
-                                              uint32_t maxThreads )\r
-{\r
-    TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );\r
-\r
-    _taskPool_t * pTaskPool = ( _taskPool_t * ) taskPoolHandle;\r
-\r
-    /* Parameter checking. */\r
-    TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( pTaskPool );\r
-    TASKPOOL_ON_ARG_ERROR_GOTO_CLEANUP( maxThreads < 1UL );\r
-\r
-    TASKPOOL_NO_FUNCTION_CLEANUP();\r
-}\r
-\r
 /*-----------------------------------------------------------*/\r
 \r
 IotTaskPoolError_t IotTaskPool_CreateJob( IotTaskPoolRoutine_t userCallback,\r
@@ -559,7 +362,6 @@ IotTaskPoolError_t IotTaskPool_DestroyRecyclableJob( IotTaskPool_t taskPoolHandl
     pool - no other values are allowed.  Use the full implementation of this\r
     library if you want multiple task pools (there is more than one task in\r
     each pool. */\r
-//_RB_could use a TASKPOOL macro to check value and return error.\r
     configASSERT( ( taskPoolHandle == NULL ) || ( taskPoolHandle == &_IotSystemTaskPool ) );\r
 \r
     /* Avoid compiler warnings about unused parameters if configASSERT() is not\r
@@ -688,7 +490,7 @@ IotTaskPoolError_t IotTaskPool_ScheduleDeferred( IotTaskPool_t taskPoolHandle,
         pTimerEvent->link.pNext = NULL;\r
         pTimerEvent->link.pPrevious = NULL;\r
         pTimerEvent->expirationTime = now + pdMS_TO_TICKS( timeMs );\r
-        pTimerEvent->job = job;\r
+        pTimerEvent->job = job; //_RB_ Think up to here can be outside the critical section.\r
 \r
         /* Append the timer event to the timer list. */\r
         IotListDouble_InsertSorted( &pTaskPool->timerEventsList, &pTimerEvent->link, _timerEventCompare );\r
@@ -723,9 +525,15 @@ IotTaskPoolError_t IotTaskPool_GetStatus( IotTaskPool_t taskPoolHandle,
 {\r
     TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );\r
 \r
-    /* Parameter checking. */\r
-//_RB_    TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( taskPoolHandle ); /* What is the point of this parameter? */\r
+    /* This lean version of the task pool only supports the task pool created\r
+    by this library (the system task pool).  NULL means use the system task\r
+    pool - no other values are allowed.  Use the full implementation of this\r
+    library if you want multiple task pools (there is more than one task in\r
+    each pool. */\r
+    configASSERT( ( taskPoolHandle == NULL ) || ( taskPoolHandle == &_IotSystemTaskPool ) );\r
     ( void ) taskPoolHandle;\r
+\r
+    /* Parameter checking. */\r
     TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( job );\r
     TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( pStatus );\r
     *pStatus = IOT_TASKPOOL_STATUS_UNDEFINED;\r
@@ -747,7 +555,7 @@ IotTaskPoolError_t IotTaskPool_TryCancel( IotTaskPool_t taskPoolHandle,
 {\r
     TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );\r
 \r
-    _taskPool_t * pTaskPool = &_IotSystemTaskPool;\r
+    _taskPool_t * const pTaskPool = &_IotSystemTaskPool;\r
 \r
     /* This lean version of the task pool only supports the task pool created\r
     by this library (the system task pool).  NULL means use the system task\r
@@ -835,14 +643,8 @@ static IotTaskPoolError_t _performTaskPoolParameterValidation( const IotTaskPool
     TASKPOOL_NO_FUNCTION_CLEANUP();\r
 }\r
 \r
-static IotTaskPoolError_t _initTaskPoolControlStructures( const IotTaskPoolInfo_t * const pInfo,\r
-                                                          _taskPool_t * const pTaskPool )\r
+static void _initTaskPoolControlStructures( _taskPool_t * const pTaskPool )\r
 {\r
-    TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );\r
-\r
-    bool semStartStopInit = false;\r
-    bool semDispatchInit = false;\r
-\r
     /* Initialize a job data structures that require no de-initialization.\r
      * All other data structures carry a value of 'NULL' before initailization.\r
      */\r
@@ -851,46 +653,9 @@ static IotTaskPoolError_t _initTaskPoolControlStructures( const IotTaskPoolInfo_
 \r
     _initJobsCache( &pTaskPool->jobsCache );\r
 \r
-    /* Initialize the semaphore to ensure all threads have started. */\r
-    pTaskPool->startStopSignal = xSemaphoreCreateCountingStatic( pInfo->minThreads, 0, &pTaskPool->startStopSignalBuffer );\r
-\r
-    if( pTaskPool->startStopSignal != NULL )\r
-    {\r
-        semStartStopInit = true;\r
-\r
-        /* Initialize the semaphore for waiting for incoming work. */\r
-        pTaskPool->dispatchSignal = xSemaphoreCreateCountingStatic( TASKPOOL_MAX_SEM_VALUE, 0, &pTaskPool->dispatchSignalBuffer );\r
-\r
-        if( pTaskPool->dispatchSignal != NULL )\r
-        {\r
-            semDispatchInit = true;\r
-        }\r
-        else\r
-        {\r
-            TASKPOOL_SET_AND_GOTO_CLEANUP( IOT_TASKPOOL_NO_MEMORY );\r
-        }\r
-    }\r
-    else\r
-    {\r
-        TASKPOOL_SET_AND_GOTO_CLEANUP( IOT_TASKPOOL_NO_MEMORY );\r
-    }\r
-\r
-    TASKPOOL_FUNCTION_CLEANUP();\r
-\r
-    if( TASKPOOL_FAILED( status ) )\r
-    {\r
-        if( semStartStopInit )\r
-        {\r
-            vSemaphoreDelete( &pTaskPool->startStopSignal );\r
-        }\r
-\r
-        if( semDispatchInit )\r
-        {\r
-            vSemaphoreDelete( &pTaskPool->dispatchSignal );\r
-        }\r
-    }\r
-\r
-    TASKPOOL_FUNCTION_CLEANUP_END();\r
+    /* Initialize the semaphore for waiting for incoming work.  Cannot fail as\r
+    statically allocated. */\r
+    pTaskPool->dispatchSignal = xSemaphoreCreateCountingStatic( TASKPOOL_MAX_SEM_VALUE, 0, &pTaskPool->dispatchSignalBuffer );\r
 }\r
 \r
 static IotTaskPoolError_t _createTaskPool( const IotTaskPoolInfo_t * const pInfo,\r
@@ -898,7 +663,6 @@ static IotTaskPoolError_t _createTaskPool( const IotTaskPoolInfo_t * const pInfo
 {\r
     TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );\r
 \r
-    uint32_t count;\r
     uint32_t threadsCreated = 0; /* Although initialised before use removing the initialiser here results in compiler warnings. */\r
     char cTaskName[ 10 ];\r
 \r
@@ -909,7 +673,7 @@ static IotTaskPoolError_t _createTaskPool( const IotTaskPoolInfo_t * const pInfo
     memset( ( void * ) pTaskPool, 0x00, sizeof( _taskPool_t ) );\r
 \r
     /* Initialize all internal data structure prior to creating all threads. */\r
-    TASKPOOL_ON_ERROR_GOTO_CLEANUP( _initTaskPoolControlStructures( pInfo, pTaskPool ) );\r
+    _initTaskPoolControlStructures( pTaskPool );\r
 \r
     /* Create the timer for a new connection. */\r
     pTaskPool->timer = xTimerCreate( NULL, portMAX_DELAY, pdFALSE, ( void * ) pTaskPool, _timerCallback );\r
@@ -921,16 +685,15 @@ static IotTaskPoolError_t _createTaskPool( const IotTaskPoolInfo_t * const pInfo
         TASKPOOL_SET_AND_GOTO_CLEANUP( IOT_TASKPOOL_NO_MEMORY );\r
     }\r
 \r
-    /* The task pool will initialize the minimum number of threads requested by the user upon start. */\r
-    /* When a thread is created, it will signal a semaphore to signify that it is about to wait on incoming */\r
-    /* jobs. A thread can be woken up for exit or for new jobs only at that point in time.  */\r
-    /* The exit condition is setting the maximum number of threads to 0. */\r
-\r
+    /* The task pool will initialize the minimum number of threads requested by the user upon start.\r
+    Note this tailored version of the task pool does not autoscale, but fixes the number of tasks\r
+    in the pool to the originally specified minimum, and the specified maximum value is ignored. */\r
     /* Create the minimum number of threads specified by the user, and if one fails shutdown and return error. */\r
     for( threadsCreated = 0; threadsCreated < pInfo->minThreads; )\r
     {\r
-        TaskHandle_t task = NULL; //_RB_ need to check compiles with C89\r
+        TaskHandle_t task = NULL;\r
 \r
+        /* Generate a unique name for the task. */\r
         snprintf( cTaskName, sizeof( cTaskName ), "pool%d", ( int ) threadsCreated );\r
 \r
         BaseType_t res = xTaskCreate( _taskPoolWorker,\r
@@ -941,7 +704,7 @@ static IotTaskPoolError_t _createTaskPool( const IotTaskPoolInfo_t * const pInfo
                                       &task );\r
 \r
         /* Create one thread. */\r
-        if( res == pdFALSE )\r
+        if( res == pdFALSE ) //_RB_ would not be needed if tasks are created statically.\r
         {\r
             IotLogError( "Could not create worker thread! Exiting..." );\r
 \r
@@ -958,24 +721,11 @@ static IotTaskPoolError_t _createTaskPool( const IotTaskPoolInfo_t * const pInfo
 \r
     TASKPOOL_FUNCTION_CLEANUP();\r
 \r
-    /* Wait for threads to be ready to wait on the condition, so that threads are actually able to receive messages. */\r
-    for( count = 0; count < threadsCreated; ++count )\r
-    {\r
-        xSemaphoreTake( pTaskPool->startStopSignal, portMAX_DELAY ); /*_RB_ Is waiting necessary, and if so, is a semaphore necessary? */\r
-    }\r
-\r
     /* In case of failure, wait on the created threads to exit. */\r
     if( TASKPOOL_FAILED( status ) )\r
     {\r
         /* Set the exit condition for the newly created threads. */\r
         _signalShutdown( pTaskPool, threadsCreated );\r
-\r
-        /* Signal all threads to exit. */\r
-        for( count = 0; count < threadsCreated; ++count )\r
-        {\r
-            xSemaphoreTake( pTaskPool->startStopSignal, portMAX_DELAY );\r
-        }\r
-\r
         _destroyTaskPool( pTaskPool );\r
     }\r
 \r
@@ -997,11 +747,6 @@ static void _destroyTaskPool( _taskPool_t * const pTaskPool )
     {\r
         vSemaphoreDelete( pTaskPool->dispatchSignal );\r
     }\r
-\r
-    if( pTaskPool->startStopSignal != NULL )\r
-    {\r
-        vSemaphoreDelete( pTaskPool->startStopSignal );\r
-    }\r
 }\r
 \r
 /* ---------------------------------------------------------------------------------------------- */\r
@@ -1016,9 +761,6 @@ static void _taskPoolWorker( void * pUserContext )
     /* Extract pTaskPool pointer from context. */\r
     _taskPool_t * pTaskPool = ( _taskPool_t * ) pUserContext;\r
 \r
-    /* Signal that this worker completed initialization and it is ready to receive notifications. */\r
-    ( void ) xSemaphoreGive( pTaskPool->startStopSignal );\r
-\r
     /* OUTER LOOP: it controls the lifetiem of the worker thread: exit condition for a worker thread\r
      * is setting maxThreads to zero. A worker thread is running until the maximum number of allowed\r
      * threads is not zero and the active threads are less than the maximum number of allowed threads.\r
@@ -1036,23 +778,6 @@ static void _taskPoolWorker( void * pUserContext )
          */\r
         taskENTER_CRITICAL();\r
         {\r
-            /* If the exit condition is verified, update the number of active threads and exit the loop. */\r
-            if( _IsShutdownStarted( pTaskPool ) )\r
-            {\r
-                IotLogDebug( "Worker thread exiting because exit condition was set." );\r
-\r
-                /* Decrease the number of active threads. */\r
-                pTaskPool->activeThreads--;\r
-\r
-                taskEXIT_CRITICAL();\r
-\r
-                /* Signal that this worker is exiting. */\r
-                xSemaphoreGive( pTaskPool->startStopSignal );\r
-\r
-                /* On shutdown, abandon the OUTER LOOP immediately. */\r
-                break;\r
-            }\r
-\r
             /* Dequeue the first job in FIFO order. */\r
             pFirst = IotDeQueue_DequeueHead( &pTaskPool->dispatchQueue );\r
 \r
@@ -1476,17 +1201,6 @@ static void _timerCallback( TimerHandle_t xTimer )
      */\r
     taskENTER_CRITICAL();\r
     {\r
-        /* Check again for shutdown and bail out early in case. */\r
-        if( _IsShutdownStarted( pTaskPool ) )\r
-        {\r
-            taskEXIT_CRITICAL();\r
-\r
-            /* Complete the shutdown sequence. */\r
-            _destroyTaskPool( pTaskPool );\r
-\r
-            return;\r
-        }\r
-\r
         /* Dispatch all deferred job whose timer expired, then reset the timer for the next\r
          * job down the line. */\r
         for( ; ; )\r