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