summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_Plus_IoT_SDK/TaskPool/.settings/language.settings.xml2
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_Plus_IoT_SDK/TaskPool/main.c455
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/include/iot_taskpool.h121
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/taskpool/iot_taskpool.c120
4 files changed, 503 insertions, 195 deletions
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_IoT_SDK/TaskPool/.settings/language.settings.xml b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_IoT_SDK/TaskPool/.settings/language.settings.xml
index 782b97ca1..aa36f4810 100644
--- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_IoT_SDK/TaskPool/.settings/language.settings.xml
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_IoT_SDK/TaskPool/.settings/language.settings.xml
@@ -5,7 +5,7 @@
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
- <provider class="org.eclipse.cdt.managedbuilder.internal.language.settings.providers.GCCBuiltinSpecsDetectorMinGW" console="false" env-hash="-610351291490083443" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetectorMinGW" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings MinGW" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
+ <provider class="org.eclipse.cdt.managedbuilder.internal.language.settings.providers.GCCBuiltinSpecsDetectorMinGW" console="false" env-hash="1351656224547092082" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetectorMinGW" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings MinGW" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_IoT_SDK/TaskPool/main.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_IoT_SDK/TaskPool/main.c
index bde06ef93..a18b36663 100644
--- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_IoT_SDK/TaskPool/main.c
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_IoT_SDK/TaskPool/main.c
@@ -29,14 +29,24 @@
#include "FreeRTOS.h"
#include "task.h"
+/* Standard includes. */
+#include <stdio.h>
+
/* IoT SDK includes. */
#include "iot_taskpool.h"
+/* The priority at which that tasks in the task pool (the worker tasks) get
+created. */
+#define tpTASK_POOL_WORKER_PRIORITY 1
+
/*
* Prototypes for the functions that demonstrate the task pool API.
*/
static void prvExample_BasicSingleJob( void );
+static void prvExample_DeferredSingleJob( void );
static void prvExample_BasicRecyclableJob( void );
+static void prvExample_ReuseRecyclableJobFromLowPriorityTask( void );
+static void prvExample_ReuseRecyclableJobFromHighPriorityTask( void );
/* Prototypes of the callback functions used in the examples. */
static void prvSimpleTaskNotifyCallback( IotTaskPool_t pTaskPool, IotTaskPoolJob_t pJob, void *pUserContext );
@@ -65,7 +75,7 @@ static const IotTaskPoolInfo_t xTaskPoolParameters = {
/* Stack size for every task pool thread - in words, not bytes. */
configMINIMAL_STACK_SIZE,
/* Priority for every task pool thread. */
- tskIDLE_PRIORITY,
+ tpTASK_POOL_WORKER_PRIORITY,
};
/*-----------------------------------------------------------*/
@@ -74,12 +84,12 @@ int main( void )
{
/* This example uses a single application task, which in turn is used to
create and send jobs to task pool tasks. */
- xTaskCreate( prvTaskPoolDemoTask,
- "PoolDemo",
- configMINIMAL_STACK_SIZE,
- NULL,
- tskIDLE_PRIORITY,
- NULL );
+ xTaskCreate( prvTaskPoolDemoTask, /* Function that implements the task. */
+ "PoolDemo", /* Text name for the task - only used for debugging. */
+ configMINIMAL_STACK_SIZE, /* Size of stack (in words, not bytes) to allocate for the task. */
+ NULL, /* Task parameter - not used in this case. */
+ tskIDLE_PRIORITY, /* Task priority, must be between 0 and configMAX_PRIORITIES - 1. */
+ NULL ); /* Used to pass out a handle to the created tsak - not used in this case. */
vTaskStartScheduler();
@@ -93,27 +103,61 @@ int main( void )
static void prvTaskPoolDemoTask( void *pvParameters )
{
IotTaskPoolError_t xResult;
+uint32_t ulLoops;
/* Remove compiler warnings about unused parameters. */
( void ) pvParameters;
/* The task pool must be created before it can be used. */
-// xResult = IotTaskPool_CreateSystemTaskPool( &xTaskPoolParameters );
-// configASSERT( xResult == IOT_TASKPOOL_SUCCESS );
+ xResult = IotTaskPool_CreateSystemTaskPool( &xTaskPoolParameters );
+ configASSERT( xResult == IOT_TASKPOOL_SUCCESS );
/* Attempting to create the task pool again should then appear to succeed
(in case it is initialised by more than one library), but have no effect. */
-// xResult = IotTaskPool_CreateSystemTaskPool( &xTaskPoolParameters );
-// configASSERT( xResult == IOT_TASKPOOL_SUCCESS );
+ xResult = IotTaskPool_CreateSystemTaskPool( &xTaskPoolParameters );
+ configASSERT( xResult == IOT_TASKPOOL_SUCCESS );
for( ;; )
{
- /* Run through each task pool example in turn. See the comments in the
- below functions for details of their behaviour. */
+ /* Demonstrate the most basic use case where a non persistent job is
+ created and scheduled to run immediately. The task pool worker tasks
+ (in which the job callback function executes) have a priority above the
+ priority of this task so the job's callback executes as soon as it is
+ scheduled. */
prvExample_BasicSingleJob();
+
+ /* Demonstrate a job being scheduled to run at some time in the
+ future, and how a job scheduled to run in the future can be cancelled if
+ it has not yet started executing. */
+ prvExample_DeferredSingleJob();
+
+ /* Demonstrate the most basic use of a recyclable job. This is similar
+ to prvExample_BasicSingleJob() but using a recyclable job. Creating a
+ recyclable job will re-use a previously created and now spare job from
+ the task pool's job cache if one is available, or otherwise dynamically
+ create a new job if a spare job is not available in the cache but space
+ remains in the cache. */
prvExample_BasicRecyclableJob();
- vTaskDelete( NULL );
+ /* Demonstrate multiple recyclable jobs being created, used, and then
+ re-used. In this the task pool worker tasks (in which the job callback
+ functions execute) have a priority above the priority of this task so
+ the job's callback functions execute as soon as they are scheduled. */
+ prvExample_ReuseRecyclableJobFromLowPriorityTask();
+
+ /* Again demonstrate multiple recyclable jobs being used, but this time
+ the priority of the task pool worker tasks (in which the job callback
+ functions execute) are lower than the priority of this task so the job's
+ callback functions don't execute until this task enteres the blocked
+ state. */
+ prvExample_ReuseRecyclableJobFromHighPriorityTask();
+
+ ulLoops++;
+ if( ( ulLoops % 10UL ) == 0 )
+ {
+ printf( "Performed %u successful iterations.\r\n", ulLoops );
+ fflush( stdout );
+ }
}
}
/*-----------------------------------------------------------*/
@@ -137,10 +181,13 @@ IotTaskPoolJobStorage_t xJobStorage;
IotTaskPoolJob_t xJob;
IotTaskPoolError_t xResult;
uint32_t ulReturn;
-const TickType_t xShortDelay = pdMS_TO_TICKS( 200 );
+const uint32_t ulNoFlags = 0UL;
+const TickType_t xNoDelay = ( TickType_t ) 0;
+size_t xFreeHeapBeforeCreatingJob = xPortGetFreeHeapSize();
+IotTaskPoolJobStatus_t xJobStatus;
- /* Ensure the notification count is 0 before scheduling the job. */
- while( ulTaskNotifyTake( pdTRUE, 0 ) != 0 );
+ /* Don't expect any notifications to be pending yet. */
+ configASSERT( ulTaskNotifyTake( pdTRUE, 0 ) == 0 );
/* Create and schedule a job using the handle of this task as the job's
context and the function that sends a notification to the task handle as
@@ -152,12 +199,111 @@ const TickType_t xShortDelay = pdMS_TO_TICKS( 200 );
&xJob );
configASSERT( xResult == IOT_TASKPOOL_SUCCESS );
- xResult = IotTaskPool_ScheduleSystemJob( xJob, 0 );
+ /* The job has been created but not scheduled so is now ready. */
+ IotTaskPool_GetStatus( NULL, xJob, &xJobStatus );
+ configASSERT( xJobStatus == IOT_TASKPOOL_STATUS_READY );
+
+ /* This is not a persistent (recyclable) job and its storage is on the
+ stack of this function, so the amount of heap space available should not
+ have chanced since entering this function. */
+ configASSERT( xFreeHeapBeforeCreatingJob == xPortGetFreeHeapSize() );
+
+ /* In the full task pool implementation the first parameter is used to
+ pass the handle of the task pool to schedule. The lean task pool
+ implementation used in this demo only supports a single task pool, which
+ is created internally within the library, so the first parameter is NULL. */
+ xResult = IotTaskPool_Schedule( NULL, xJob, ulNoFlags );
configASSERT( xResult == IOT_TASKPOOL_SUCCESS );
- /* Wait for the notification coming from the job's callback function. */
- ulReturn = ulTaskNotifyTake( pdTRUE, xShortDelay );
+ /* Look for the notification coming from the job's callback function. The
+ priority of the task pool worker task that executes the callback is higher
+ than the priority of this task so a block time is not needed - the task pool
+ worker task pre-empts this task and sends the notification (from the job's
+ callback) as soon as the job is scheduled. */
+ ulReturn = ulTaskNotifyTake( pdTRUE, xNoDelay );
configASSERT( ulReturn );
+
+ /* The job's callback has executed so the job has now completed. */
+ IotTaskPool_GetStatus( NULL, xJob, &xJobStatus );
+ configASSERT( xJobStatus == IOT_TASKPOOL_STATUS_COMPLETED );
+}
+/*-----------------------------------------------------------*/
+
+static void prvExample_DeferredSingleJob( void )
+{
+IotTaskPoolJobStorage_t xJobStorage;
+IotTaskPoolJob_t xJob;
+IotTaskPoolError_t xResult;
+uint32_t ulReturn;
+const uint32_t ulShortDelay_ms = 100UL;
+const TickType_t xNoDelay = ( TickType_t ) 0, xAllowableMargin = ( TickType_t ) 5; /* Large margin for Windows port, which is not real time. */
+TickType_t xTimeBefore, xElapsedTime, xShortDelay_ticks;
+size_t xFreeHeapBeforeCreatingJob = xPortGetFreeHeapSize();
+IotTaskPoolJobStatus_t xJobStatus;
+
+ /* Don't expect any notifications to be pending yet. */
+ configASSERT( ulTaskNotifyTake( pdTRUE, 0 ) == 0 );
+
+ /* Create a job using the handle of this task as the job's context and the
+ function that sends a notification to the task handle as the jobs callback
+ function. The job is created using storage allocated on the stack of this
+ function - so no memory is allocated. */
+ xResult = IotTaskPool_CreateJob( prvSimpleTaskNotifyCallback, /* Callback function. */
+ ( void * ) xTaskGetCurrentTaskHandle(), /* Job context. */
+ &xJobStorage,
+ &xJob );
+ configASSERT( xResult == IOT_TASKPOOL_SUCCESS );
+
+ /* The job has been created but not scheduled so is now ready. */
+ IotTaskPool_GetStatus( NULL, xJob, &xJobStatus );
+ configASSERT( xJobStatus == IOT_TASKPOOL_STATUS_READY );
+
+ /* This is not a persistent (recyclable) job and its storage is on the
+ stack of this function, so the amount of heap space available should not
+ have chanced since entering this function. */
+ configASSERT( xFreeHeapBeforeCreatingJob == xPortGetFreeHeapSize() );
+
+ /* Schedule the job to run its callback in xShortDelay_ms milliseconds time.
+ In the full task pool implementation the first parameter is used to pass the
+ handle of the task pool to schedule. The lean task pool implementation used
+ in this demo only supports a single task pool, which is created internally
+ within the library, so the first parameter is NULL. */
+ xResult = IotTaskPool_ScheduleDeferred( NULL, xJob, ulShortDelay_ms );
+ configASSERT( xResult == IOT_TASKPOOL_SUCCESS );
+
+ /* The scheduled job should not have executed yet, so don't expect any
+ notifications and expect the job's status to be 'deferred'. */
+ ulReturn = ulTaskNotifyTake( pdTRUE, xNoDelay );
+ configASSERT( ulReturn == 0 );
+ IotTaskPool_GetStatus( NULL, xJob, &xJobStatus );
+ configASSERT( xJobStatus == IOT_TASKPOOL_STATUS_DEFERRED );
+
+ /* As the job has not yet been executed it can be stopped. */
+ xResult = IotTaskPool_TryCancel( NULL, xJob, &xJobStatus );
+ configASSERT( xResult == IOT_TASKPOOL_SUCCESS );
+ IotTaskPool_GetStatus( NULL, xJob, &xJobStatus );
+ configASSERT( xJobStatus == IOT_TASKPOOL_STATUS_CANCELED );
+
+ /* Schedule the job again, and this time wait until its callback is
+ executed (the callback function sends a notification to this task) to see
+ that it executes at the right time. */
+ xTimeBefore = xTaskGetTickCount();
+ xResult = IotTaskPool_ScheduleDeferred( NULL, xJob, ulShortDelay_ms );
+ configASSERT( xResult == IOT_TASKPOOL_SUCCESS );
+
+ /* Wait twice the deferred execution time to ensure the callback is executed
+ before the call below times out. */
+ ulReturn = ulTaskNotifyTake( pdTRUE, pdMS_TO_TICKS( ulShortDelay_ms * 2UL ) );
+ xElapsedTime = xTaskGetTickCount() - xTimeBefore;
+
+ /* A single notification should not have been received... */
+ configASSERT( ulReturn == 1 );
+
+ /* ...and the time since scheduling the job should be greater than or
+ equal to the deferred execution time - which is converted to ticks for
+ comparison. */
+ xShortDelay_ticks = pdMS_TO_TICKS( ulShortDelay_ms );
+ configASSERT( ( xElapsedTime >= xShortDelay_ticks ) && ( xElapsedTime < ( xShortDelay_ticks + xAllowableMargin ) ) );
}
/*-----------------------------------------------------------*/
@@ -166,27 +312,269 @@ static void prvExample_BasicRecyclableJob( void )
IotTaskPoolJob_t xJob;
IotTaskPoolError_t xResult;
uint32_t ulReturn;
-const TickType_t xShortDelay = pdMS_TO_TICKS( 200 );
+const uint32_t ulNoFlags = 0UL;
+const TickType_t xNoDelay = ( TickType_t ) 0;
+size_t xFreeHeapBeforeCreatingJob = xPortGetFreeHeapSize();
- /* Ensure the notification count is 0 before scheduling the job. */
- while( ulTaskNotifyTake( pdTRUE, 0 ) != 0 );
+ /* Don't expect any notifications to be pending yet. */
+ configASSERT( ulTaskNotifyTake( pdTRUE, 0 ) == 0 );
/* Create and schedule a job using the handle of this task as the job's
context and the function that sends a notification to the task handle as
- the jobs callback function. The job is created as a recyclable job - so it
- is allocated inside the create function, but can then be used again and
- again. */
- xResult = IotTaskPool_CreateRecyclableSystemJob( prvSimpleTaskNotifyCallback,
- ( void * ) xTaskGetCurrentTaskHandle(),
- &xJob );
+ the jobs callback function. The job is created as a recyclable job and in
+ this case the memory used to hold the job status is allocated inside the
+ create function. As the job is persistent it can be used multiple times,
+ as demonstrated in other examples within this demo. In the full task pool
+ implementation the first parameter is used to pass the handle of the task
+ pool this recyclable job is to be associated with. In the lean
+ implementation of the task pool used by this demo there is only one task
+ pool (the system task pool created within the task pool library) so the
+ first parameter is NULL. */
+ xResult = IotTaskPool_CreateRecyclableJob( NULL,
+ prvSimpleTaskNotifyCallback,
+ (void * ) xTaskGetCurrentTaskHandle(),
+ &xJob );
configASSERT( xResult == IOT_TASKPOOL_SUCCESS );
- xResult = IotTaskPool_ScheduleSystemJob( xJob, 0 );
+ /* This recyclable job is persistent, and in this case created dynamically,
+ so expect there to be less heap space then when entering the function. */
+ configASSERT( xPortGetFreeHeapSize() < xFreeHeapBeforeCreatingJob );
+
+ /* In the full task pool implementation the first parameter is used to
+ pass the handle of the task pool to schedule. The lean task pool
+ implementation used in this demo only supports a single task pool, which
+ is created internally within the library, so the first parameter is NULL. */
+ xResult = IotTaskPool_Schedule( NULL, xJob, ulNoFlags );
configASSERT( xResult == IOT_TASKPOOL_SUCCESS );
- /* Wait for the notification coming from the job's callback function. */
- ulReturn = ulTaskNotifyTake( pdTRUE, xShortDelay );
+ /* Look for the notification coming from the job's callback function. The
+ priority of the task pool worker task that executes the callback is higher
+ than the priority of this task so a block time is not needed - the task pool
+ worker task pre-empts this task and sends the notification (from the job's
+ callback) as soon as the job is scheduled. */
+ ulReturn = ulTaskNotifyTake( pdTRUE, xNoDelay );
configASSERT( ulReturn );
+
+ /* Clean up recyclable job. In the full implementation of the task pool
+ the first parameter is used to pass a handle to the task pool the job is
+ associated with. In the lean implementation of the task pool used by this
+ demo there is only one task pool (the system task pool created in the
+ task pool library itself) so the first parameter is NULL. */
+ IotTaskPool_DestroyRecyclableJob( NULL, xJob );
+
+ /* Once the job has been deleted the memory used to hold the job is
+ returned, so the available heap should be exactly as when entering this
+ function. */
+ configASSERT( xPortGetFreeHeapSize() == xFreeHeapBeforeCreatingJob );
+}
+/*-----------------------------------------------------------*/
+
+static void prvExample_ReuseRecyclableJobFromLowPriorityTask( void )
+{
+IotTaskPoolError_t xResult;
+uint32_t x, xIndex, ulNotificationValue;
+const uint32_t ulJobsToCreate = 5UL, ulNoFlags = 0UL;
+IotTaskPoolJob_t xJobs[ ulJobsToCreate ];
+size_t xFreeHeapBeforeCreatingJob = xPortGetFreeHeapSize();
+IotTaskPoolJobStatus_t xJobStatus;
+
+ /* Don't expect any notifications to be pending yet. */
+ configASSERT( ulTaskNotifyTake( pdTRUE, 0 ) == 0 );
+
+ /* Create ulJobsToCreate jobs using the handle of this task as the job's
+ context and the function that sends a notification to the task handle as
+ the jobs callback function. The jobs are created as a recyclable job and
+ in this case the memory to store the job information is allocated within
+ the create function as at this time there are no recyclable jobs in the
+ task pool jobs cache. As the jobs are persistent they can be used multiple
+ times. In the full task pool implementation the first parameter is used to
+ pass the handle of the task pool this recyclable job is to be associated
+ with. In the lean implementation of the task pool used by this demo there
+ is only one task pool (the system task pool created within the task pool
+ library) so the first parameter is NULL. */
+ for( x = 0; x < ulJobsToCreate; x++ )
+ {
+ xResult = IotTaskPool_CreateRecyclableJob( NULL,
+ prvSimpleTaskNotifyCallback,
+ (void * ) xTaskGetCurrentTaskHandle(),
+ &( xJobs[ x ] ) );
+ configASSERT( xResult == IOT_TASKPOOL_SUCCESS );
+
+ /* The job has been created but not scheduled so is now ready. */
+ IotTaskPool_GetStatus( NULL, xJobs[ x ], &xJobStatus );
+ configASSERT( xJobStatus == IOT_TASKPOOL_STATUS_READY );
+ }
+
+ /* Demonstrate that the jobs can be recycled by performing twice the number
+ of iterations of scheduling jobs than there actually are created jobs. This
+ works because the task pool task priorities are above the priority of this
+ task, so the tasks that run the jobs pre-empt this task as soon as a job is
+ ready. */
+ for( x = 0; x < ( ulJobsToCreate * 2UL ); x++ )
+ {
+ /* Make sure array index does not go out of bounds. */
+ xIndex = x % ulJobsToCreate;
+
+ xResult = IotTaskPool_Schedule( NULL, xJobs[ xIndex ], ulNoFlags );
+ configASSERT( xResult == IOT_TASKPOOL_SUCCESS );
+
+ /* The priority of the task pool task(s) is higher than the priority
+ of this task, so the job's callback function should have already
+ executed, sending a notification to this task, and incrementing this
+ task's notification value. */
+ xTaskNotifyWait( 0UL, /* Don't clear any bits on entry. */
+ 0UL, /* Don't clear any bits on exit. */
+ &ulNotificationValue, /* Obtain the notification value. */
+ 0UL ); /* No block time, return immediately. */
+ configASSERT( ulNotificationValue == ( x + 1 ) );
+
+ /* The job's callback has executed so the job is now completed. */
+ IotTaskPool_GetStatus( NULL, xJobs[ xIndex ], &xJobStatus );
+ configASSERT( xJobStatus == IOT_TASKPOOL_STATUS_COMPLETED );
+
+ /* To leave the list of jobs empty we can stop re-creating jobs half
+ way through iterations of this loop. */
+ if( x < ulJobsToCreate )
+ {
+ /* Recycle the job so it can be used again. In the full task pool
+ implementation the first parameter is used to pass the handle of the
+ task pool this job will be associated with. In this lean task pool
+ implementation only the system task pool exists (the task pool created
+ internally to the task pool library) so the first parameter is just
+ passed as NULL. *//*_RB_ Why not recycle it automatically? */
+ IotTaskPool_RecycleJob( NULL, xJobs[ xIndex ] );
+ xResult = IotTaskPool_CreateRecyclableJob( NULL,
+ prvSimpleTaskNotifyCallback,
+ (void * ) xTaskGetCurrentTaskHandle(),
+ &( xJobs[ xIndex ] ) );
+ }
+ }
+
+ /* Clear all the notification value bits again. */
+ xTaskNotifyWait( portMAX_DELAY, /* Clear all bits on entry - portMAX_DELAY is used as it is a portable way of having all bits set. */
+ 0UL, /* Don't clear any bits on exit. */
+ NULL, /* Don't need the notification value this time. */
+ 0UL ); /* No block time, return immediately. */
+ configASSERT( ulTaskNotifyTake( pdTRUE, 0 ) == 0 );
+
+ /* Clean up all the recyclable job. In the full implementation of the task
+ pool the first parameter is used to pass a handle to the task pool the job
+ is associated with. In the lean implementation of the task pool used by
+ this demo there is only one task pool (the system task pool created in the
+ task pool library itself) so the first parameter is NULL. */
+ for( x = 0; x < ulJobsToCreate; x++ )
+ {
+ xResult = IotTaskPool_DestroyRecyclableJob( NULL, xJobs[ x ] );
+ configASSERT( xResult == IOT_TASKPOOL_SUCCESS );
+
+ /* Attempting to destroy the same job twice will fail. */
+//_RB_ vPortFree() asserts because it attempts to free memory again. xResult = IotTaskPool_DestroyRecyclableJob( NULL, xJobs[ x ] );
+// configASSERT( xResult != IOT_TASKPOOL_SUCCESS );
+ }
+
+ /* Once the job has been deleted the memory used to hold the job is
+ returned, so the available heap should be exactly as when entering this
+ function. */
+ configASSERT( xPortGetFreeHeapSize() == xFreeHeapBeforeCreatingJob );
+}
+/*-----------------------------------------------------------*/
+
+static void prvExample_ReuseRecyclableJobFromHighPriorityTask( void )
+{
+IotTaskPoolError_t xResult;
+uint32_t x, ulNotificationValue;
+const uint32_t ulJobsToCreate = 5UL;
+const uint32_t ulNoFlags = 0UL;
+IotTaskPoolJob_t xJobs[ ulJobsToCreate ];
+IotTaskPoolJobStorage_t xJobStorage[ ulJobsToCreate ];
+size_t xFreeHeapBeforeCreatingJob = xPortGetFreeHeapSize();
+TickType_t xShortDelay = pdMS_TO_TICKS( 150 );
+IotTaskPoolJobStatus_t xJobStatus;
+
+ /* Don't expect any notifications to be pending yet. */
+ configASSERT( ulTaskNotifyTake( pdTRUE, 0 ) == 0 );
+
+ /* prvExample_ReuseRecyclableJobFromLowPriorityTask() executes in a task
+ that has a lower [task] priority than the task pool's worker tasks.
+ Therefore a talk pool worker preempts the task that calls
+ prvExample_ReuseRecyclableJobFromHighPriorityTask() as soon as the job is
+ scheduled. prvExample_ReuseRecyclableJobFromHighPriorityTask() reverses the
+ priorities - prvExample_ReuseRecyclableJobFromHighPriorityTask() raises its
+ priority to above the task pool's worker tasks, so the worker tasks do not
+ execute until the calling task enters the blocked state. First raise the
+ priority - passing NULL means raise the priority of the calling task. */
+ vTaskPrioritySet( NULL, tpTASK_POOL_WORKER_PRIORITY + 1 );
+
+ /* Create ulJobsToCreate jobs using the handle of this task as the job's
+ context and the function that sends a notification to the task handle as
+ the jobs callback function. */
+ for( x = 0; x < ulJobsToCreate; x++ )
+ {
+ xResult = IotTaskPool_CreateJob( prvSimpleTaskNotifyCallback, /* Callback function. */
+ ( void * ) xTaskGetCurrentTaskHandle(), /* Job context. */
+ &( xJobStorage[ x ] ),
+ &( xJobs[ x ] ) );
+ configASSERT( xResult == IOT_TASKPOOL_SUCCESS );
+
+ /* This is not a persistent (recyclable) job and its storage is on the
+ stack of this function, so the amount of heap space available should not
+ have chanced since entering this function. */
+ configASSERT( xFreeHeapBeforeCreatingJob == xPortGetFreeHeapSize() );
+ }
+
+ for( x = 0; x < ulJobsToCreate; x++ )
+ {
+ /* Schedule the next job. */
+ xResult = IotTaskPool_Schedule( NULL, xJobs[ x ], ulNoFlags );
+ configASSERT( xResult == IOT_TASKPOOL_SUCCESS );
+
+ /* Although scheduled, the job's callback has not executed, so the job
+ reports itself as scheduled. */
+ IotTaskPool_GetStatus( NULL, xJobs[ x ], &xJobStatus );
+ configASSERT( xJobStatus == IOT_TASKPOOL_STATUS_SCHEDULED );
+
+ /* The priority of the task pool task(s) is lower than the priority
+ of this task, so the job's callback function should not have executed
+ yes, so don't expect the notification value for this task to have
+ changed. */
+ xTaskNotifyWait( 0UL, /* Don't clear any bits on entry. */
+ 0UL, /* Don't clear any bits on exit. */
+ &ulNotificationValue, /* Obtain the notification value. */
+ 0UL ); /* No block time, return immediately. */
+ configASSERT( ulNotificationValue == 0 );
+ }
+
+ /* At this point there are ulJobsToCreate scheduled, but none have executed
+ their callbacks because the priority of this task is higher than the
+ priority of the task pool worker threads. When this task blocks to wait for
+ a notification a worker thread will be able to executes - but as soon as its
+ callback function sends a notification to this task this task will
+ preempt it (because it has a higher priority) so this task only expects to
+ receive one notification at a time. */
+ for( x = 0; x < ulJobsToCreate; x++ )
+ {
+ xTaskNotifyWait( 0UL, /* Don't clear any bits on entry. */
+ 0UL, /* Don't clear any bits on exit. */
+ &ulNotificationValue, /* Obtain the notification value. */
+ xShortDelay ); /* Short delay to allow a task pool worker to execute. */
+ configASSERT( ulNotificationValue == ( x + 1 ) );
+ }
+
+ /* All the scheduled jobs have now executed, so waiting for another
+ notification should timeout without the notification value changing. */
+ xTaskNotifyWait( 0UL, /* Don't clear any bits on entry. */
+ 0UL, /* Don't clear any bits on exit. */
+ &ulNotificationValue, /* Obtain the notification value. */
+ xShortDelay ); /* Short delay to allow a task pool worker to execute. */
+ configASSERT( ulNotificationValue == x );
+
+ /* Reset the priority of this task and clear the notifications ready for the
+ next example. */
+ vTaskPrioritySet( NULL, tskIDLE_PRIORITY );
+ xTaskNotifyWait( portMAX_DELAY, /* Clear all bits on entry - portMAX_DELAY is used as it is a portable way of having all bits set. */
+ 0UL, /* Don't clear any bits on exit. */
+ NULL, /* Don't need the notification value this time. */
+ 0UL ); /* No block time, return immediately. */
}
/*-----------------------------------------------------------*/
@@ -269,6 +657,9 @@ volatile uint32_t ulSetToNonZeroInDebuggerToContinue = 0;
taskENTER_CRITICAL();
{
+ printf( "Assert hit on line %lu of %s\r\n", ulLine, pcFileName );
+ fflush( stdout );
+
/* You can step out of this function to debug the assertion by using
the debugger to set ulSetToNonZeroInDebuggerToContinue to a non-zero
value. */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/include/iot_taskpool.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/include/iot_taskpool.h
index 7e94e7264..a91ccf152 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/include/iot_taskpool.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/include/iot_taskpool.h
@@ -53,11 +53,9 @@
* - @functionname{taskpool_function_setmaxthreads}
* - @functionname{taskpool_function_createjob}
* - @functionname{taskpool_function_createrecyclablejob}
- * - @functionname{taskpool_function_createrecyclablesystemjob}
* - @functionname{taskpool_function_destroyrecyclablejob}
* - @functionname{taskpool_function_recyclejob}
* - @functionname{taskpool_function_schedule}
- * - @functionname{taskpool_function_schedulesystemjob}
* - @functionname{taskpool_function_scheduledeferred}
* - @functionname{taskpool_function_getstatus}
* - @functionname{taskpool_function_trycancel}
@@ -73,11 +71,9 @@
* @functionpage{IotTaskPool_SetMaxThreads,taskpool,setmaxthreads}
* @functionpage{IotTaskPool_CreateJob,taskpool,createjob}
* @functionpage{IotTaskPool_CreateRecyclableJob,taskpool,createrecyclablejob}
- * @functionpage{IotTaskPool_CreateRecyclableSystemJob,taskpool,createrecyclablesystemjob}
* @functionpage{IotTaskPool_DestroyRecyclableJob,taskpool,destroyrecyclablejob}
* @functionpage{IotTaskPool_RecycleJob,taskpool,recyclejob}
* @functionpage{IotTaskPool_Schedule,taskpool,schedule}
- * @functionpage{IotTaskPool_ScheduleSystemJob,taskpool,schedule}
* @functionpage{IotTaskPool_ScheduleDeferred,taskpool,scheduledeferred}
* @functionpage{IotTaskPool_GetStatus,taskpool,getstatus}
* @functionpage{IotTaskPool_TryCancel,taskpool,trycancel}
@@ -164,7 +160,7 @@ IotTaskPoolError_t IotTaskPool_Create( const IotTaskPoolInfo_t * const pInfo,
* This function should be called to destroy one instance of a task pool previously created with a call
* to @ref IotTaskPool_Create or @ref IotTaskPool_CreateSystemTaskPool.
* Calling this fuction release all underlying resources. After calling this function, any job scheduled but not yet executed
- * will be cancelled and destroyed.
+ * will be canceled and destroyed.
* The `taskPool` instance will no longer be valid after this function returns.
*
* @param[in] taskPool A handle to the task pool, e.g. as returned by a call to @ref IotTaskPool_Create or
@@ -247,7 +243,7 @@ IotTaskPoolError_t IotTaskPool_CreateJob( IotTaskPoolRoutine_t userCallback,
* - #IOT_TASKPOOL_NO_MEMORY
* - #IOT_TASKPOOL_SHUTDOWN_IN_PROGRESS
*
- * @note This function will not allocate memory.
+ * @note This function will not allocate memory. //_RB_ Incorrect comment.
*
* @warning A recyclable job should be recycled with a call to @ref IotTaskPool_RecycleJob rather than destroyed.
*
@@ -260,36 +256,6 @@ IotTaskPoolError_t IotTaskPool_CreateRecyclableJob( IotTaskPool_t taskPool,
/* @[declare_taskpool_createrecyclablejob] */
/**
- * brief Creates a job for the system task pool by allocating the job dynamically.
- * The system task pool is the task pool created by @ref IotTaskPool_CreateSystemTaskPool.
- *
- * A recyclable job does not need to be allocated twice, but it can rather be reused through
- * subsequent calls to @ref IotTaskPool_CreateRecyclableJob.
- *
- * @param[in] userCallback A user-specified callback for the job.
- * @param[in] pUserContext A user-specified context for the callback.
- * @param[out] pJob A pointer to an instance of @ref IotTaskPoolJob_t that will be initialized when this
- * function returns successfully. This handle can be used to inspect the job status with
- * @ref IotTaskPool_GetStatus or cancel the job with @ref IotTaskPool_TryCancel, etc....
- *
- * @return One of the following:
- * - #IOT_TASKPOOL_SUCCESS
- * - #IOT_TASKPOOL_BAD_PARAMETER
- * - #IOT_TASKPOOL_NO_MEMORY
- * - #IOT_TASKPOOL_SHUTDOWN_IN_PROGRESS
- *
- * @note This function will not allocate memory.
- *
- * @warning A recyclable job should be recycled with a call to @ref IotTaskPool_RecycleJob rather than destroyed.
- *
- */
-/* @[declare_taskpool_createrecyclablesystemjob] */
-IotTaskPoolError_t IotTaskPool_CreateRecyclableSystemJob( IotTaskPoolRoutine_t userCallback,
- void * pUserContext,
- IotTaskPoolJob_t * const pJob );
-/* @[declare_taskpool_createrecyclablesystemjob] */
-
-/**
* @brief This function un-initializes a job.
*
* This function will destroy a job created with @ref IotTaskPool_CreateRecyclableJob.
@@ -445,88 +411,7 @@ IotTaskPoolError_t IotTaskPool_RecycleJob( IotTaskPool_t taskPool,
IotTaskPoolError_t IotTaskPool_Schedule( IotTaskPool_t taskPool,
IotTaskPoolJob_t job,
uint32_t flags );
-
-/**
- * @brief This function schedules a job created with @ref IotTaskPool_CreateJob or @ref IotTaskPool_CreateRecyclableJob @ref IotTaskPool_CreateRecyclableSystemJob
- * against the system task pool. The system task pool is the task pool created by @ref IotTaskPool_CreateSystemTaskPool.
- *
- * See @ref taskpool_design for a description of the jobs lifetime and interaction with the threads used in the task pool
- * library.
- *
- * @param[in] job A job to schedule for execution. This must be first initialized with a call to @ref IotTaskPool_CreateJob.
- * @param[in] flags Flags to be passed by the user, e.g. to identify the job as high priority by specifying #IOT_TASKPOOL_JOB_HIGH_PRIORITY.
- *
- * @return One of the following:
- * - #IOT_TASKPOOL_SUCCESS
- * - #IOT_TASKPOOL_BAD_PARAMETER
- * - #IOT_TASKPOOL_ILLEGAL_OPERATION
- * - #IOT_TASKPOOL_NO_MEMORY
- * - #IOT_TASKPOOL_SHUTDOWN_IN_PROGRESS
- *
- *
- * @note This function will not allocate memory, so it is guaranteed to succeed if the parameters are correct and the task pool
- * was correctly initialized, and not yet destroyed.
- *
- * <b>Example</b>
- * @code{c}
- * // An example of a user context to pass to a callback through a task pool thread.
- * typedef struct JobUserContext
- * {
- * uint32_t counter;
- * } JobUserContext_t;
- *
- * // An example of a user callback to invoke through a task pool thread.
- * static void ExecutionCb( IotTaskPool_t taskPool, IotTaskPoolJob_t job, void * context )
- * {
- * ( void )taskPool;
- * ( void )job;
- *
- * JobUserContext_t * pUserContext = ( JobUserContext_t * )context;
- *
- * pUserContext->counter++;
- * }
- *
- * void TaskPoolExample( )
- * {
- * JobUserContext_t userContext = { 0 };
- * IotTaskPoolJob_t job;
- *
- * // Create the system task pool. This example assumes the task pool is created successfully.
- * // It is recommended to test the function's return value in production code.
- * IotTaskPool_CreateSystemTaskPool( &xTaskPoolParameters );
- *
- * // Statically allocate one job, schedule it.
- * IotTaskPool_CreateJob( &ExecutionCb, &userContext, &job );
- *
- * IotTaskPoolError_t errorSchedule = IotTaskPool_ScheduleSystemJob( &job, 0 );
- *
- * switch ( errorSchedule )
- * {
- * case IOT_TASKPOOL_SUCCESS:
- * break;
- * case IOT_TASKPOOL_BAD_PARAMETER: // Invalid parameters, such as a NULL handle, can trigger this error.
- * case IOT_TASKPOOL_ILLEGAL_OPERATION: // Scheduling a job that was previously scheduled or destroyed could trigger this error.
- * case IOT_TASKPOOL_NO_MEMORY: // Scheduling a with flag #IOT_TASKPOOL_JOB_HIGH_PRIORITY could trigger this error.
- * case IOT_TASKPOOL_SHUTDOWN_IN_PROGRESS: // Scheduling a job after trying to destroy the task pool could trigger this error.
- * // ASSERT
- * break;
- * default:
- * // ASSERT
- * }
- *
- * //
- * // ... Perform other operations ...
- * //
- *
- * IotTaskPool_Destroy( taskPool );
- * }
- * @endcode
- */
-/* @[declare_taskpool_schedulesystemjob] */
-IotTaskPoolError_t IotTaskPool_ScheduleSystemJob( IotTaskPoolJob_t pJob,
- uint32_t flags );
-
-/* @[declare_taskpool_schedulesystemjob] */
+/* @[declare_taskpool_schedule] */
/**
* @brief This function schedules a job created with @ref IotTaskPool_CreateJob against the task pool
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/taskpool/iot_taskpool.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/taskpool/iot_taskpool.c
index fff69ca83..a01e6423c 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/taskpool/iot_taskpool.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/taskpool/iot_taskpool.c
@@ -32,6 +32,7 @@
/* Standard includes. */
#include <stdbool.h>
+#include <stdio.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
@@ -490,15 +491,6 @@ IotTaskPoolError_t IotTaskPool_CreateJob( IotTaskPoolRoutine_t userCallback,
/*-----------------------------------------------------------*/
-IotTaskPoolError_t IotTaskPool_CreateRecyclableSystemJob( IotTaskPoolRoutine_t userCallback,
- void * pUserContext,
- IotTaskPoolJob_t * const pJob )
-{
- return IotTaskPool_CreateRecyclableJob ( &_IotSystemTaskPool, userCallback, pUserContext, pJob );
-}
-
-/*-----------------------------------------------------------*/
-
IotTaskPoolError_t IotTaskPool_CreateRecyclableJob( IotTaskPool_t taskPoolHandle,
IotTaskPoolRoutine_t userCallback,
void * pUserContext,
@@ -506,11 +498,21 @@ IotTaskPoolError_t IotTaskPool_CreateRecyclableJob( IotTaskPool_t taskPoolHandle
{
TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );
- _taskPool_t * pTaskPool = ( _taskPool_t * ) taskPoolHandle;
+ _taskPool_t * const pTaskPool = &_IotSystemTaskPool;
_taskPoolJob_t * pTempJob = NULL;
+ /* This lean version of the task pool only supports the task pool created
+ by this library (the system task pool). NULL means use the system task
+ pool - no other values are allowed. Use the full implementation of this
+ library if you want multiple task pools (there is more than one task in
+ each pool. */
+ configASSERT( ( taskPoolHandle == NULL ) || ( taskPoolHandle == &_IotSystemTaskPool ) );
+
+ /* Avoid compiler warnings about unused parameters if configASSERT() is not
+ defined. */
+ ( void ) taskPoolHandle;
+
/* Parameter checking. */
- TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( taskPoolHandle );
TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( userCallback );
TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( ppJob );
@@ -542,12 +544,21 @@ IotTaskPoolError_t IotTaskPool_DestroyRecyclableJob( IotTaskPool_t taskPoolHandl
{
TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );
- ( void ) taskPoolHandle;
-
_taskPoolJob_t * pJob = ( _taskPoolJob_t * ) pJobHandle;
+ /* This lean version of the task pool only supports the task pool created
+ by this library (the system task pool). NULL means use the system task
+ pool - no other values are allowed. Use the full implementation of this
+ library if you want multiple task pools (there is more than one task in
+ each pool. */
+#warning could use a TASKPOOL macro to check value and return error.
+ configASSERT( ( taskPoolHandle == NULL ) || ( taskPoolHandle == &_IotSystemTaskPool ) );
+
+ /* Avoid compiler warnings about unused parameters if configASSERT() is not
+ defined. */
+ ( void ) taskPoolHandle;
+
/* Parameter checking. */
- TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( taskPoolHandle );
TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( pJobHandle );
IotTaskPool_Assert( IotLink_IsLinked( &pJob->link ) == false );
@@ -564,10 +575,19 @@ IotTaskPoolError_t IotTaskPool_RecycleJob( IotTaskPool_t taskPoolHandle,
{
TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );
- _taskPool_t * pTaskPool = ( _taskPool_t * ) taskPoolHandle;
+ _taskPool_t * pTaskPool = ( _taskPool_t * ) &_IotSystemTaskPool;
+
+ /* This lean version of the task pool only supports the task pool created
+ by this library (the system task pool). NULL means use the system task
+ pool - no other values are allowed. Use the full implementation of this
+ library if you want multiple task pools (there is more than one task in
+ each pool. */
+ configASSERT( ( taskPoolHandle == NULL ) || ( taskPoolHandle == &_IotSystemTaskPool ) );
+
+ /* Ensure unused parameters do not cause compiler warnings in case
+ configASSERT() is not defined. */
+ ( void ) taskPoolHandle;
- /* Parameter checking. */
- TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( taskPoolHandle );
TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( pJob );
taskENTER_CRITICAL();
@@ -589,12 +609,23 @@ IotTaskPoolError_t IotTaskPool_Schedule( IotTaskPool_t taskPoolHandle,
{
TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );
- _taskPool_t * pTaskPool = ( _taskPool_t * ) taskPoolHandle;
+ _taskPool_t * const pTaskPool = &_IotSystemTaskPool;
+ /* Task pool must have been created. */
configASSERT( pTaskPool->running != false );
+ /* This lean version of the task pool only supports the task pool created
+ by this library (the system task pool). NULL means use the system task
+ pool - no other values are allowed. Use the full implementation of this
+ library if you want multiple task pools (there is more than one task in
+ each pool. */
+ configASSERT( ( taskPoolHandle == NULL ) || ( taskPoolHandle == &_IotSystemTaskPool ) );
+
+ /* Avoid compiler warnings about unused parameters if configASSERT() is not
+ defined. */
+ ( void ) taskPoolHandle;
+
/* Parameter checking. */
- TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( taskPoolHandle );
TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( pJob );
TASKPOOL_ON_ARG_ERROR_GOTO_CLEANUP( ( flags != 0UL ) && ( flags != IOT_TASKPOOL_JOB_HIGH_PRIORITY ) );
@@ -609,24 +640,21 @@ IotTaskPoolError_t IotTaskPool_Schedule( IotTaskPool_t taskPoolHandle,
/*-----------------------------------------------------------*/
-IotTaskPoolError_t IotTaskPool_ScheduleSystemJob( IotTaskPoolJob_t pJob,
- uint32_t flags )
-{
- return IotTaskPool_Schedule( &_IotSystemTaskPool, pJob, flags );
-}
-
-/*-----------------------------------------------------------*/
-
IotTaskPoolError_t IotTaskPool_ScheduleDeferred( IotTaskPool_t taskPoolHandle,
IotTaskPoolJob_t job,
uint32_t timeMs )
{
TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );
- _taskPool_t * pTaskPool = ( _taskPool_t * ) taskPoolHandle;
+ _taskPool_t * pTaskPool = &_IotSystemTaskPool;
+
+ /* This lean version of the task pool only supports the task pool created
+ by this library (the system task pool). NULL means use the system task
+ pool - no other values are allowed. Use the full implementation of this
+ library if you want multiple task pools (there is more than one task in
+ each pool. */
+ configASSERT( ( taskPoolHandle == NULL ) || ( taskPoolHandle == &_IotSystemTaskPool ) );
- /* Parameter checking. */
- TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( taskPoolHandle );
TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( job );
if( timeMs == 0UL )
@@ -688,7 +716,8 @@ IotTaskPoolError_t IotTaskPool_GetStatus( IotTaskPool_t taskPoolHandle,
TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );
/* Parameter checking. */
- TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( taskPoolHandle );
+//_RB_ TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( taskPoolHandle ); /* What is the point of this parameter? */
+ ( void ) taskPoolHandle;
TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( job );
TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( pStatus );
*pStatus = IOT_TASKPOOL_STATUS_UNDEFINED;
@@ -710,10 +739,14 @@ IotTaskPoolError_t IotTaskPool_TryCancel( IotTaskPool_t taskPoolHandle,
{
TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );
- _taskPool_t * pTaskPool = ( _taskPool_t * ) taskPoolHandle;
+ _taskPool_t * pTaskPool = &_IotSystemTaskPool;
- /* Parameter checking. */
- TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( taskPoolHandle );
+ /* This lean version of the task pool only supports the task pool created
+ by this library (the system task pool). NULL means use the system task
+ pool - no other values are allowed. Use the full implementation of this
+ library if you want multiple task pools (there is more than one task in
+ each pool. */
+ configASSERT( ( taskPoolHandle == NULL ) || ( taskPoolHandle == &_IotSystemTaskPool ) );
TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( job );
if( pStatus != NULL )
@@ -859,6 +892,7 @@ static IotTaskPoolError_t _createTaskPool( const IotTaskPoolInfo_t * const pInfo
uint32_t count;
uint32_t threadsCreated;
+ char cTaskName[ 10 ];
/* Check input values for consistency. */
TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( pTaskPool );
@@ -887,10 +921,12 @@ static IotTaskPoolError_t _createTaskPool( const IotTaskPoolInfo_t * const pInfo
/* Create the minimum number of threads specified by the user, and if one fails shutdown and return error. */
for( threadsCreated = 0; threadsCreated < pInfo->minThreads; )
{
- TaskHandle_t task = NULL;
+ TaskHandle_t task = NULL; //_RB_ need to check compiles with C89
+
+ snprintf( cTaskName, sizeof( cTaskName ), "pool%d", ( int ) threadsCreated );
BaseType_t res = xTaskCreate( _taskPoolWorker,
- NULL,
+ cTaskName,
pInfo->stackSize,
pTaskPool,
pInfo->priority,
@@ -1019,7 +1055,7 @@ static void _taskPoolWorker( void * pUserContext )
pJob = IotLink_Container( _taskPoolJob_t, pFirst, link );
/* Update status to 'executing'. */
- pJob->status = IOT_TASKPOOL_STATUS_COMPLETED;
+ pJob->status = IOT_TASKPOOL_STATUS_COMPLETED; /*_RB_ Should this be 'executing'? */
userCallback = pJob->userCallback;
}
}
@@ -1156,7 +1192,7 @@ static void _recycleJob( _taskPoolCache_t * const pCache,
_taskPoolJob_t * const pJob )
{
/* We should never try and recycling a job that is linked into some queue. */
- IotTaskPool_Assert( IotLink_IsLinked( &pJob->link ) == false );
+ IotTaskPool_Assert( IotLink_IsLinked( &pJob->link ) == false );//_RB_ Seems to be duplicate of test before this is called.
/* We will recycle the job if there is space in the cache. */
if( pCache->freeCount < IOT_TASKPOOL_JOBS_RECYCLE_LIMIT )
@@ -1232,15 +1268,11 @@ static IotTaskPoolError_t _scheduleInternal( _taskPool_t * const pTaskPool,
/* Update the job status to 'scheduled'. */
pJob->status = IOT_TASKPOOL_STATUS_SCHEDULED;
- BaseType_t higherPriorityTaskWoken;
-
/* Append the job to the dispatch queue. */
IotDeQueue_EnqueueTail( &pTaskPool->dispatchQueue, &pJob->link );
/* Signal a worker to pick up the job. */
- ( void ) xSemaphoreGiveFromISR( pTaskPool->dispatchSignal, &higherPriorityTaskWoken );
-
- portYIELD_FROM_ISR( higherPriorityTaskWoken );
+ xSemaphoreGive( pTaskPool->dispatchSignal );
TASKPOOL_NO_FUNCTION_CLEANUP_NOLABEL();
}
@@ -1333,7 +1365,7 @@ static IotTaskPoolError_t _tryCancelInternal( _taskPool_t * const pTaskPool,
{
bool shouldReschedule = false;
- /* If the job being cancelled was at the head of the timeouts queue, then we need to reschedule the timer
+ /* If the job being canceled was at the head of the timeouts queue, then we need to reschedule the timer
* with the next job timeout */
IotLink_t * pHeadLink = IotListDouble_PeekHead( &pTaskPool->timerEventsList );