@ -41,10 +41,6 @@
created . */
created . */
# define tpTASK_POOL_WORKER_PRIORITY 1
# define tpTASK_POOL_WORKER_PRIORITY 1
/* The number of jobs created in the example functions that create more than
one job . */
# define tpJOBS_TO_CREATE 5
/*
/*
* Prototypes for the functions that demonstrate the task pool API .
* Prototypes for the functions that demonstrate the task pool API .
* See the implementation of the prvTaskPoolDemoTask ( ) function within this file
* See the implementation of the prvTaskPoolDemoTask ( ) function within this file
@ -75,27 +71,27 @@ static void prvTaskPoolDemoTask( void *pvParameters );
/*-----------------------------------------------------------*/
/*-----------------------------------------------------------*/
/* Parameters used to create the system task pool - see TBD for more information
/* Parameters used to create the system task pool - see TBD for more information
as the task pool used in this example is a slimmed down version of the full
* as the task pool used in this example is a slimmed down version of the full
library - the slimmed down version being intended specifically for FreeRTOS
* library - the slimmed down version being intended specifically for FreeRTOS
kernel use cases . */
* kernel use cases . */
static const IotTaskPoolInfo_t xTaskPoolParameters = {
static const IotTaskPoolInfo_t xTaskPoolParameters = {
/* Minimum number of threads in a task pool.
/* Minimum number of threads in a task pool.
Note the slimmed down version of the task
* Note the slimmed down version of the task
pool used by this library does not autoscale
* pool used by this library does not autoscale
the number of tasks in the pool so in this
* the number of tasks in the pool so in this
case this sets the number of tasks in the
* case this sets the number of tasks in the
pool . */
* pool . */
2 ,
2 ,
/* Maximum number of threads in a task pool.
/* Maximum number of threads in a task pool.
Note the slimmed down version of the task
* Note the slimmed down version of the task
pool used by this library does not autoscale
* pool used by this library does not autoscale
the number of tasks in the pool so in this
* the number of tasks in the pool so in this
case this parameter is just ignored . */
* case this parameter is just ignored . */
2 ,
2 ,
/* Stack size for every task pool thread - in
/* Stack size for every task pool thread - in
bytes , hence multiplying by the number of bytes
* bytes , hence multiplying by the number of bytes
in a word as configMINIMAL_STACK_SIZE is
* in a word as configMINIMAL_STACK_SIZE is
specified in words . */
* specified in words . */
configMINIMAL_STACK_SIZE * sizeof ( portSTACK_TYPE ) ,
configMINIMAL_STACK_SIZE * sizeof ( portSTACK_TYPE ) ,
/* Priority for every task pool thread. */
/* Priority for every task pool thread. */
tpTASK_POOL_WORKER_PRIORITY ,
tpTASK_POOL_WORKER_PRIORITY ,
@ -106,13 +102,13 @@ static const IotTaskPoolInfo_t xTaskPoolParameters = {
void vStartSimpleTaskPoolDemo ( void )
void vStartSimpleTaskPoolDemo ( void )
{
{
/* This example uses a single application task, which in turn is used to
/* This example uses a single application task, which in turn is used to
create and send jobs to task pool tasks . */
* create and send jobs to task pool tasks . */
xTaskCreate ( prvTaskPoolDemoTask , /* Function that implements the task. */
xTaskCreate ( prvTaskPoolDemoTask , /* Function that implements the task. */
" PoolDemo " , /* Text name for the task - only used for debugging. */
" 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. */
configMINIMAL_STACK_SIZE , /* Size of stack (in words, not bytes) to allocate for the task. */
NULL , /* Task parameter - not used in this case. */
NULL , /* Task parameter - not used in this case. */
tskIDLE_PRIORITY , /* Task priority, must be between 0 and configMAX_PRIORITIES - 1. */
tskIDLE_PRIORITY , /* Task priority, must be between 0 and configMAX_PRIORITIES - 1. */
NULL ) ; /* Used to pass out a handle to the created t s ak - not used in this case. */
NULL ) ; /* Used to pass out a handle to the created t as k - not used in this case. */
}
}
/*-----------------------------------------------------------*/
/*-----------------------------------------------------------*/
@ -125,49 +121,49 @@ uint32_t ulLoops = 0;
( void ) pvParameters ;
( void ) pvParameters ;
/* The task pool must be created before it can be used. The system task
/* The task pool must be created before it can be used. The system task
pool is the task pool managed by the task pool library itself - the storage
* pool is the task pool managed by the task pool library itself - the storage
used by the task pool is provided by the library . */
* used by the task pool is provided by the library . */
xResult = IotTaskPool_CreateSystemTaskPool ( & xTaskPoolParameters ) ;
xResult = IotTaskPool_CreateSystemTaskPool ( & xTaskPoolParameters ) ;
configASSERT ( xResult = = IOT_TASKPOOL_SUCCESS ) ;
configASSERT ( xResult = = IOT_TASKPOOL_SUCCESS ) ;
/* Attempting to create the task pool again should then appear to succeed
/* 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 . */
* ( in case it is initialised by more than one library ) , but have no effect . */
xResult = IotTaskPool_CreateSystemTaskPool ( & xTaskPoolParameters ) ;
xResult = IotTaskPool_CreateSystemTaskPool ( & xTaskPoolParameters ) ;
configASSERT ( xResult = = IOT_TASKPOOL_SUCCESS ) ;
configASSERT ( xResult = = IOT_TASKPOOL_SUCCESS ) ;
for ( ; ; )
for ( ; ; )
{
{
/* Demonstrate the most basic use case where a non persistent job is
/* Demonstrate the most basic use case where a non persistent job is
created and scheduled to run immediately . The task pool worker tasks
* created and scheduled to run immediately . The task pool worker tasks
( in which the job callback function executes ) have a priority above the
* ( 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
* priority of this task so the job ' s callback executes as soon as it is
scheduled . */
* scheduled . */
prvExample_BasicSingleJob ( ) ;
prvExample_BasicSingleJob ( ) ;
/* Demonstrate a job being scheduled to run at some time in the
/* 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
* future , and how a job scheduled to run in the future can be cancelled
it has not yet started executing . */
* if it has not yet started executing . */
prvExample_DeferredJobAndCancellingJobs ( ) ;
prvExample_DeferredJobAndCancellingJobs ( ) ;
/* Demonstrate the most basic use of a recyclable job. This is similar
/* Demonstrate the most basic use of a recyclable job. This is similar
to prvExample_BasicSingleJob ( ) but using a recyclable job . Creating a
* to prvExample_BasicSingleJob ( ) but using a recyclable job . Creating a
recyclable job will re - use a previously created and now spare job from
* 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
* 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
* create a new job if a spare job is not available in the cache but space
remains in the cache . */
* remains in the cache . */
prvExample_BasicRecyclableJob ( ) ;
prvExample_BasicRecyclableJob ( ) ;
/* Demonstrate multiple recyclable jobs being created, used, and then
/* Demonstrate a recyclable job being created, used, and then re-used.
re - used . In this the task pool worker tasks ( in which the job callback
* In this the task pool worker tasks ( in which the job callback
functions execute ) have a priority above the priority of this task so
* functions execute ) have a priority above the priority of this task so
the job ' s callback functions execute as soon as they are scheduled . */
* the job ' s callback functions execute as soon as they are scheduled . */
prvExample_ReuseRecyclableJobFromLowPriorityTask ( ) ;
prvExample_ReuseRecyclableJobFromLowPriorityTask ( ) ;
/* Again demonstrate multiple recyclable jobs being used, but this time
/* Again demonstrate a recyclable job being created, used, and then
the priority of the task pool worker tasks ( in which the job callback
* re - usedbut this time the priority of the task pool worker tasks ( in
functions execute ) are lower than the priority of this task so the job ' s
* which the job callback functions execute ) are lower than the priority
callback functions don ' t execute until this task enteres the blocked
* of this task so the job ' s callback functions don ' t execute until this
state . */
* task enters the blocked state . */
prvExample_ReuseRecyclableJobFromHighPriorityTask ( ) ;
prvExample_ReuseRecyclableJobFromHighPriorityTask ( ) ;
ulLoops + + ;
ulLoops + + ;
@ -183,7 +179,7 @@ uint32_t ulLoops = 0;
static void prvSimpleTaskNotifyCallback ( IotTaskPool_t pTaskPool , IotTaskPoolJob_t pJob , void * pUserContext )
static void prvSimpleTaskNotifyCallback ( IotTaskPool_t pTaskPool , IotTaskPoolJob_t pJob , void * pUserContext )
{
{
/* The jobs context is the handle of the task to which a notification should
/* The jobs context is the handle of the task to which a notification should
be sent . */
* be sent . */
TaskHandle_t xTaskToNotify = ( TaskHandle_t ) pUserContext ;
TaskHandle_t xTaskToNotify = ( TaskHandle_t ) pUserContext ;
/* Remove warnings about unused parameters. */
/* Remove warnings about unused parameters. */
@ -207,15 +203,15 @@ size_t xFreeHeapBeforeCreatingJob = xPortGetFreeHeapSize();
IotTaskPoolJobStatus_t xJobStatus ;
IotTaskPoolJobStatus_t xJobStatus ;
/* Don't expect any notifications to be pending yet. */
/* Don't expect any notifications to be pending yet. */
configASSERT ( ulTaskNotifyTake ( pdTRUE , 0 ) = = 0 ) ;
configASSERT ( ulTaskNotifyTake ( pdTRUE , xNoDelay ) = = 0 ) ;
/* Create and schedule a job using the handle of this task as the job's
/* 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
* context and the function that sends a notification to the task handle as
the job s callback function . This is not a recyclable job so the storage
* the job ' s callback function . This is not a recyclable job so the storage
required to hold information about the job is provided by this task - in
* required to hold information about the job is provided by this task - in
this case the storage is on the stack of this task so no memory is allocated
* this case the storage is on the stack of this task so no memory is allocated
dynamically but the stack frame must remain in scope for the lifetime of
* dynamically but the stack frame must remain in scope for the lifetime of
the job . */
* the job . */
xResult = IotTaskPool_CreateJob ( prvSimpleTaskNotifyCallback , /* Callback function. */
xResult = IotTaskPool_CreateJob ( prvSimpleTaskNotifyCallback , /* Callback function. */
( void * ) xTaskGetCurrentTaskHandle ( ) , /* Job context. */
( void * ) xTaskGetCurrentTaskHandle ( ) , /* Job context. */
& xJobStorage ,
& xJobStorage ,
@ -227,22 +223,22 @@ IotTaskPoolJobStatus_t xJobStatus;
configASSERT ( xJobStatus = = IOT_TASKPOOL_STATUS_READY ) ;
configASSERT ( xJobStatus = = IOT_TASKPOOL_STATUS_READY ) ;
/* This is not a persistent (recyclable) job and its storage is on the
/* 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
* stack of this function , so the amount of heap space available should not
have chanc ed since entering this function . */
* have chang ed since entering this function . */
configASSERT ( xFreeHeapBeforeCreatingJob = = xPortGetFreeHeapSize ( ) ) ;
configASSERT ( xFreeHeapBeforeCreatingJob = = xPortGetFreeHeapSize ( ) ) ;
/* In the full task pool implementation the first parameter is used to
/* 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
* 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
* implementation used in this demo only supports a single task pool , which
is created internally within the library , so the first parameter is NULL . */
* is created internally within the library , so the first parameter is NULL . */
xResult = IotTaskPool_Schedule ( NULL , xJob , ulNoFlags ) ;
xResult = IotTaskPool_Schedule ( NULL , xJob , ulNoFlags ) ;
configASSERT ( xResult = = IOT_TASKPOOL_SUCCESS ) ;
configASSERT ( xResult = = IOT_TASKPOOL_SUCCESS ) ;
/* Look for the notification coming from the job's callback function. The
/* 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
* 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
* 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
* worker task pre empts this task and sends the notification ( from the job ' s
callback ) as soon as the job is scheduled . */
* callback ) as soon as the job is scheduled . */
ulReturn = ulTaskNotifyTake ( pdTRUE , xNoDelay ) ;
ulReturn = ulTaskNotifyTake ( pdTRUE , xNoDelay ) ;
configASSERT ( ulReturn ) ;
configASSERT ( ulReturn ) ;
@ -265,12 +261,12 @@ size_t xFreeHeapBeforeCreatingJob = xPortGetFreeHeapSize();
IotTaskPoolJobStatus_t xJobStatus ;
IotTaskPoolJobStatus_t xJobStatus ;
/* Don't expect any notifications to be pending yet. */
/* Don't expect any notifications to be pending yet. */
configASSERT ( ulTaskNotifyTake ( pdTRUE , 0 ) = = 0 ) ;
configASSERT ( ulTaskNotifyTake ( pdTRUE , xNoDelay ) = = 0 ) ;
/* Create a job using the handle of this task as the job's context and the
/* 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 job s callback
* function that sends a notification to the task handle as the job ' s callback
function . The job is created using storage allocated on the stack of this
* function . The job is created using storage allocated on the stack of this
function - so no memory is allocated . */
* function - so no memory is allocated . */
xResult = IotTaskPool_CreateJob ( prvSimpleTaskNotifyCallback , /* Callback function. */
xResult = IotTaskPool_CreateJob ( prvSimpleTaskNotifyCallback , /* Callback function. */
( void * ) xTaskGetCurrentTaskHandle ( ) , /* Job context. */
( void * ) xTaskGetCurrentTaskHandle ( ) , /* Job context. */
& xJobStorage ,
& xJobStorage ,
@ -282,49 +278,49 @@ IotTaskPoolJobStatus_t xJobStatus;
configASSERT ( xJobStatus = = IOT_TASKPOOL_STATUS_READY ) ;
configASSERT ( xJobStatus = = IOT_TASKPOOL_STATUS_READY ) ;
/* This is not a persistent (recyclable) job and its storage is on the
/* 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
* stack of this function , so the amount of heap space available should not
have chanc ed since entering this function . */
* have chang ed since entering this function . */
configASSERT ( xFreeHeapBeforeCreatingJob = = xPortGetFreeHeapSize ( ) ) ;
configASSERT ( xFreeHeapBeforeCreatingJob = = xPortGetFreeHeapSize ( ) ) ;
/* Schedule the job to run its callback in x ShortDelay_ms milliseconds time.
/* Schedule the job to run its callback in ul ShortDelay_ms milliseconds time.
In the full task pool implementation the first parameter is used to pass the
* 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
* 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
* in this demo only supports a single task pool , which is created internally
within the library , so the first parameter is NULL . */
* within the library , so the first parameter is NULL . */
xResult = IotTaskPool_ScheduleDeferred ( NULL , xJob , ulShortDelay_ms ) ;
xResult = IotTaskPool_ScheduleDeferred ( NULL , xJob , ulShortDelay_ms ) ;
configASSERT ( xResult = = IOT_TASKPOOL_SUCCESS ) ;
configASSERT ( xResult = = IOT_TASKPOOL_SUCCESS ) ;
/* The scheduled job should not have executed yet, so don't expect any
/* The scheduled job should not have executed yet, so don't expect any
notifications and expect the job ' s status to be ' deferred ' . */
* notifications and expect the job ' s status to be ' deferred ' . */
ulReturn = ulTaskNotifyTake ( pdTRUE , xNoDelay ) ;
ulReturn = ulTaskNotifyTake ( pdTRUE , xNoDelay ) ;
configASSERT ( ulReturn = = 0 ) ;
configASSERT ( ulReturn = = 0 ) ;
IotTaskPool_GetStatus ( NULL , xJob , & xJobStatus ) ;
IotTaskPool_GetStatus ( NULL , xJob , & xJobStatus ) ;
configASSERT ( xJobStatus = = IOT_TASKPOOL_STATUS_DEFERRED ) ;
configASSERT ( xJobStatus = = IOT_TASKPOOL_STATUS_DEFERRED ) ;
/* As the job has not yet been executed it can be stopp ed. */
/* As the job has not yet been executed it can be cancell ed. */
xResult = IotTaskPool_TryCancel ( NULL , xJob , & xJobStatus ) ;
xResult = IotTaskPool_TryCancel ( NULL , xJob , & xJobStatus ) ;
configASSERT ( xResult = = IOT_TASKPOOL_SUCCESS ) ;
configASSERT ( xResult = = IOT_TASKPOOL_SUCCESS ) ;
IotTaskPool_GetStatus ( NULL , xJob , & xJobStatus ) ;
IotTaskPool_GetStatus ( NULL , xJob , & xJobStatus ) ;
configASSERT ( xJobStatus = = IOT_TASKPOOL_STATUS_CANCELED ) ;
configASSERT ( xJobStatus = = IOT_TASKPOOL_STATUS_CANCELED ) ;
/* Schedule the job again, and this time wait until its callback is
/* Schedule the job again, and this time wait until its callback is
executed ( the callback function sends a notification to this task ) to see
* executed ( the callback function sends a notification to this task ) to see
that it executes at the right time . */
* that it executes at the right time . */
xTimeBefore = xTaskGetTickCount ( ) ;
xTimeBefore = xTaskGetTickCount ( ) ;
xResult = IotTaskPool_ScheduleDeferred ( NULL , xJob , ulShortDelay_ms ) ;
xResult = IotTaskPool_ScheduleDeferred ( NULL , xJob , ulShortDelay_ms ) ;
configASSERT ( xResult = = IOT_TASKPOOL_SUCCESS ) ;
configASSERT ( xResult = = IOT_TASKPOOL_SUCCESS ) ;
/* Wait twice the deferred execution time to ensure the callback is executed
/* Wait twice the deferred execution time to ensure the callback is executed
before the call below times out . */
* before the call below times out . */
ulReturn = ulTaskNotifyTake ( pdTRUE , pdMS_TO_TICKS ( ulShortDelay_ms * 2UL ) ) ;
ulReturn = ulTaskNotifyTake ( pdTRUE , pdMS_TO_TICKS ( ulShortDelay_ms * 2UL ) ) ;
xElapsedTime = xTaskGetTickCount ( ) - xTimeBefore ;
xElapsedTime = xTaskGetTickCount ( ) - xTimeBefore ;
/* A single notification should not have been received... */
/* A single notification should have been received... */
configASSERT ( ulReturn = = 1 ) ;
configASSERT ( ulReturn = = 1 ) ;
/* ...and the time since scheduling the job should be greater than or
/* ...and the time since scheduling the job should be greater than or
equal to the deferred execution time - which is converted to ticks for
* equal to the deferred execution time - which is converted to ticks for
comparison . */
* comparison . */
xShortDelay_ticks = pdMS_TO_TICKS ( ulShortDelay_ms ) ;
xShortDelay_ticks = pdMS_TO_TICKS ( ulShortDelay_ms ) ;
configASSERT ( ( xElapsedTime > = xShortDelay_ticks ) & & ( xElapsedTime < ( xShortDelay_ticks + xAllowableMargin ) ) ) ;
configASSERT ( ( xElapsedTime > = xShortDelay_ticks ) & & ( xElapsedTime < ( xShortDelay_ticks + xAllowableMargin ) ) ) ;
}
}
@ -340,19 +336,19 @@ const TickType_t xNoDelay = ( TickType_t ) 0;
size_t xFreeHeapBeforeCreatingJob = xPortGetFreeHeapSize ( ) ;
size_t xFreeHeapBeforeCreatingJob = xPortGetFreeHeapSize ( ) ;
/* Don't expect any notifications to be pending yet. */
/* Don't expect any notifications to be pending yet. */
configASSERT ( ulTaskNotifyTake ( pdTRUE , 0 ) = = 0 ) ;
configASSERT ( ulTaskNotifyTake ( pdTRUE , xNoDelay ) = = 0 ) ;
/* Create and schedule a job using the handle of this task as the job's
/* 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
* context and the function that sends a notification to the task handle as
the job s callback function . The job is created as a recyclable job and in
* the job ' s 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
* 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 ,
* 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
* 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
* 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
* 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
* 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
* pool ( the system task pool created within the task pool library ) so the
first parameter is NULL . */
* first parameter is NULL . */
xResult = IotTaskPool_CreateRecyclableJob ( NULL ,
xResult = IotTaskPool_CreateRecyclableJob ( NULL ,
prvSimpleTaskNotifyCallback ,
prvSimpleTaskNotifyCallback ,
( void * ) xTaskGetCurrentTaskHandle ( ) ,
( void * ) xTaskGetCurrentTaskHandle ( ) ,
@ -360,34 +356,34 @@ size_t xFreeHeapBeforeCreatingJob = xPortGetFreeHeapSize();
configASSERT ( xResult = = IOT_TASKPOOL_SUCCESS ) ;
configASSERT ( xResult = = IOT_TASKPOOL_SUCCESS ) ;
/* This recyclable job is persistent, and in this case created dynamically,
/* This recyclable job is persistent, and in this case created dynamically,
so expect there to be less heap space th e n when entering the function . */
* so expect there to be less heap space th a n when entering the function . */
configASSERT ( xPortGetFreeHeapSize ( ) < xFreeHeapBeforeCreatingJob ) ;
configASSERT ( xPortGetFreeHeapSize ( ) < xFreeHeapBeforeCreatingJob ) ;
/* In the full task pool implementation the first parameter is used to
/* 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
* 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
* implementation used in this demo only supports a single task pool , which
is created internally within the library , so the first parameter is NULL . */
* is created internally within the library , so the first parameter is NULL . */
xResult = IotTaskPool_Schedule ( NULL , xJob , ulNoFlags ) ;
xResult = IotTaskPool_Schedule ( NULL , xJob , ulNoFlags ) ;
configASSERT ( xResult = = IOT_TASKPOOL_SUCCESS ) ;
configASSERT ( xResult = = IOT_TASKPOOL_SUCCESS ) ;
/* Look for the notification coming from the job's callback function. The
/* 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
* 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
* 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
* worker task pre empts this task and sends the notification ( from the job ' s
callback ) as soon as the job is scheduled . */
* callback ) as soon as the job is scheduled . */
ulReturn = ulTaskNotifyTake ( pdTRUE , xNoDelay ) ;
ulReturn = ulTaskNotifyTake ( pdTRUE , xNoDelay ) ;
configASSERT ( ulReturn ) ;
configASSERT ( ulReturn ) ;
/* Clean up recyclable job. In the full implementation of the task pool
/* 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
* 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
* 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
* demo there is only one task pool ( the system task pool created in the
task pool library itself ) so the first parameter is NULL . */
* task pool library itself ) so the first parameter is NULL . */
IotTaskPool_DestroyRecyclableJob ( NULL , xJob ) ;
IotTaskPool_DestroyRecyclableJob ( NULL , xJob ) ;
/* Once the job has been deleted the memory used to hold the job is
/* 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
* returned , so the available heap should be exactly as when entering this
function . */
* function . */
configASSERT ( xPortGetFreeHeapSize ( ) = = xFreeHeapBeforeCreatingJob ) ;
configASSERT ( xPortGetFreeHeapSize ( ) = = xFreeHeapBeforeCreatingJob ) ;
}
}
/*-----------------------------------------------------------*/
/*-----------------------------------------------------------*/
@ -395,106 +391,127 @@ size_t xFreeHeapBeforeCreatingJob = xPortGetFreeHeapSize();
static void prvExample_ReuseRecyclableJobFromLowPriorityTask ( void )
static void prvExample_ReuseRecyclableJobFromLowPriorityTask ( void )
{
{
IotTaskPoolError_t xResult ;
IotTaskPoolError_t xResult ;
uint32_t x, xIndex , ulNotificationValue;
uint32_t ulNotificationValue;
const uint32_t ulNoFlags = 0UL ;
const uint32_t ulNoFlags = 0UL ;
IotTaskPoolJob_t xJobs [ tpJOBS_TO_CREATE ] ;
const TickType_t xNoDelay = ( TickType_t ) 0 ;
size_t xFreeHeapBeforeCreatingJob = xPortGetFreeHeapSize ( ) ;
IotTaskPoolJob_t xJob , xJobRecycled ;
size_t xFreeHeapBeforeCreatingJob = xPortGetFreeHeapSize ( ) , xFreeHeapAfterCreatingJob = 0 ;
IotTaskPoolJobStatus_t xJobStatus ;
IotTaskPoolJobStatus_t xJobStatus ;
/* Don't expect any notifications to be pending yet. */
/* Don't expect any notifications to be pending yet. */
configASSERT ( ulTaskNotifyTake ( pdTRUE , 0 ) = = 0 ) ;
configASSERT ( ulTaskNotifyTake ( pdTRUE , xNoDelay ) = = 0 ) ;
/* Create tpJOBS_TO_CREATE jobs using the handle of this task as the job's
/* Create a recycleable job using the handle of this task as the job's
context and the function that sends a notification to the task handle as
* 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
* the job ' s callback function . In the full task pool implementation the
in this case the memory to store the job information is allocated within
* first parameter is used to pass the handle of the task pool this
the create function as at this time there are no recyclable jobs in the
* recyclable job is to be associated with . In the lean implementation of
task pool jobs cache . As the jobs are persistent they can be used multiple
* the task pool used by this demo there is only one task pool ( the system
times . In the full task pool implementation the first parameter is used to
* task pool created within the task pool library ) so the first parameter is
pass the handle of the task pool this recyclable job is to be associated
* NULL . */
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 < tpJOBS_TO_CREATE ; x + + )
{
xResult = IotTaskPool_CreateRecyclableJob ( NULL ,
xResult = IotTaskPool_CreateRecyclableJob ( NULL ,
prvSimpleTaskNotifyCallback ,
prvSimpleTaskNotifyCallback ,
( void * ) xTaskGetCurrentTaskHandle ( ) ,
( void * ) xTaskGetCurrentTaskHandle ( ) ,
& ( xJob s[ x ] ) ) ;
& ( xJob ) ) ;
configASSERT ( xResult = = IOT_TASKPOOL_SUCCESS ) ;
configASSERT ( xResult = = IOT_TASKPOOL_SUCCESS ) ;
/* The job is 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 . So
* expect there to be less heap space than when entering the function . */
xFreeHeapAfterCreatingJob = xPortGetFreeHeapSize ( ) ;
configASSERT ( xFreeHeapAfterCreatingJob < xFreeHeapBeforeCreatingJob ) ;
/* The job has been created but not scheduled so is now ready. */
/* The job has been created but not scheduled so is now ready. */
IotTaskPool_GetStatus ( NULL , xJobs [ x ] , & xJobStatus ) ;
IotTaskPool_GetStatus ( NULL , xJob , & xJobStatus ) ;
configASSERT ( xJobStatus = = IOT_TASKPOOL_STATUS_READY ) ;
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 < ( tpJOBS_TO_CREATE * 2UL ) ; x + + )
{
/* Make sure array index does not go out of bounds. */
xIndex = x % tpJOBS_TO_CREATE ;
xResult = IotTaskPool_Schedule ( NULL , xJobs [ xIndex ] , ulNoFlags ) ;
/* 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 ) ;
configASSERT ( xResult = = IOT_TASKPOOL_SUCCESS ) ;
/* The priority of the task pool task(s) is higher than the priority
/* 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
* of this task , so the job ' s callback function should have already
executed , sending a notification to this task , and incrementing this
* executed , sending a notification to this task , and incrementing this
task ' s notification value . */
* task ' s notification value . */
xTaskNotifyWait ( 0UL , /* Don't clear any bits on entry. */
xTaskNotifyWait ( 0UL , /* Don't clear any bits on entry. */
0UL , /* Don't clear any bits on exit. */
0UL , /* Don't clear any bits on exit. */
& ulNotificationValue , /* Obtain the notification value. */
& ulNotificationValue , /* Obtain the notification value. */
0UL ) ; /* No block time, return immediately. */
xNoDelay ) ; /* No block time, return immediately. */
configASSERT ( ulNotificationValue = = ( x + 1 ) ) ;
configASSERT ( ulNotificationValue = = 1 ) ;
/* The job's callback has executed so the job is now completed. */
/* The job's callback has executed so the job is now completed. */
IotTaskPool_GetStatus ( NULL , xJob s[ xIndex ] , & xJobStatus ) ;
IotTaskPool_GetStatus ( NULL , xJob , & xJobStatus ) ;
configASSERT ( xJobStatus = = IOT_TASKPOOL_STATUS_COMPLETED ) ;
configASSERT ( xJobStatus = = IOT_TASKPOOL_STATUS_COMPLETED ) ;
/* To leave the list of jobs empty we can stop re-creating jobs half
/* Return the job to the task pool's job cache. */
way through iterations of this loop . */
IotTaskPool_RecycleJob ( NULL , xJob ) ;
if ( x < tpJOBS_TO_CREATE )
{
/* Create a recycleable job again using the handle of this task as the job's
/* Recycle the job so it can be used again. In the full task pool
* context and the function that sends a notification to the task handle as
implementation the first parameter is used to pass the handle of the
* the job ' s callback function . In the full task pool implementation the
task pool this job will be associated with . In this lean task pool
* first parameter is used to pass the handle of the task pool this
implementation only the system task pool exists ( the task pool created
* recyclable job is to be associated with . In the lean implementation of
internally to the task pool library ) so the first parameter is just
* the task pool used by this demo there is only one task pool ( the system
passed as NULL . */ /*_RB_ Why not recycle it automatically? */
* task pool created within the task pool library ) so the first parameter is
IotTaskPool_RecycleJob ( NULL , xJobs [ xIndex ] ) ;
* NULL . */
xResult = IotTaskPool_CreateRecyclableJob ( NULL ,
xResult = IotTaskPool_CreateRecyclableJob ( NULL ,
prvSimpleTaskNotifyCallback ,
prvSimpleTaskNotifyCallback ,
( void * ) xTaskGetCurrentTaskHandle ( ) ,
( void * ) xTaskGetCurrentTaskHandle ( ) ,
& ( xJobs [ xIndex ] ) ) ;
& ( xJobRecycled ) ) ;
configASSERT ( xResult = = IOT_TASKPOOL_SUCCESS ) ;
/* Since this time the task pool's job cache had a recycleable job, it must
* have been re - used . Thefore expect the free heap space to be same as after
* the creation of first job */
configASSERT ( xPortGetFreeHeapSize ( ) = = xFreeHeapAfterCreatingJob ) ;
/* Expect the task pool to re-use the job in its cache as opposed to
* allocating a new one . */
configASSERT ( xJobRecycled = = xJob ) ;
/* 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 , xJobRecycled , ulNoFlags ) ;
configASSERT ( xResult = = IOT_TASKPOOL_SUCCESS ) ;
configASSERT ( xResult = = IOT_TASKPOOL_SUCCESS ) ;
}
}
/* Clear all the notification value bits again. */
/* 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. */
xNoDelay ) ; /* No block time, return immediately. */
configASSERT ( ulNotificationValue = = 2 ) ;
/* The job's callback has executed so the job is now completed. */
IotTaskPool_GetStatus ( NULL , xJobRecycled , & xJobStatus ) ;
configASSERT ( xJobStatus = = IOT_TASKPOOL_STATUS_COMPLETED ) ;
/* Clean up 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 . */
xResult = IotTaskPool_DestroyRecyclableJob ( NULL , xJobRecycled ) ;
configASSERT ( xResult = = IOT_TASKPOOL_SUCCESS ) ;
/* Clear all the notification value bits ready for the next example. */
xTaskNotifyWait ( portMAX_DELAY , /* Clear all bits on entry - portMAX_DELAY is used as it is a portable way of having all bits set. */
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. */
0UL , /* Don't clear any bits on exit. */
NULL , /* Don't need the notification value this time. */
NULL , /* Don't need the notification value this time. */
0UL ) ; /* No block time, return immediately. */
xNoDelay ) ; /* No block time, return immediately. */
configASSERT ( ulTaskNotifyTake ( pdTRUE , 0 ) = = 0 ) ;
configASSERT ( ulTaskNotifyTake ( pdTRUE , xNoDelay ) = = 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 < tpJOBS_TO_CREATE ; x + + )
{
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
/* 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
* returned , so the available heap should be exactly as when entering this
function . */
* function . */
configASSERT ( xPortGetFreeHeapSize ( ) = = xFreeHeapBeforeCreatingJob ) ;
configASSERT ( xPortGetFreeHeapSize ( ) = = xFreeHeapBeforeCreatingJob ) ;
}
}
/*-----------------------------------------------------------*/
/*-----------------------------------------------------------*/
@ -502,98 +519,178 @@ IotTaskPoolJobStatus_t xJobStatus;
static void prvExample_ReuseRecyclableJobFromHighPriorityTask ( void )
static void prvExample_ReuseRecyclableJobFromHighPriorityTask ( void )
{
{
IotTaskPoolError_t xResult ;
IotTaskPoolError_t xResult ;
uint32_t x, ulNotificationValue;
uint32_t ulNotificationValue;
const uint32_t ulNoFlags = 0UL ;
const uint32_t ulNoFlags = 0UL ;
IotTaskPoolJob_t xJobs [ tpJOBS_TO_CREATE ] ;
const TickType_t xNoDelay = ( TickType_t ) 0 ;
IotTaskPoolJobStorage_t xJobStorage [ tpJOBS_TO_CREATE ] ;
size_t xFreeHeapBeforeCreatingJob = xPortGetFreeHeapSize ( ) ;
TickType_t xShortDelay = pdMS_TO_TICKS ( 150 ) ;
TickType_t xShortDelay = pdMS_TO_TICKS ( 150 ) ;
IotTaskPoolJob_t xJob , xJobRecycled ;
size_t xFreeHeapBeforeCreatingJob = xPortGetFreeHeapSize ( ) , xFreeHeapAfterCreatingJob = 0 ;
IotTaskPoolJobStatus_t xJobStatus ;
IotTaskPoolJobStatus_t xJobStatus ;
/* Don't expect any notifications to be pending yet. */
/* Don't expect any notifications to be pending yet. */
configASSERT ( ulTaskNotifyTake ( pdTRUE , 0 ) = = 0 ) ;
configASSERT ( ulTaskNotifyTake ( pdTRUE , xNoDelay ) = = 0 ) ;
/* prvExample_ReuseRecyclableJobFromLowPriorityTask() executes in a task
/* prvExample_ReuseRecyclableJobFromLowPriorityTask() executes in a task
that has a lower [ task ] priority than the task pool ' s worker tasks .
* that has a lower [ task ] priority than the task pool ' s worker tasks .
Therefore a tal k pool worker preempts the task that calls
* Therefore a tas k pool worker preempts the task that calls
prvExample_ReuseRecyclableJobFromHighPriorityTask ( ) as soon as the job is
* prvExample_ReuseRecyclableJobFromHighPriorityTask ( ) as soon as the job is
scheduled . prvExample_ReuseRecyclableJobFromHighPriorityTask ( ) reverses the
* scheduled . prvExample_ReuseRecyclableJobFromHighPriorityTask ( ) reverses the
priorities - prvExample_ReuseRecyclableJobFromHighPriorityTask ( ) raises its
* priorities - prvExample_ReuseRecyclableJobFromHighPriorityTask ( ) raises its
priority to above the task pool ' s worker tasks , so the worker tasks do not
* 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
* execute until the calling task enters the blocked state . First raise the
priority - passing NULL means raise the priority of the calling task . */
* priority - passing NULL means raise the priority of the calling task . */
vTaskPrioritySet ( NULL , tpTASK_POOL_WORKER_PRIORITY + 1 ) ;
vTaskPrioritySet ( NULL , tpTASK_POOL_WORKER_PRIORITY + 1 ) ;
/* Create tpJOBS_TO_CREATE jobs using the handle of this task as the job's
/* Create a recycleable job using the handle of this task as the job's
context and the function that sends a notification to the task handle as
* context and the function that sends a notification to the task handle as
the jobs callback function . */
* the job ' s callback function . In the full task pool implementation the
for ( x = 0 ; x < tpJOBS_TO_CREATE ; x + + )
* 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
xResult = IotTaskPool_CreateJob ( prvSimpleTaskNotifyCallback , /* Callback function. */
* the task pool used by this demo there is only one task pool ( the system
( void * ) xTaskGetCurrentTaskHandle ( ) , /* Job context. */
* task pool created within the task pool library ) so the first parameter is
& ( xJobStorage [ x ] ) ,
* NULL . */
& ( xJobs [ x ] ) ) ;
xResult = IotTaskPool_CreateRecyclableJob ( NULL ,
prvSimpleTaskNotifyCallback ,
( void * ) xTaskGetCurrentTaskHandle ( ) ,
& ( xJob ) ) ;
configASSERT ( xResult = = IOT_TASKPOOL_SUCCESS ) ;
configASSERT ( xResult = = IOT_TASKPOOL_SUCCESS ) ;
/* This is not a persistent (recyclable) job and its storage is on the
/* The job is created as a recyclable job and in this case the memory to
stack of this function , so the amount of heap space available should not
* store the job information is allocated within the create function as at
have chanced since entering this function . */
* this time there are no recyclable jobs in the task pool jobs cache . So
configASSERT ( xFreeHeapBeforeCreatingJob = = xPortGetFreeHeapSize ( ) ) ;
* expect there to be less heap space than when entering the function . */
}
xFreeHeapAfterCreatingJob = xPortGetFreeHeapSize ( ) ;
configASSERT ( xFreeHeapAfterCreatingJob < xFreeHeapBeforeCreatingJob ) ;
for ( x = 0 ; x < tpJOBS_TO_CREATE ; x + + )
/* The job has been created but not scheduled so is now ready. */
{
IotTaskPool_GetStatus ( NULL , xJob , & xJobStatus ) ;
/* Schedule the next job. */
configASSERT ( xJobStatus = = IOT_TASKPOOL_STATUS_READY ) ;
xResult = IotTaskPool_Schedule ( NULL , xJobs [ x ] , ulNoFlags ) ;
configASSERT ( xResult = = IOT_TASKPOOL_SUCCESS ) ;
/* Although scheduled, the job's callback has not executed, so the job
/* In the full task pool implementation the first parameter is used to
reports itself as scheduled . */
* pass the handle of the task pool to schedule . The lean task pool
IotTaskPool_GetStatus ( NULL , xJobs [ x ] , & xJobStatus ) ;
* implementation used in this demo only supports a single task pool , which
configASSERT ( xJobStatus = = IOT_TASKPOOL_STATUS_SCHEDULED ) ;
* is created internally within the library , so the first parameter is NULL . */
xResult = IotTaskPool_Schedule ( NULL , xJob , ulNoFlags ) ;
configASSERT ( xResult = = IOT_TASKPOOL_SUCCESS ) ;
/* The priority of the task pool task(s) is lower than the priority
/* 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
* 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
* yet , so don ' t expect the notification value for this task to have
changed . */
* changed . */
xTaskNotifyWait ( 0UL , /* Don't clear any bits on entry. */
xTaskNotifyWait ( 0UL , /* Don't clear any bits on entry. */
0UL , /* Don't clear any bits on exit. */
0UL , /* Don't clear any bits on exit. */
& ulNotificationValue , /* Obtain the notification value. */
& ulNotificationValue , /* Obtain the notification value. */
0UL ) ; /* No block time, return immediately. */
xNoDelay ) ; /* No block time, return immediately. */
configASSERT ( ulNotificationValue = = 0 ) ;
configASSERT ( ulNotificationValue = = 0 ) ;
}
/* At this point there are tpJOBS_TO_CREATE scheduled, but none have executed
/* When this task blocks to wait for a notification, a worker thread will be
their callbacks because the priority of this task is higher than the
* able to execute - but as soon as its callback function sends a
priority of the task pool worker threads . When this task blocks to wait for
* notification to this task , this task will preempt it ( because it has a
a notification a worker thread will be able to executes - but as soon as its
* higher priority ) . So this task expects to receive one notification . */
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 < tpJOBS_TO_CREATE ; x + + )
{
xTaskNotifyWait ( 0UL , /* Don't clear any bits on entry. */
xTaskNotifyWait ( 0UL , /* Don't clear any bits on entry. */
0UL , /* Don't clear any bits on exit. */
0UL , /* Don't clear any bits on exit. */
& ulNotificationValue , /* Obtain the notification value. */
& ulNotificationValue , /* Obtain the notification value. */
xShortDelay ) ; /* Short delay to allow a task pool worker to execute. */
xShortDelay ) ; /* Short delay to allow a task pool worker to execute. */
configASSERT ( ulNotificationValue = = ( x + 1 ) ) ;
configASSERT ( ulNotificationValue = = 1 ) ;
}
/* All the scheduled jobs have now executed, so waiting for another
/* Since the scheduled job has now executed, so waiting for another
notification should timeout without the notification value changing . */
* notification should timeout without the notification value changing . */
xTaskNotifyWait ( 0UL , /* Don't clear any bits on entry. */
xTaskNotifyWait ( 0UL , /* Don't clear any bits on entry. */
0UL , /* Don't clear any bits on exit. */
0UL , /* Don't clear any bits on exit. */
& ulNotificationValue , /* Obtain the notification value. */
& ulNotificationValue , /* Obtain the notification value. */
xShortDelay ) ; /* Short delay to allow a task pool worker to execute. */
xShortDelay ) ; /* Short delay to allow a task pool worker to execute. */
configASSERT ( ulNotificationValue = = x ) ;
configASSERT ( ulNotificationValue = = 1 ) ;
/* The job's callback has executed so the job is now completed. */
IotTaskPool_GetStatus ( NULL , xJob , & xJobStatus ) ;
configASSERT ( xJobStatus = = IOT_TASKPOOL_STATUS_COMPLETED ) ;
/* Reset the priority of this task and clear the notifications ready for the
/* Return the job to the task pool's job cache. */
next example . */
IotTaskPool_RecycleJob ( NULL , xJob ) ;
/* Create a recycleable job again using the handle of this task as the job's
* context and the function that sends a notification to the task handle as
* the job ' s callback function . 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 ( ) ,
& ( xJobRecycled ) ) ;
configASSERT ( xResult = = IOT_TASKPOOL_SUCCESS ) ;
/* Since this time the task pool's job cache had a recycleable job, it must
* have been re - used . Thefore expect the free heap space to be same as after
* the creation of first job */
configASSERT ( xPortGetFreeHeapSize ( ) = = xFreeHeapAfterCreatingJob ) ;
/* Expect the task pool to re-use the job in its cache as opposed to
* allocating a new one . */
configASSERT ( xJobRecycled = = xJob ) ;
/* 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 , xJobRecycled , ulNoFlags ) ;
configASSERT ( xResult = = IOT_TASKPOOL_SUCCESS ) ;
/* 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
* yet , 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. */
xNoDelay ) ; /* No block time, return immediately. */
configASSERT ( ulNotificationValue = = 1 ) ;
/* When this task blocks to wait for a notification, a worker thread will be
* able to execute - 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 expects to receive one notification . */
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 = = 2 ) ;
/* Since the scheduled job has 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 = = 2 ) ;
/* The job's callback has executed so the job is now completed. */
IotTaskPool_GetStatus ( NULL , xJobRecycled , & xJobStatus ) ;
configASSERT ( xJobStatus = = IOT_TASKPOOL_STATUS_COMPLETED ) ;
/* Clean up 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 . */
xResult = IotTaskPool_DestroyRecyclableJob ( NULL , xJobRecycled ) ;
configASSERT ( xResult = = IOT_TASKPOOL_SUCCESS ) ;
/* Reset this task's priority. */
vTaskPrioritySet ( NULL , tskIDLE_PRIORITY ) ;
vTaskPrioritySet ( NULL , tskIDLE_PRIORITY ) ;
/* Clear all the notification value bits ready for the next example. */
xTaskNotifyWait ( portMAX_DELAY , /* Clear all bits on entry - portMAX_DELAY is used as it is a portable way of having all bits set. */
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. */
0UL , /* Don't clear any bits on exit. */
NULL , /* Don't need the notification value this time. */
NULL , /* Don't need the notification value this time. */
0UL ) ; /* No block time, return immediately. */
xNoDelay ) ; /* No block time, return immediately. */
configASSERT ( ulTaskNotifyTake ( pdTRUE , xNoDelay ) = = 0 ) ;
/* 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 ) ;
}
}
/*-----------------------------------------------------------*/
/*-----------------------------------------------------------*/