summaryrefslogtreecommitdiff
path: root/FreeRTOS-Plus
diff options
context:
space:
mode:
authorrtel <rtel@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>2019-07-01 17:05:20 +0000
committerrtel <rtel@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>2019-07-01 17:05:20 +0000
commite36946f7f2d14b3b4f6f51f0a1f881e28cb4a6e9 (patch)
treeef12b03a7640edd24ec87fbb9769d52c7c09450e /FreeRTOS-Plus
parent68138996a6703fd5400c0ce1a9a9e14cee9c5d0a (diff)
downloadfreertos-e36946f7f2d14b3b4f6f51f0a1f881e28cb4a6e9.tar.gz
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: http://svn.code.sf.net/p/freertos/code/trunk@2668 1d2547de-c912-0410-9cb9-b8ca96c0e9e2
Diffstat (limited to 'FreeRTOS-Plus')
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_Plus_IoT_SDK/TaskPool/.project2
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_Plus_IoT_SDK/TaskPool/main.c101
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/include/iot_taskpool.h44
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/c_sdk/standard/common/taskpool/iot_taskpool.c140
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 @@
<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>
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}
@@ -256,6 +260,36 @@ IotTaskPoolError_t IotTaskPool_CreateRecyclableJob( IotTaskPool_t taskPool,
/* @[declare_taskpool_createrecyclablejob] */
/**
+ * brief Creates a job for the system task pool by allocating the job dynamically.
+ * The system task pool is the task pool created by @ref IotTaskPool_CreateSystemTaskPool.
+ *
+ * A recyclable job does not need to be allocated twice, but it can rather be reused through
+ * subsequent calls to @ref IotTaskPool_CreateRecyclableJob.
+ *
+ * @param[in] userCallback A user-specified callback for the job.
+ * @param[in] pUserContext A user-specified context for the callback.
+ * @param[out] pJob A pointer to an instance of @ref IotTaskPoolJob_t that will be initialized when this
+ * function returns successfully. This handle can be used to inspect the job status with
+ * @ref IotTaskPool_GetStatus or cancel the job with @ref IotTaskPool_TryCancel, etc....
+ *
+ * @return One of the following:
+ * - #IOT_TASKPOOL_SUCCESS
+ * - #IOT_TASKPOOL_BAD_PARAMETER
+ * - #IOT_TASKPOOL_NO_MEMORY
+ * - #IOT_TASKPOOL_SHUTDOWN_IN_PROGRESS
+ *
+ * @note This function will not allocate memory.
+ *
+ * @warning A recyclable job should be recycled with a call to @ref IotTaskPool_RecycleJob rather than destroyed.
+ *
+ */
+/* @[declare_taskpool_createrecyclablesystemjob] */
+IotTaskPoolError_t IotTaskPool_CreateRecyclableSystemJob( IotTaskPoolRoutine_t userCallback,
+ void * pUserContext,
+ IotTaskPoolJob_t * const pJob );
+/* @[declare_taskpool_createrecyclablesystemjob] */
+
+/**
* @brief This function un-initializes a job.
*
* This function will destroy a job created with @ref IotTaskPool_CreateRecyclableJob.
@@ -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
@@ -44,30 +44,6 @@
#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.
*/
#define TASKPOOL_MAX_SEM_VALUE 0xFFFF
@@ -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();
}