mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-19 21:11:57 -04:00
In small FreeRTOS applications it is unlikely there will be any task pools other than the system task pool. IotTaskPool_CreateRecyclableSystemJob() is therefore introduced to complement IotTaskPool_CreateRecyclableJob() that does not require the handle of the target task pool to be specified as a parameter. Likewise IotTaskPool_ScheduleSystemJob() is introduced to complement IotTaskPool_ScheduleJob() for the same reason.
IotTaskPool_CreateSystemTaskPool() calls synchronisation primitives, so cannot be called before the scheduler starts. Add a configASSERT() to ensure the scheduler is running when it executes. IotTaskPool_CreateSystemTaskPool() can conceivably be called from multiple different libraries that depend on the thread pool. In this version _IotSystemTaskPool.running can be used to check the system task pool has not already been created. If the task pool has been created simply return from IotTaskPool_CreateSystemTaskPool() instead of re-creating it (which would leak memory and leave orphaned tasks). Call taskENTER_CRITICAL() and taskEXIT_CRITICAL() directly in place of mapping them to TASKPOOL_ENTER_CRITICAL() and TASKPOOL_EXIT_CRITICAL() in the same file. Rename _timerThread() _timerCallback(), as it is a callback function and not a thread. Remove the unused flags parameter from _scheduleInternal().
This commit is contained in:
parent
76cc2a00c6
commit
e75b609c74
|
@ -147,7 +147,7 @@
|
|||
<link>
|
||||
<name>FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/taskpool/iot_taskpool.c</name>
|
||||
<type>1</type>
|
||||
<locationURI>PARENT-5-FREERTOS_ROOT/T/amazon-freertos-master_fr_task_pool/libraries/c_sdk/standard/common/taskpool/iot_taskpool.c</locationURI>
|
||||
<locationURI>FREERTOS_ROOT/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/taskpool/iot_taskpool.c</locationURI>
|
||||
</link>
|
||||
</linkedResources>
|
||||
<variableList>
|
||||
|
|
|
@ -1,3 +1,30 @@
|
|||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/* Kernel includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
@ -9,6 +36,7 @@
|
|||
* Prototypes for the functions that demonstrate the task pool API.
|
||||
*/
|
||||
static void prvExample_BasicSingleJob( void );
|
||||
static void prvExample_BasicRecyclableJob( void );
|
||||
|
||||
/* Prototypes of the callback functions used in the examples. */
|
||||
static void prvSimpleTaskNotifyCallback( IotTaskPool_t pTaskPool, IotTaskPoolJob_t pJob, void *pUserContext );
|
||||
|
@ -62,6 +90,34 @@ int main( void )
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvTaskPoolDemoTask( void *pvParameters )
|
||||
{
|
||||
IotTaskPoolError_t xResult;
|
||||
|
||||
/* 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 );
|
||||
|
||||
/* 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 );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
/* Run through each task pool example in turn. See the comments in the
|
||||
below functions for details of their behaviour. */
|
||||
prvExample_BasicSingleJob();
|
||||
prvExample_BasicRecyclableJob();
|
||||
|
||||
vTaskDelete( NULL );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvSimpleTaskNotifyCallback( IotTaskPool_t pTaskPool, IotTaskPoolJob_t pJob, void *pUserContext )
|
||||
{
|
||||
TaskHandle_t xTaskToNotify = ( TaskHandle_t ) pUserContext;
|
||||
|
@ -80,46 +136,57 @@ static void prvExample_BasicSingleJob( void )
|
|||
IotTaskPoolJobStorage_t xJobStorage;
|
||||
IotTaskPoolJob_t xJob;
|
||||
IotTaskPoolError_t xResult;
|
||||
uint32_t ulReturn;
|
||||
const TickType_t xShortDelay = pdMS_TO_TICKS( 200 );
|
||||
|
||||
/* Ensure the notification count is 0 before scheduling the job. */
|
||||
while( 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 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 );
|
||||
IotTaskPool_ScheduleSystem( xJob, 0 );
|
||||
|
||||
xResult = IotTaskPool_ScheduleSystemJob( xJob, 0 );
|
||||
configASSERT( xResult == IOT_TASKPOOL_SUCCESS );
|
||||
|
||||
/* Wait for the notification coming from the job's callback function. */
|
||||
ulTaskNotifyTake( pdTRUE, portMAX_DELAY );
|
||||
ulReturn = ulTaskNotifyTake( pdTRUE, xShortDelay );
|
||||
configASSERT( ulReturn );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvTaskPoolDemoTask( void *pvParameters )
|
||||
static void prvExample_BasicRecyclableJob( void )
|
||||
{
|
||||
IotTaskPoolJob_t xJob;
|
||||
IotTaskPoolError_t xResult;
|
||||
uint32_t ulReturn;
|
||||
const TickType_t xShortDelay = pdMS_TO_TICKS( 200 );
|
||||
|
||||
/* Remove compiler warnings about unused parameters. */
|
||||
( void ) pvParameters;
|
||||
/* Ensure the notification count is 0 before scheduling the job. */
|
||||
while( ulTaskNotifyTake( pdTRUE, 0 ) != 0 );
|
||||
|
||||
/* The task pool must be created before it can be used. */
|
||||
xResult = IotTaskPool_CreateSystemTaskPool( &xTaskPoolParameters );
|
||||
/* 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 );
|
||||
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. */
|
||||
prvExample_BasicSingleJob();
|
||||
xResult = IotTaskPool_ScheduleSystemJob( xJob, 0 );
|
||||
configASSERT( xResult == IOT_TASKPOOL_SUCCESS );
|
||||
|
||||
|
||||
|
||||
vTaskDelete( NULL );
|
||||
}
|
||||
/* Wait for the notification coming from the job's callback function. */
|
||||
ulReturn = ulTaskNotifyTake( pdTRUE, xShortDelay );
|
||||
configASSERT( ulReturn );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
|
@ -53,9 +53,11 @@
|
|||
* - @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}
|
||||
|
@ -71,9 +73,11 @@
|
|||
* @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}
|
||||
|
@ -255,6 +259,36 @@ IotTaskPoolError_t IotTaskPool_CreateRecyclableJob( IotTaskPool_t taskPool,
|
|||
IotTaskPoolJob_t * const pJob );
|
||||
/* @[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.
|
||||
*
|
||||
|
@ -413,7 +447,7 @@ IotTaskPoolError_t IotTaskPool_Schedule( IotTaskPool_t taskPool,
|
|||
uint32_t flags );
|
||||
|
||||
/**
|
||||
* @brief This function schedules a job created with @ref IotTaskPool_CreateJob or @ref IotTaskPool_CreateRecyclableJob
|
||||
* @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
|
||||
|
@ -464,7 +498,7 @@ IotTaskPoolError_t IotTaskPool_Schedule( IotTaskPool_t taskPool,
|
|||
* // Statically allocate one job, schedule it.
|
||||
* IotTaskPool_CreateJob( &ExecutionCb, &userContext, &job );
|
||||
*
|
||||
* IotTaskPoolError_t errorSchedule = IotTaskPool_ScheduleSystem( &job, 0 );
|
||||
* IotTaskPoolError_t errorSchedule = IotTaskPool_ScheduleSystemJob( &job, 0 );
|
||||
*
|
||||
* switch ( errorSchedule )
|
||||
* {
|
||||
|
@ -488,11 +522,11 @@ IotTaskPoolError_t IotTaskPool_Schedule( IotTaskPool_t taskPool,
|
|||
* }
|
||||
* @endcode
|
||||
*/
|
||||
/* @[declare_taskpool_schedule] */
|
||||
IotTaskPoolError_t IotTaskPool_ScheduleSystem( IotTaskPoolJob_t pJob,
|
||||
/* @[declare_taskpool_schedulesystemjob] */
|
||||
IotTaskPoolError_t IotTaskPool_ScheduleSystemJob( IotTaskPoolJob_t pJob,
|
||||
uint32_t flags );
|
||||
|
||||
/* @[declare_taskpool_schedule] */
|
||||
/* @[declare_taskpool_schedulesystemjob] */
|
||||
|
||||
/**
|
||||
* @brief This function schedules a job created with @ref IotTaskPool_CreateJob against the task pool
|
||||
|
|
|
@ -43,30 +43,6 @@
|
|||
/* Task pool internal include. */
|
||||
#include "private/iot_taskpool_internal.h"
|
||||
|
||||
/**
|
||||
* @brief Enter a critical section by disabling interrupts.
|
||||
*
|
||||
*/
|
||||
#define TASKPOOL_ENTER_CRITICAL() taskENTER_CRITICAL()
|
||||
|
||||
/**
|
||||
* @brief Enter a critical section by disabling interrupts.
|
||||
*
|
||||
*/
|
||||
#define TASKPOOL_ENTER_CRITICAL_FROM_ISR() taskENTER_CRITICAL_FROM_ISR()
|
||||
|
||||
/**
|
||||
* @brief Exit a critical section by re-enabling interrupts.
|
||||
*
|
||||
*/
|
||||
#define TASKPOOL_EXIT_CRITICAL() taskEXIT_CRITICAL()
|
||||
|
||||
/**
|
||||
* @brief Exit a critical section by re-enabling interrupts.
|
||||
*
|
||||
*/
|
||||
#define TASKPOOL_EXIT_CRITICAL_FROM_ISR( x ) taskEXIT_CRITICAL_FROM_ISR( x )
|
||||
|
||||
/**
|
||||
* @brief Maximum semaphore value for wait operations.
|
||||
*/
|
||||
|
@ -171,7 +147,7 @@ static void _rescheduleDeferredJobsTimer( TimerHandle_t const timer,
|
|||
*
|
||||
* param[in] timer The timer to handle.
|
||||
*/
|
||||
static void _timerThread( TimerHandle_t xTimer );
|
||||
static void _timerCallback( TimerHandle_t xTimer );
|
||||
|
||||
/* -------------- Convenience functions to create/initialize/destroy the task pool -------------- */
|
||||
|
||||
|
@ -238,8 +214,7 @@ static void _signalShutdown( _taskPool_t * const pTaskPool,
|
|||
*
|
||||
*/
|
||||
static IotTaskPoolError_t _scheduleInternal( _taskPool_t * const pTaskPool,
|
||||
_taskPoolJob_t * const pJob,
|
||||
uint32_t flags );
|
||||
_taskPoolJob_t * const pJob );
|
||||
|
||||
/**
|
||||
* Matches a deferred job in the timer queue with its timer event wrapper.
|
||||
|
@ -276,11 +251,21 @@ IotTaskPoolError_t IotTaskPool_CreateSystemTaskPool( const IotTaskPoolInfo_t * c
|
|||
{
|
||||
TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );
|
||||
|
||||
/* Parameter checking. */
|
||||
TASKPOOL_ON_ERROR_GOTO_CLEANUP( _performTaskPoolParameterValidation( pInfo ) );
|
||||
/* At this time the task pool cannot be created before the scheduler has
|
||||
started because the function attempts to block on synchronization
|
||||
primitives (although I'm not sure why). */
|
||||
configASSERT( xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED );
|
||||
|
||||
/* Create the system task pool pool. */
|
||||
TASKPOOL_SET_AND_GOTO_CLEANUP( _createTaskPool( pInfo, &_IotSystemTaskPool ) );
|
||||
/* Guard against multiple attempts to create the system task pool in case
|
||||
this function is called by more than one library initialization routine. */
|
||||
if( _IotSystemTaskPool.running == false )
|
||||
{
|
||||
/* Parameter checking. */
|
||||
TASKPOOL_ON_ERROR_GOTO_CLEANUP( _performTaskPoolParameterValidation( pInfo ) );
|
||||
|
||||
/* Create the system task pool pool. */
|
||||
TASKPOOL_SET_AND_GOTO_CLEANUP( _createTaskPool( pInfo, &_IotSystemTaskPool ) );
|
||||
}
|
||||
|
||||
TASKPOOL_NO_FUNCTION_CLEANUP();
|
||||
}
|
||||
|
@ -349,7 +334,7 @@ IotTaskPoolError_t IotTaskPool_Destroy( IotTaskPool_t taskPoolHandle )
|
|||
/* Destroying the task pool should be safe, and therefore we will grab the task pool lock.
|
||||
* No worker thread or application thread should access any data structure
|
||||
* in the task pool while the task pool is being destroyed. */
|
||||
TASKPOOL_ENTER_CRITICAL();
|
||||
taskENTER_CRITICAL();
|
||||
{
|
||||
IotLink_t * pItemLink;
|
||||
|
||||
|
@ -439,7 +424,7 @@ IotTaskPoolError_t IotTaskPool_Destroy( IotTaskPool_t taskPoolHandle )
|
|||
/* (4) Set the exit condition. */
|
||||
_signalShutdown( pTaskPool, activeThreads );
|
||||
}
|
||||
TASKPOOL_EXIT_CRITICAL();
|
||||
taskEXIT_CRITICAL();
|
||||
|
||||
/* (5) Wait for all active threads to reach the end of their life-span. */
|
||||
for( count = 0; count < activeThreads; ++count )
|
||||
|
@ -505,6 +490,15 @@ 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,
|
||||
|
@ -520,12 +514,12 @@ IotTaskPoolError_t IotTaskPool_CreateRecyclableJob( IotTaskPool_t taskPoolHandle
|
|||
TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( userCallback );
|
||||
TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( ppJob );
|
||||
|
||||
TASKPOOL_ENTER_CRITICAL();
|
||||
taskENTER_CRITICAL();
|
||||
{
|
||||
/* Bail out early if this task pool is shutting down. */
|
||||
pTempJob = _fetchOrAllocateJob( &pTaskPool->jobsCache );
|
||||
}
|
||||
TASKPOOL_EXIT_CRITICAL();
|
||||
taskEXIT_CRITICAL();
|
||||
|
||||
if( pTempJob == NULL )
|
||||
{
|
||||
|
@ -548,7 +542,8 @@ IotTaskPoolError_t IotTaskPool_DestroyRecyclableJob( IotTaskPool_t taskPoolHandl
|
|||
{
|
||||
TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );
|
||||
|
||||
_taskPool_t * pTaskPool = ( _taskPool_t * ) taskPoolHandle;
|
||||
( void ) taskPoolHandle;
|
||||
|
||||
_taskPoolJob_t * pJob = ( _taskPoolJob_t * ) pJobHandle;
|
||||
|
||||
/* Parameter checking. */
|
||||
|
@ -575,13 +570,13 @@ IotTaskPoolError_t IotTaskPool_RecycleJob( IotTaskPool_t taskPoolHandle,
|
|||
TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( taskPoolHandle );
|
||||
TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( pJob );
|
||||
|
||||
TASKPOOL_ENTER_CRITICAL();
|
||||
taskENTER_CRITICAL();
|
||||
{
|
||||
IotTaskPool_Assert( IotLink_IsLinked( &pJob->link ) == false );
|
||||
|
||||
_recycleJob( &pTaskPool->jobsCache, pJob );
|
||||
}
|
||||
TASKPOOL_EXIT_CRITICAL();
|
||||
taskEXIT_CRITICAL();
|
||||
|
||||
TASKPOOL_NO_FUNCTION_CLEANUP();
|
||||
}
|
||||
|
@ -596,22 +591,32 @@ IotTaskPoolError_t IotTaskPool_Schedule( IotTaskPool_t taskPoolHandle,
|
|||
|
||||
_taskPool_t * pTaskPool = ( _taskPool_t * ) taskPoolHandle;
|
||||
|
||||
configASSERT( pTaskPool->running != false );
|
||||
|
||||
/* 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 ) );
|
||||
|
||||
TASKPOOL_ENTER_CRITICAL();
|
||||
taskENTER_CRITICAL(); //_RB_ Critical section is too long - does the whole thing need to be protected?
|
||||
{
|
||||
_scheduleInternal( pTaskPool, pJob, flags );
|
||||
_scheduleInternal( pTaskPool, pJob );
|
||||
}
|
||||
TASKPOOL_EXIT_CRITICAL();
|
||||
taskEXIT_CRITICAL();
|
||||
|
||||
TASKPOOL_NO_FUNCTION_CLEANUP();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
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 )
|
||||
|
@ -629,13 +634,13 @@ IotTaskPoolError_t IotTaskPool_ScheduleDeferred( IotTaskPool_t taskPoolHandle,
|
|||
TASKPOOL_SET_AND_GOTO_CLEANUP( IotTaskPool_Schedule( pTaskPool, job, 0 ) );
|
||||
}
|
||||
|
||||
TASKPOOL_ENTER_CRITICAL();
|
||||
taskENTER_CRITICAL();
|
||||
{
|
||||
_taskPoolTimerEvent_t * pTimerEvent = IotTaskPool_MallocTimerEvent( sizeof( _taskPoolTimerEvent_t ) );
|
||||
|
||||
if( pTimerEvent == NULL )
|
||||
{
|
||||
TASKPOOL_EXIT_CRITICAL();
|
||||
taskEXIT_CRITICAL();
|
||||
|
||||
TASKPOOL_SET_AND_GOTO_CLEANUP( IOT_TASKPOOL_NO_MEMORY );
|
||||
}
|
||||
|
@ -669,7 +674,7 @@ IotTaskPoolError_t IotTaskPool_ScheduleDeferred( IotTaskPool_t taskPoolHandle,
|
|||
_rescheduleDeferredJobsTimer( pTaskPool->timer, pTimerEvent );
|
||||
}
|
||||
}
|
||||
TASKPOOL_EXIT_CRITICAL();
|
||||
taskEXIT_CRITICAL();
|
||||
|
||||
TASKPOOL_NO_FUNCTION_CLEANUP();
|
||||
}
|
||||
|
@ -682,19 +687,17 @@ IotTaskPoolError_t IotTaskPool_GetStatus( IotTaskPool_t taskPoolHandle,
|
|||
{
|
||||
TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );
|
||||
|
||||
_taskPool_t * pTaskPool = ( _taskPool_t * ) taskPoolHandle;
|
||||
|
||||
/* Parameter checking. */
|
||||
TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( taskPoolHandle );
|
||||
TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( job );
|
||||
TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( pStatus );
|
||||
*pStatus = IOT_TASKPOOL_STATUS_UNDEFINED;
|
||||
|
||||
TASKPOOL_ENTER_CRITICAL();
|
||||
taskENTER_CRITICAL();
|
||||
{
|
||||
*pStatus = job->status;
|
||||
}
|
||||
TASKPOOL_EXIT_CRITICAL();
|
||||
taskEXIT_CRITICAL();
|
||||
|
||||
TASKPOOL_NO_FUNCTION_CLEANUP();
|
||||
}
|
||||
|
@ -718,11 +721,11 @@ IotTaskPoolError_t IotTaskPool_TryCancel( IotTaskPool_t taskPoolHandle,
|
|||
*pStatus = IOT_TASKPOOL_STATUS_UNDEFINED;
|
||||
}
|
||||
|
||||
TASKPOOL_ENTER_CRITICAL();
|
||||
taskENTER_CRITICAL();
|
||||
{
|
||||
status = _tryCancelInternal( pTaskPool, job, pStatus );
|
||||
}
|
||||
TASKPOOL_EXIT_CRITICAL();
|
||||
taskEXIT_CRITICAL();
|
||||
|
||||
TASKPOOL_NO_FUNCTION_CLEANUP();
|
||||
}
|
||||
|
@ -855,7 +858,7 @@ static IotTaskPoolError_t _createTaskPool( const IotTaskPoolInfo_t * const pInfo
|
|||
TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );
|
||||
|
||||
uint32_t count;
|
||||
uint32_t threadsCreated = 0;
|
||||
uint32_t threadsCreated;
|
||||
|
||||
/* Check input values for consistency. */
|
||||
TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( pTaskPool );
|
||||
|
@ -866,8 +869,8 @@ static IotTaskPoolError_t _createTaskPool( const IotTaskPoolInfo_t * const pInfo
|
|||
/* Initialize all internal data structure prior to creating all threads. */
|
||||
TASKPOOL_ON_ERROR_GOTO_CLEANUP( _initTaskPoolControlStructures( pInfo, pTaskPool ) );
|
||||
|
||||
/* Create the timer mutex for a new connection. */
|
||||
pTaskPool->timer = xTimerCreate( NULL, portMAX_DELAY, pdFALSE, ( void * ) pTaskPool, _timerThread );
|
||||
/* Create the timer for a new connection. */
|
||||
pTaskPool->timer = xTimerCreate( NULL, portMAX_DELAY, pdFALSE, ( void * ) pTaskPool, _timerCallback );
|
||||
|
||||
if( pTaskPool->timer == NULL )
|
||||
{
|
||||
|
@ -876,13 +879,13 @@ static IotTaskPoolError_t _createTaskPool( const IotTaskPoolInfo_t * const pInfo
|
|||
TASKPOOL_SET_AND_GOTO_CLEANUP( IOT_TASKPOOL_NO_MEMORY );
|
||||
}
|
||||
|
||||
/* The task pool will initialize the minimum number of threads reqeusted by the user upon start. */
|
||||
/* The task pool will initialize the minimum number of threads requested by the user upon start. */
|
||||
/* When a thread is created, it will signal a semaphore to signify that it is about to wait on incoming */
|
||||
/* jobs. A thread can be woken up for exit or for new jobs only at that point in time. */
|
||||
/* The exit condition is setting the maximum number of threads to 0. */
|
||||
|
||||
/* Create the minimum number of threads specified by the user, and if one fails shutdown and return error. */
|
||||
for( ; threadsCreated < pInfo->minThreads; )
|
||||
for( threadsCreated = 0; threadsCreated < pInfo->minThreads; )
|
||||
{
|
||||
TaskHandle_t task = NULL;
|
||||
|
||||
|
@ -914,7 +917,7 @@ static IotTaskPoolError_t _createTaskPool( const IotTaskPoolInfo_t * const pInfo
|
|||
/* Wait for threads to be ready to wait on the condition, so that threads are actually able to receive messages. */
|
||||
for( count = 0; count < threadsCreated; ++count )
|
||||
{
|
||||
xSemaphoreTake( pTaskPool->startStopSignal, portMAX_DELAY );
|
||||
xSemaphoreTake( pTaskPool->startStopSignal, portMAX_DELAY ); /*_RB_ Is waiting necessary, and if so, is a semaphore necessary? */
|
||||
}
|
||||
|
||||
/* In case of failure, wait on the created threads to exit. */
|
||||
|
@ -987,7 +990,7 @@ static void _taskPoolWorker( void * pUserContext )
|
|||
/* Acquire the lock to check the exit condition, and release the lock if the exit condition is verified,
|
||||
* or before waiting for incoming notifications.
|
||||
*/
|
||||
TASKPOOL_ENTER_CRITICAL();
|
||||
taskENTER_CRITICAL();
|
||||
{
|
||||
/* If the exit condition is verified, update the number of active threads and exit the loop. */
|
||||
if( _IsShutdownStarted( pTaskPool ) )
|
||||
|
@ -997,7 +1000,7 @@ static void _taskPoolWorker( void * pUserContext )
|
|||
/* Decrease the number of active threads. */
|
||||
pTaskPool->activeThreads--;
|
||||
|
||||
TASKPOOL_EXIT_CRITICAL();
|
||||
taskEXIT_CRITICAL();
|
||||
|
||||
/* Signal that this worker is exiting. */
|
||||
xSemaphoreGive( pTaskPool->startStopSignal );
|
||||
|
@ -1020,7 +1023,7 @@ static void _taskPoolWorker( void * pUserContext )
|
|||
userCallback = pJob->userCallback;
|
||||
}
|
||||
}
|
||||
TASKPOOL_EXIT_CRITICAL();
|
||||
taskEXIT_CRITICAL();
|
||||
|
||||
/* INNER LOOP: it controls the execution of jobs: the exit condition is the lack of a job to execute. */
|
||||
while( pJob != NULL )
|
||||
|
@ -1047,7 +1050,7 @@ static void _taskPoolWorker( void * pUserContext )
|
|||
}
|
||||
|
||||
/* Acquire the lock before updating the job status. */
|
||||
TASKPOOL_ENTER_CRITICAL();
|
||||
taskENTER_CRITICAL();
|
||||
{
|
||||
/* Try and dequeue the next job in the dispatch queue. */
|
||||
IotLink_t * pItem = NULL;
|
||||
|
@ -1058,7 +1061,7 @@ static void _taskPoolWorker( void * pUserContext )
|
|||
/* If there is no job left in the dispatch queue, update the worker status and leave. */
|
||||
if( pItem == NULL )
|
||||
{
|
||||
TASKPOOL_EXIT_CRITICAL();
|
||||
taskEXIT_CRITICAL();
|
||||
|
||||
/* Abandon the INNER LOOP. Execution will tranfer back to the OUTER LOOP condition. */
|
||||
break;
|
||||
|
@ -1072,7 +1075,7 @@ static void _taskPoolWorker( void * pUserContext )
|
|||
|
||||
pJob->status = IOT_TASKPOOL_STATUS_COMPLETED;
|
||||
}
|
||||
TASKPOOL_EXIT_CRITICAL();
|
||||
taskEXIT_CRITICAL();
|
||||
}
|
||||
} while( running == true );
|
||||
|
||||
|
@ -1222,8 +1225,7 @@ static void _signalShutdown( _taskPool_t * const pTaskPool,
|
|||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
static IotTaskPoolError_t _scheduleInternal( _taskPool_t * const pTaskPool,
|
||||
_taskPoolJob_t * const pJob,
|
||||
uint32_t flags )
|
||||
_taskPoolJob_t * const pJob )
|
||||
{
|
||||
TASKPOOL_FUNCTION_ENTRY( IOT_TASKPOOL_SUCCESS );
|
||||
|
||||
|
@ -1418,7 +1420,7 @@ static void _rescheduleDeferredJobsTimer( TimerHandle_t const timer,
|
|||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void _timerThread( TimerHandle_t xTimer )
|
||||
static void _timerCallback( TimerHandle_t xTimer )
|
||||
{
|
||||
_taskPool_t * pTaskPool = pvTimerGetTimerID( xTimer );
|
||||
|
||||
|
@ -1432,12 +1434,12 @@ static void _timerThread( TimerHandle_t xTimer )
|
|||
* If this mutex cannot be locked it means that another thread is manipulating the
|
||||
* timeouts list, and will reset the timer to fire again, although it will be late.
|
||||
*/
|
||||
TASKPOOL_ENTER_CRITICAL();
|
||||
taskENTER_CRITICAL();
|
||||
{
|
||||
/* Check again for shutdown and bail out early in case. */
|
||||
if( _IsShutdownStarted( pTaskPool ) )
|
||||
{
|
||||
TASKPOOL_EXIT_CRITICAL();
|
||||
taskEXIT_CRITICAL();
|
||||
|
||||
/* Complete the shutdown sequence. */
|
||||
_destroyTaskPool( pTaskPool );
|
||||
|
@ -1487,11 +1489,11 @@ static void _timerThread( TimerHandle_t xTimer )
|
|||
IotLogDebug( "Scheduling job from timer event." );
|
||||
|
||||
/* Queue the job associated with the received timer event. */
|
||||
( void ) _scheduleInternal( pTaskPool, pTimerEvent->job, 0 );
|
||||
( void ) _scheduleInternal( pTaskPool, pTimerEvent->job );
|
||||
|
||||
/* Free the timer event. */
|
||||
IotTaskPool_FreeTimerEvent( pTimerEvent );
|
||||
}
|
||||
}
|
||||
TASKPOOL_EXIT_CRITICAL();
|
||||
taskEXIT_CRITICAL();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue