ChibiOS 21.11.4
chjobs.h
Go to the documentation of this file.
1/*
2 ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014,
3 2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio.
4
5 This file is part of ChibiOS.
6
7 ChibiOS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation version 3 of the License.
10
11 ChibiOS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20/**
21 * @file oslib/include/chjobs.h
22 * @brief Jobs Queues structures and macros.
23 * @details This module implements queues of generic jobs to be delegated
24 * asynchronously to a pool of dedicated threads.
25 * Operations defined for Jobs Queues
26 * - <b>Get</b>: An job object is taken from the pool of the
27 * available jobs.
28 * - <b>Post</b>: A job is posted to the queue, it will be
29 * returned to the pool after execution.
30 * .
31 *
32 * @addtogroup oslib_jobs_queues
33 * @{
34 */
35
36#ifndef CHJOBS_H
37#define CHJOBS_H
38
39#if (CH_CFG_USE_JOBS == TRUE) || defined(__DOXYGEN__)
40
41/*===========================================================================*/
42/* Module constants. */
43/*===========================================================================*/
44
45/**
46 * @brief Dispatcher return code in case of a @p JOB_NUL has been received.
47 */
48#define MSG_JOB_NULL ((msg_t)-2)
49
50/*===========================================================================*/
51/* Module pre-compile time settings. */
52/*===========================================================================*/
53
54/*===========================================================================*/
55/* Derived constants and error checks. */
56/*===========================================================================*/
57
58#if CH_CFG_USE_MEMPOOLS == FALSE
59#error "CH_CFG_USE_JOBS requires CH_CFG_USE_MEMPOOLS"
60#endif
61
62#if CH_CFG_USE_SEMAPHORES == FALSE
63#error "CH_CFG_USE_JOBS requires CH_CFG_USE_SEMAPHORES"
64#endif
65
66#if CH_CFG_USE_MAILBOXES == FALSE
67#error "CH_CFG_USE_JOBS requires CH_CFG_USE_MAILBOXES"
68#endif
69
70/*===========================================================================*/
71/* Module data structures and types. */
72/*===========================================================================*/
73
74/**
75 * @brief Type of a jobs queue.
76 */
77typedef struct ch_jobs_queue {
78 /**
79 * @brief Pool of the free jobs.
80 */
82 /**
83 * @brief Mailbox of the sent jobs.
84 */
87
88/**
89 * @brief Type of a job function.
90 */
91typedef void (*job_function_t)(void *arg);
92
93/**
94 * @brief Type of a job descriptor.
95 */
96typedef struct ch_job_descriptor {
97 /**
98 * @brief Job function.
99 */
101 /**
102 * @brief Argument to be passed to the job function.
103 */
104 void *jobarg;
106
107/*===========================================================================*/
108/* Module macros. */
109/*===========================================================================*/
110
111/*===========================================================================*/
112/* External declarations. */
113/*===========================================================================*/
114
115#ifdef __cplusplus
116extern "C" {
117#endif
118
119#ifdef __cplusplus
120}
121#endif
122
123/*===========================================================================*/
124/* Module inline functions. */
125/*===========================================================================*/
126
127/**
128 * @brief Initializes a jobs queue object.
129 *
130 * @param[out] jqp pointer to a @p jobs_queue_t structure
131 * @param[in] jobsn number of jobs available
132 * @param[in] jobsbuf pointer to the buffer of jobs, it must be able
133 * to hold @p jobsn @p job_descriptor_t structures
134 * @param[in] msgbuf pointer to the buffer of messages, it must be able
135 * to hold @p jobsn @p msg_t messages
136 *
137 * @init
138 */
139static inline void chJobObjectInit(jobs_queue_t *jqp,
140 size_t jobsn,
141 job_descriptor_t *jobsbuf,
142 msg_t *msgbuf) {
143
144 chDbgCheck((jobsn > 0U) && (jobsbuf != NULL) && (msgbuf != NULL));
145
147 chGuardedPoolLoadArray(&jqp->free, (void *)jobsbuf, jobsn);
148 chMBObjectInit(&jqp->mbx, msgbuf, jobsn);
149}
150
151/**
152 * @brief Allocates a free job object.
153 *
154 * @param[in] jqp pointer to a @p jobs_queue_t structure
155 * @return The pointer to the allocated job object.
156 *
157 * @api
158 */
163
164/**
165 * @brief Allocates a free job object.
166 *
167 * @param[in] jqp pointer to a @p jobs_queue_t structure
168 * @return The pointer to the allocated job object.
169 * @retval NULL if a job object is not immediately available.
170 *
171 * @iclass
172 */
174
176}
177
178/**
179 * @brief Allocates a free job object.
180 *
181 * @param[in] jqp pointer to a @p jobs_queue_t structure
182 * @param[in] timeout the number of ticks before the operation timeouts,
183 * the following special values are allowed:
184 * - @a TIME_IMMEDIATE immediate timeout.
185 * - @a TIME_INFINITE no timeout.
186 * .
187 * @return The pointer to the allocated job object.
188 * @retval NULL if a job object is not available within the specified
189 * timeout.
190 *
191 * @sclass
192 */
194 sysinterval_t timeout) {
195
196 return (job_descriptor_t *)chGuardedPoolAllocTimeoutS(&jqp->free, timeout);
197}
198
199/**
200 * @brief Allocates a free job object.
201 *
202 * @param[in] jqp pointer to a @p jobs_queue_t structure
203 * @param[in] timeout the number of ticks before the operation timeouts,
204 * the following special values are allowed:
205 * - @a TIME_IMMEDIATE immediate timeout.
206 * - @a TIME_INFINITE no timeout.
207 * .
208 * @return The pointer to the allocated job object.
209 * @retval NULL if a job object is not available within the specified
210 * timeout.
211 *
212 * @api
213 */
215 sysinterval_t timeout) {
216
217 return (job_descriptor_t *)chGuardedPoolAllocTimeout(&jqp->free, timeout);
218}
219
220/**
221 * @brief Posts a job object.
222 * @note By design the object can be always immediately posted.
223 *
224 * @param[in] jqp pointer to a @p jobs_queue_t structure
225 * @param[in] jp pointer to the job object to be posted
226 *
227 * @iclass
228 */
229static inline void chJobPostI(jobs_queue_t *jqp, job_descriptor_t *jp) {
230 msg_t msg;
231
232 msg = chMBPostI(&jqp->mbx, (msg_t)jp);
233 chDbgAssert(msg == MSG_OK, "post failed");
234}
235
236/**
237 * @brief Posts a job object.
238 * @note By design the object can be always immediately posted.
239 *
240 * @param[in] jqp pointer to a @p jobs_queue_t structure
241 * @param[in] jp pointer to the job object to be posted
242 *
243 * @sclass
244 */
245static inline void chJobPostS(jobs_queue_t *jqp, job_descriptor_t *jp) {
246 msg_t msg;
247
248 msg = chMBPostTimeoutS(&jqp->mbx, (msg_t)jp, TIME_IMMEDIATE);
249 chDbgAssert(msg == MSG_OK, "post failed");
250}
251
252/**
253 * @brief Posts a job object.
254 * @note By design the object can be always immediately posted.
255 *
256 * @param[in] jqp pointer to a @p jobs_queue_t structure
257 * @param[in] jp pointer to the job object to be posted
258 *
259 * @api
260 */
261static inline void chJobPost(jobs_queue_t *jqp, job_descriptor_t *jp) {
262 msg_t msg;
263
264 msg = chMBPostTimeout(&jqp->mbx, (msg_t)jp, TIME_IMMEDIATE);
265 chDbgAssert(msg == MSG_OK, "post failed");
266}
267
268/**
269 * @brief Posts an high priority job object.
270 * @note By design the object can be always immediately posted.
271 *
272 * @param[in] jqp pointer to a @p jobs_queue_t structure
273 * @param[in] jp pointer to the job object to be posted
274 *
275 * @iclass
276 */
277static inline void chJobPostAheadI(jobs_queue_t *jqp, job_descriptor_t *jp) {
278 msg_t msg;
279
280 msg = chMBPostAheadI(&jqp->mbx, (msg_t)jp);
281 chDbgAssert(msg == MSG_OK, "post failed");
282}
283
284/**
285 * @brief Posts an high priority job object.
286 * @note By design the object can be always immediately posted.
287 *
288 * @param[in] jqp pointer to a @p jobs_queue_t structure
289 * @param[in] jp pointer to the job object to be posted
290 *
291 * @sclass
292 */
293static inline void chJobPostAheadS(jobs_queue_t *jqp, job_descriptor_t *jp) {
294 msg_t msg;
295
297 chDbgAssert(msg == MSG_OK, "post failed");
298}
299
300/**
301 * @brief Posts an high priority job object.
302 * @note By design the object can be always immediately posted.
303 *
304 * @param[in] jqp pointer to a @p jobs_queue_t structure
305 * @param[in] jp pointer to the job object to be posted
306 *
307 * @api
308 */
309static inline void chJobPostAhead(jobs_queue_t *jqp, job_descriptor_t *jp) {
310 msg_t msg;
311
312 msg = chMBPostAheadTimeout(&jqp->mbx, (msg_t)jp, TIME_IMMEDIATE);
313 chDbgAssert(msg == MSG_OK, "post failed");
314}
315
316/**
317 * @brief Waits for a job then executes it.
318 *
319 * @param[in] jqp pointer to a @p jobs_queue_t structure
320 * @return The function outcome.
321 * @retval MSG_OK if a job has been executed.
322 * @retval MSG_RESET if the internal mailbox has been reset.
323 * @retval MSG_JOB_NULL if a @p JOB_NULL has been received.
324 */
325static inline msg_t chJobDispatch(jobs_queue_t *jqp) {
326 msg_t msg, jmsg;
327
328 /* Waiting for a job.*/
329 msg = chMBFetchTimeout(&jqp->mbx, &jmsg, TIME_INFINITE);
330 if (msg == MSG_OK) {
332
333 chDbgAssert(jp != NULL, "is NULL");
334
335 if (jp->jobfunc != NULL) {
336
337 /* Invoking the job function.*/
338 jp->jobfunc(jp->jobarg);
339
340 /* Returning the job descriptor object.*/
341 chGuardedPoolFree(&jqp->free, (void *)jp);
342 }
343 else {
344 msg = MSG_JOB_NULL;
345 }
346 }
347
348 return msg;
349}
350
351/**
352 * @brief Waits for a job then executes it.
353 *
354 * @param[in] jqp pointer to a @p jobs_queue_t structure
355 * @param[in] timeout the number of ticks before the operation timeouts,
356 * the following special values are allowed:
357 * - @a TIME_IMMEDIATE immediate timeout.
358 * - @a TIME_INFINITE no timeout.
359 * .
360 * @return The function outcome.
361 * @retval MSG_OK if a job has been executed.
362 * @retval MSG_TIMEOUT if a timeout occurred.
363 * @retval MSG_RESET if the internal mailbox has been reset.
364 * @retval MSG_JOB_NULL if a @p JOB_NULL has been received.
365 */
367 sysinterval_t timeout) {
368 msg_t msg, jmsg;
369
370 /* Waiting for a job or a timeout.*/
371 msg = chMBFetchTimeout(&jqp->mbx, &jmsg, timeout);
372 if (msg == MSG_OK) {
374
375 chDbgAssert(jp != NULL, "is NULL");
376
377 if (jp->jobfunc != NULL) {
378
379 /* Invoking the job function.*/
380 jp->jobfunc(jp->jobarg);
381
382 /* Returning the job descriptor object.*/
383 chGuardedPoolFree(&jqp->free, (void *)jp);
384 }
385 else {
386 msg = MSG_JOB_NULL;
387 }
388 }
389
390 return msg;
391}
392
393#endif /* CH_CFG_USE_JOBS == TRUE */
394
395#endif /* CHJOBS_H */
396
397/** @} */
#define chDbgAssert(c, r)
Condition assertion.
Definition chdebug.h:144
#define chDbgCheck(c)
Function parameters check.
Definition chdebug.h:118
int32_t msg_t
Definition chearly.h:88
static void chJobPostS(jobs_queue_t *jqp, job_descriptor_t *jp)
Posts a job object.
Definition chjobs.h:245
static void chJobPost(jobs_queue_t *jqp, job_descriptor_t *jp)
Posts a job object.
Definition chjobs.h:261
static msg_t chJobDispatchTimeout(jobs_queue_t *jqp, sysinterval_t timeout)
Waits for a job then executes it.
Definition chjobs.h:366
static job_descriptor_t * chJobGet(jobs_queue_t *jqp)
Allocates a free job object.
Definition chjobs.h:159
static void chJobPostAheadS(jobs_queue_t *jqp, job_descriptor_t *jp)
Posts an high priority job object.
Definition chjobs.h:293
static void chJobPostI(jobs_queue_t *jqp, job_descriptor_t *jp)
Posts a job object.
Definition chjobs.h:229
static void chJobObjectInit(jobs_queue_t *jqp, size_t jobsn, job_descriptor_t *jobsbuf, msg_t *msgbuf)
Initializes a jobs queue object.
Definition chjobs.h:139
void(* job_function_t)(void *arg)
Type of a job function.
Definition chjobs.h:91
static job_descriptor_t * chJobGetI(jobs_queue_t *jqp)
Allocates a free job object.
Definition chjobs.h:173
static void chJobPostAheadI(jobs_queue_t *jqp, job_descriptor_t *jp)
Posts an high priority job object.
Definition chjobs.h:277
static job_descriptor_t * chJobGetTimeout(jobs_queue_t *jqp, sysinterval_t timeout)
Allocates a free job object.
Definition chjobs.h:214
#define MSG_JOB_NULL
Dispatcher return code in case of a JOB_NUL has been received.
Definition chjobs.h:48
static job_descriptor_t * chJobGetTimeoutS(jobs_queue_t *jqp, sysinterval_t timeout)
Allocates a free job object.
Definition chjobs.h:193
static void chJobPostAhead(jobs_queue_t *jqp, job_descriptor_t *jp)
Posts an high priority job object.
Definition chjobs.h:309
struct ch_jobs_queue jobs_queue_t
Type of a jobs queue.
static msg_t chJobDispatch(jobs_queue_t *jqp)
Waits for a job then executes it.
Definition chjobs.h:325
struct ch_job_descriptor job_descriptor_t
Type of a job descriptor.
void chMBObjectInit(mailbox_t *mbp, msg_t *buf, size_t n)
Initializes a mailbox_t object.
Definition chmboxes.c:87
msg_t chMBFetchTimeout(mailbox_t *mbp, msg_t *msgp, sysinterval_t timeout)
Retrieves a message from a mailbox.
Definition chmboxes.c:415
msg_t chMBPostTimeout(mailbox_t *mbp, msg_t msg, sysinterval_t timeout)
Posts a message into a mailbox.
Definition chmboxes.c:165
msg_t chMBPostI(mailbox_t *mbp, msg_t msg)
Posts a message into a mailbox.
Definition chmboxes.c:243
msg_t chMBPostAheadTimeout(mailbox_t *mbp, msg_t msg, sysinterval_t timeout)
Posts an high priority message into a mailbox.
Definition chmboxes.c:290
msg_t chMBPostTimeoutS(mailbox_t *mbp, msg_t msg, sysinterval_t timeout)
Posts a message into a mailbox.
Definition chmboxes.c:194
msg_t chMBPostAheadTimeoutS(mailbox_t *mbp, msg_t msg, sysinterval_t timeout)
Posts an high priority message into a mailbox.
Definition chmboxes.c:319
msg_t chMBPostAheadI(mailbox_t *mbp, msg_t msg)
Posts an high priority message into a mailbox.
Definition chmboxes.c:368
void * chGuardedPoolAllocTimeout(guarded_memory_pool_t *gmp, sysinterval_t timeout)
Allocates an object from a guarded memory pool.
Definition chmempools.c:302
void * chGuardedPoolAllocTimeoutS(guarded_memory_pool_t *gmp, sysinterval_t timeout)
Allocates an object from a guarded memory pool.
Definition chmempools.c:275
void chGuardedPoolLoadArray(guarded_memory_pool_t *gmp, void *p, size_t n)
Loads a guarded memory pool with an array of static objects.
Definition chmempools.c:247
static void chGuardedPoolObjectInit(guarded_memory_pool_t *gmp, size_t size)
Initializes an empty guarded memory pool.
Definition chmempools.h:245
void chGuardedPoolFree(guarded_memory_pool_t *gmp, void *objp)
Releases an object into a guarded memory pool.
Definition chmempools.c:325
static void * chGuardedPoolAllocI(guarded_memory_pool_t *gmp)
Allocates an object from a guarded memory pool.
Definition chmempools.h:275
#define MSG_OK
Normal wakeup message.
Definition chschd.h:39
#define TIME_IMMEDIATE
Zero interval specification for some functions with a timeout specification.
Definition chtime.h:47
uint64_t sysinterval_t
Type of time interval.
Definition chtime.h:119
#define TIME_INFINITE
Infinite interval specification for all functions with a timeout specification.
Definition chtime.h:55
Type of a job descriptor.
Definition chjobs.h:96
void * jobarg
Argument to be passed to the job function.
Definition chjobs.h:104
job_function_t jobfunc
Job function.
Definition chjobs.h:100
Type of a jobs queue.
Definition chjobs.h:77
guarded_memory_pool_t free
Pool of the free jobs.
Definition chjobs.h:81
mailbox_t mbx
Mailbox of the sent jobs.
Definition chjobs.h:85
Guarded memory pool descriptor.
Definition chmempools.h:77
Structure representing a mailbox object.
Definition chmboxes.h:52