]> git.sur5r.net Git - freertos/blob
b989c586ce112a5d195da69ac1e0f80f405d200b
[freertos] /
1 /*\r
2  * Amazon FreeRTOS Common V1.0.0\r
3  * Copyright (C) 2018 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
4  *\r
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of\r
6  * this software and associated documentation files (the "Software"), to deal in\r
7  * the Software without restriction, including without limitation the rights to\r
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r
9  * the Software, and to permit persons to whom the Software is furnished to do so,\r
10  * subject to the following conditions:\r
11  *\r
12  * The above copyright notice and this permission notice shall be included in all\r
13  * copies or substantial portions of the Software.\r
14  *\r
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
17  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
18  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
19  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
20  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
21  *\r
22  * http://aws.amazon.com/freertos\r
23  * http://www.FreeRTOS.org\r
24  */\r
25 \r
26 /**\r
27  * @file iot_taskpool_internal.h\r
28  * @brief Internal header of task pool library. This header should not be included in\r
29  * typical application code.\r
30  */\r
31 \r
32 #ifndef IOT_TASKPOOL_INTERNAL_H_\r
33 #define IOT_TASKPOOL_INTERNAL_H_\r
34 \r
35 /* The config header is always included first. */\r
36 #include "iot_config.h"\r
37 \r
38 /* Task pool include. */\r
39 #include "private/iot_error.h"\r
40 #include "iot_taskpool.h"\r
41 \r
42 /* FreeRTOS includes. */\r
43 #include "FreeRTOS.h"\r
44 #include "semphr.h"\r
45 #include "timers.h"\r
46 \r
47 /* Establish a few convenience macros to handle errors in a standard way. */\r
48 \r
49 /**\r
50  * @brief Every public API return an enumeration value with an undelying value of 0 in case of success.\r
51  */\r
52 #define TASKPOOL_SUCCEEDED( x )               ( ( x ) == IOT_TASKPOOL_SUCCESS )\r
53 \r
54 /**\r
55  * @brief Every public API returns an enumeration value with an undelying value different than 0 in case of success.\r
56  */\r
57 #define TASKPOOL_FAILED( x )                  ( ( x ) != IOT_TASKPOOL_SUCCESS )\r
58 \r
59 /**\r
60  * @brief Jump to the cleanup area.\r
61  */\r
62 #define TASKPOOL_GOTO_CLEANUP()               IOT_GOTO_CLEANUP()\r
63 \r
64 /**\r
65  * @brief Declare the storage for the error status variable.\r
66  */\r
67 #define  TASKPOOL_FUNCTION_ENTRY( result )    IOT_FUNCTION_ENTRY( IotTaskPoolError_t, result )\r
68 \r
69 /**\r
70  * @brief Check error and leave in case of failure.\r
71  */\r
72 #define TASKPOOL_ON_ERROR_GOTO_CLEANUP( expr )                           \\r
73     { if( TASKPOOL_FAILED( status = ( expr ) ) ) { IOT_GOTO_CLEANUP(); } \\r
74     }\r
75 \r
76 /**\r
77  * @brief Exit if an argument is NULL.\r
78  */\r
79 #define TASKPOOL_ON_NULL_ARG_GOTO_CLEANUP( ptr )      IOT_VALIDATE_PARAMETER( IOT_TASKPOOL, ( ptr != NULL ) )\r
80 \r
81 /**\r
82  * @brief Exit if an argument is NULL.\r
83  */\r
84 #define TASKPOOL_ON_ARG_ERROR_GOTO_CLEANUP( expr )    IOT_VALIDATE_PARAMETER( IOT_TASKPOOL, ( ( expr ) == false ) )\r
85 \r
86 /**\r
87  * @brief Set error and leave.\r
88  */\r
89 #define TASKPOOL_SET_AND_GOTO_CLEANUP( expr )         IOT_SET_AND_GOTO_CLEANUP( expr )\r
90 \r
91 /**\r
92  * @brief Initialize error and declare start of cleanup area.\r
93  */\r
94 #define TASKPOOL_FUNCTION_CLEANUP()                   IOT_FUNCTION_CLEANUP_BEGIN()\r
95 \r
96 /**\r
97  * @brief Initialize error and declare end of cleanup area.\r
98  */\r
99 #define TASKPOOL_FUNCTION_CLEANUP_END()               IOT_FUNCTION_CLEANUP_END()\r
100 \r
101 /**\r
102  * @brief Create an empty cleanup area.\r
103  */\r
104 #define TASKPOOL_NO_FUNCTION_CLEANUP()                IOT_FUNCTION_EXIT_NO_CLEANUP()\r
105 \r
106 /**\r
107  * @brief Does not create a cleanup area.\r
108  */\r
109 #define TASKPOOL_NO_FUNCTION_CLEANUP_NOLABEL()        return status\r
110 \r
111 /**\r
112  * @def IotTaskPool_Assert( expression )\r
113  * @brief Assertion macro for the Task pool library.\r
114  *\r
115  * Set @ref IOT_TASKPOOL_ENABLE_ASSERTS to `1` to enable assertions in the Task pool\r
116  * library.\r
117  *\r
118  * @param[in] expression Expression to be evaluated.\r
119  */\r
120 #if IOT_TASKPOOL_ENABLE_ASSERTS == 1\r
121     #ifndef IotTaskPool_Assert\r
122         #include <assert.h>\r
123         #define IotTaskPool_Assert( expression )    assert( expression )\r
124     #endif\r
125 #else\r
126     #define IotTaskPool_Assert( expression )\r
127 #endif\r
128 \r
129 /* Configure logs for TASKPOOL functions. */\r
130 #ifdef IOT_LOG_LEVEL_TASKPOOL\r
131     #define LIBRARY_LOG_LEVEL        IOT_LOG_LEVEL_TASKPOOL\r
132 #else\r
133     #ifdef IOT_LOG_LEVEL_GLOBAL\r
134         #define LIBRARY_LOG_LEVEL    IOT_LOG_LEVEL_GLOBAL\r
135     #else\r
136         #define LIBRARY_LOG_LEVEL    IOT_LOG_NONE\r
137     #endif\r
138 #endif\r
139 \r
140 #define LIBRARY_LOG_NAME    ( "TASKPOOL" )\r
141 #include "iot_logging_setup.h"\r
142 \r
143 /*\r
144  * Provide default values for undefined memory allocation functions based on\r
145  * the usage of dynamic memory allocation.\r
146  */\r
147 #if IOT_STATIC_MEMORY_ONLY == 1\r
148     #include "private/iot_static_memory.h"\r
149 \r
150 /**\r
151  * @brief Allocate an #_taskPool_t. This function should have the\r
152  * same signature as [malloc].\r
153  */\r
154     void * IotTaskPool_MallocTaskPool( size_t size );\r
155 \r
156 /**\r
157  * @brief Free an #_taskPool_t. This function should have the\r
158  * same signature as [malloc].\r
159  */\r
160     void IotTaskPool_FreeTaskPool( void * ptr );\r
161 \r
162 /**\r
163  * @brief Allocate an #IotTaskPoolJob_t. This function should have the\r
164  * same signature as [malloc].\r
165  */\r
166     void * IotTaskPool_MallocJob( size_t size );\r
167 \r
168 /**\r
169  * @brief Free an #IotTaskPoolJob_t. This function should have the same\r
170  * same signature as [malloc].\r
171  * (http://pubs.opengroup.org/onlinepubs/9699919799/functions/malloc.html).\r
172  */\r
173     void IotTaskPool_FreeJob( void * ptr );\r
174 \r
175 /**\r
176  * @brief Allocate an #_taskPoolTimerEvent_t. This function should have the\r
177  * same signature as [malloc].\r
178  */\r
179     void * IotTaskPool_MallocTimerEvent( size_t size );\r
180 \r
181 /**\r
182  * @brief Free an #_taskPoolTimerEvent_t. This function should have the\r
183  * same signature as[ free ].\r
184  */\r
185     void IotTaskPool_FreeTimerEvent( void * ptr );\r
186 \r
187 #else /* if IOT_STATIC_MEMORY_ONLY == 1 */\r
188     #include <stdlib.h>\r
189 \r
190     #ifndef IotTaskPool_MallocTaskPool\r
191         #define IotTaskPool_MallocTaskPool    malloc\r
192     #endif\r
193 \r
194     #ifndef IotTaskPool_FreeTaskPool\r
195         #define IotTaskPool_FreeTaskPool    free\r
196     #endif\r
197 \r
198     #ifndef IotTaskPool_MallocJob\r
199         #define IotTaskPool_MallocJob    malloc\r
200     #endif\r
201 \r
202     #ifndef IotTaskPool_FreeJob\r
203         #define IotTaskPool_FreeJob    free\r
204     #endif\r
205 \r
206     #ifndef IotTaskPool_MallocTimerEvent\r
207         #define IotTaskPool_MallocTimerEvent    malloc\r
208     #endif\r
209 \r
210     #ifndef IotTaskPool_FreeTimerEvent\r
211         #define IotTaskPool_FreeTimerEvent    free\r
212     #endif\r
213 \r
214 #endif /* if IOT_STATIC_MEMORY_ONLY == 1 */\r
215 \r
216 /* ---------------------------------------------------------------------------------------------- */\r
217 \r
218 /**\r
219  * @cond DOXYGEN_IGNORE\r
220  * Doxygen should ignore this section.\r
221  *\r
222  * A macros to manage task pool memory allocation.\r
223  */\r
224 #define IOT_TASK_POOL_INTERNAL_STATIC    ( ( uint32_t ) 0x00000001 )      /* Flag to mark a job as user-allocated. */\r
225 /** @endcond */\r
226 \r
227 /**\r
228  * @brief Task pool jobs cache.\r
229  *\r
230  * @warning This is a system-level data type that should not be modified or used directly in any application.\r
231  * @warning This is a system-level data type that can and will change across different versions of the platform, with no regards for backward compatibility.\r
232  *\r
233  */\r
234 typedef struct _taskPoolCache\r
235 {\r
236     IotListDouble_t freeList; /**< @brief A list ot hold cached jobs. */\r
237 \r
238     uint32_t freeCount;       /**< @brief A counter to track the number of jobs in the cache. */\r
239 } _taskPoolCache_t;\r
240 \r
241 /**\r
242  * @brief The task pool data structure keeps track of the internal state and the signals for the dispatcher threads.\r
243  * The task pool is a thread safe data structure.\r
244  *\r
245  * @warning This is a system-level data type that should not be modified or used directly in any application.\r
246  * @warning This is a system-level data type that can and will change across different versions of the platform, with no regards for backward compatibility.\r
247  *\r
248  */\r
249 typedef struct _taskPool\r
250 {\r
251     IotDeQueue_t dispatchQueue;              /**< @brief The queue for the jobs waiting to be executed. */\r
252     IotListDouble_t timerEventsList;         /**< @brief The timeouts queue for all deferred jobs waiting to be executed. */\r
253     _taskPoolCache_t jobsCache;              /**< @brief A cache to re-use jobs in order to limit memory allocations. */\r
254     uint32_t activeThreads;                  /**< @brief The number of threads in the task pool at any given time. */\r
255     int32_t priority;                        /**< @brief The priority for all task pool threads. */\r
256     SemaphoreHandle_t dispatchSignal;        /**< @brief The synchronization object on which threads are waiting for incoming jobs. */\r
257     StaticSemaphore_t dispatchSignalBuffer;  /**< @brief The semaphore buffer. */\r
258     SemaphoreHandle_t startStopSignal;       /**< @brief The synchronization object for threads to signal start and stop condition. */\r
259     StaticSemaphore_t startStopSignalBuffer; /**< @brief The semaphore buffer. */\r
260     TimerHandle_t timer;                     /**< @brief The timer for deferred jobs. */\r
261     StaticTimer_t timerBuffer;               /**< @brief The timer buffer. */\r
262     bool running;                            /**< @brief A flag to track whether the task pool is operational or should shut down. */\r
263 } _taskPool_t;\r
264 \r
265 /**\r
266  * @brief The job data structure keeps track of the user callback and context, as well as the status of the job.\r
267  *\r
268  * @warning This is a system-level data type that should not be modified or used directly in any application.\r
269  * @warning This is a system-level data type that can and will change across different versions of the platform, with no regards for backward compatibility.\r
270  *\r
271  */\r
272 typedef struct _taskPoolJob\r
273 {\r
274     IotLink_t link;                    /**< @brief The link to insert the job in the dispatch queue. */\r
275     IotTaskPoolRoutine_t userCallback; /**< @brief The user provided callback. */\r
276     void * pUserContext;               /**< @brief The user provided context. */\r
277     uint32_t flags;                    /**< @brief Internal flags. */\r
278     IotTaskPoolJobStatus_t status;     /**< @brief The status for the job. */\r
279 } _taskPoolJob_t;\r
280 \r
281 /**\r
282  * @brief Represents an operation that is subject to a timer.\r
283  *\r
284  * These events are queued per MQTT connection. They are sorted by their\r
285  * expiration time.\r
286  */\r
287 typedef struct _taskPoolTimerEvent\r
288 {\r
289     IotLink_t link;            /**< @brief List link member. */\r
290     TickType_t expirationTime; /**< @brief When this event should be processed. */\r
291     IotTaskPoolJob_t job;      /**< @brief The task pool job associated with this event. */\r
292 } _taskPoolTimerEvent_t;\r
293 \r
294 #endif /* ifndef IOT_TASKPOOL_INTERNAL_H_ */