From b63bf362086b59b6dc07c9d38c80a4a3ffd5ef31 Mon Sep 17 00:00:00 2001 From: rtel Date: Mon, 1 Jul 2019 17:05:20 +0000 Subject: [PATCH] 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(). git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@2668 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- .../FreeRTOS_Plus_IoT_SDK/TaskPool/.project | 2 +- .../FreeRTOS_Plus_IoT_SDK/TaskPool/main.c | 101 ++++++++++--- .../standard/common/include/iot_taskpool.h | 44 +++++- .../standard/common/taskpool/iot_taskpool.c | 140 +++++++++--------- 4 files changed, 195 insertions(+), 92 deletions(-) diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_IoT_SDK/TaskPool/.project b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_IoT_SDK/TaskPool/.project index f3fa6ed36..ad46abe4c 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_IoT_SDK/TaskPool/.project +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_IoT_SDK/TaskPool/.project @@ -147,7 +147,7 @@ FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/taskpool/iot_taskpool.c 1 - PARENT-5-FREERTOS_ROOT/T/amazon-freertos-master_fr_task_pool/libraries/c_sdk/standard/common/taskpool/iot_taskpool.c + FREERTOS_ROOT/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/taskpool/iot_taskpool.c 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 c3181f570..bde06ef93 100644 --- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_IoT_SDK/TaskPool/main.c +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_IoT_SDK/TaskPool/main.c @@ -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 ); } /*-----------------------------------------------------------*/ 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 142c431ef..7e94e7264 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,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 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 214bffb0e..fff69ca83 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 @@ -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(); } -- 2.39.5