ChibiOS  21.6.0
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  */
77 typedef struct ch_jobs_queue {
78  /**
79  * @brief Pool of the free jobs.
80  */
82  /**
83  * @brief Mailbox of the sent jobs.
84  */
86 } jobs_queue_t;
87 
88 /**
89  * @brief Type of a job function.
90  */
91 typedef void (*job_function_t)(void *arg);
92 
93 /**
94  * @brief Type of a job descriptor.
95  */
96 typedef 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
116 extern "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  */
139 static 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  */
159 static inline job_descriptor_t *chJobGet(jobs_queue_t *jqp) {
160 
162 }
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 
175  return (job_descriptor_t *)chGuardedPoolAllocI(&jqp->free);
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  */
229 static 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  */
245 static 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  */
261 static 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  */
277 static 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  */
293 static inline void chJobPostAheadS(jobs_queue_t *jqp, job_descriptor_t *jp) {
294  msg_t msg;
295 
296  msg = chMBPostAheadTimeoutS(&jqp->mbx, (msg_t)jp, TIME_IMMEDIATE);
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  */
309 static 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  */
325 static 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) {
331  job_descriptor_t *jp = (job_descriptor_t *)jmsg;
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) {
373  job_descriptor_t *jp = (job_descriptor_t *)jmsg;
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 /** @} */
chMBPostI
msg_t chMBPostI(mailbox_t *mbp, msg_t msg)
Posts a message into a mailbox.
Definition: chmboxes.c:243
chJobGetTimeout
static job_descriptor_t * chJobGetTimeout(jobs_queue_t *jqp, sysinterval_t timeout)
Allocates a free job object.
Definition: chjobs.h:214
chGuardedPoolAllocI
static void * chGuardedPoolAllocI(guarded_memory_pool_t *gmp)
Allocates an object from a guarded memory pool.
Definition: chmempools.h:275
chGuardedPoolAllocTimeout
void * chGuardedPoolAllocTimeout(guarded_memory_pool_t *gmp, sysinterval_t timeout)
Allocates an object from a guarded memory pool.
Definition: chmempools.c:302
chGuardedPoolLoadArray
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
chJobPost
static void chJobPost(jobs_queue_t *jqp, job_descriptor_t *jp)
Posts a job object.
Definition: chjobs.h:261
chJobPostS
static void chJobPostS(jobs_queue_t *jqp, job_descriptor_t *jp)
Posts a job object.
Definition: chjobs.h:245
chJobGetI
static job_descriptor_t * chJobGetI(jobs_queue_t *jqp)
Allocates a free job object.
Definition: chjobs.h:173
chDbgAssert
#define chDbgAssert(c, r)
Condition assertion.
Definition: chdebug.h:144
guarded_memory_pool_t
Guarded memory pool descriptor.
Definition: chmempools.h:77
job_descriptor_t
struct ch_job_descriptor job_descriptor_t
Type of a job descriptor.
chMBPostTimeoutS
msg_t chMBPostTimeoutS(mailbox_t *mbp, msg_t msg, sysinterval_t timeout)
Posts a message into a mailbox.
Definition: chmboxes.c:194
chJobGetTimeoutS
static job_descriptor_t * chJobGetTimeoutS(jobs_queue_t *jqp, sysinterval_t timeout)
Allocates a free job object.
Definition: chjobs.h:193
msg_t
int32_t msg_t
Definition: chearly.h:88
ch_job_descriptor::jobarg
void * jobarg
Argument to be passed to the job function.
Definition: chjobs.h:104
chJobDispatch
static msg_t chJobDispatch(jobs_queue_t *jqp)
Waits for a job then executes it.
Definition: chjobs.h:325
chMBPostTimeout
msg_t chMBPostTimeout(mailbox_t *mbp, msg_t msg, sysinterval_t timeout)
Posts a message into a mailbox.
Definition: chmboxes.c:165
chJobGet
static job_descriptor_t * chJobGet(jobs_queue_t *jqp)
Allocates a free job object.
Definition: chjobs.h:159
chJobPostAheadS
static void chJobPostAheadS(jobs_queue_t *jqp, job_descriptor_t *jp)
Posts an high priority job object.
Definition: chjobs.h:293
chDbgCheck
#define chDbgCheck(c)
Function parameters check.
Definition: chdebug.h:118
ch_jobs_queue::mbx
mailbox_t mbx
Mailbox of the sent jobs.
Definition: chjobs.h:85
TIME_IMMEDIATE
#define TIME_IMMEDIATE
Zero interval specification for some functions with a timeout specification.
Definition: chtime.h:47
chJobObjectInit
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
ch_jobs_queue
Type of a jobs queue.
Definition: chjobs.h:77
ch_job_descriptor::jobfunc
job_function_t jobfunc
Job function.
Definition: chjobs.h:100
chMBObjectInit
void chMBObjectInit(mailbox_t *mbp, msg_t *buf, size_t n)
Initializes a mailbox_t object.
Definition: chmboxes.c:87
TIME_INFINITE
#define TIME_INFINITE
Infinite interval specification for all functions with a timeout specification.
Definition: chtime.h:55
ch_jobs_queue::free
guarded_memory_pool_t free
Pool of the free jobs.
Definition: chjobs.h:81
chJobPostAhead
static void chJobPostAhead(jobs_queue_t *jqp, job_descriptor_t *jp)
Posts an high priority job object.
Definition: chjobs.h:309
MSG_OK
#define MSG_OK
Normal wakeup message.
Definition: chschd.h:39
sysinterval_t
uint64_t sysinterval_t
Type of time interval.
Definition: chtime.h:119
chJobDispatchTimeout
static msg_t chJobDispatchTimeout(jobs_queue_t *jqp, sysinterval_t timeout)
Waits for a job then executes it.
Definition: chjobs.h:366
chJobPostI
static void chJobPostI(jobs_queue_t *jqp, job_descriptor_t *jp)
Posts a job object.
Definition: chjobs.h:229
chGuardedPoolObjectInit
static void chGuardedPoolObjectInit(guarded_memory_pool_t *gmp, size_t size)
Initializes an empty guarded memory pool.
Definition: chmempools.h:245
ch_job_descriptor
Type of a job descriptor.
Definition: chjobs.h:96
job_function_t
void(* job_function_t)(void *arg)
Type of a job function.
Definition: chjobs.h:91
chMBFetchTimeout
msg_t chMBFetchTimeout(mailbox_t *mbp, msg_t *msgp, sysinterval_t timeout)
Retrieves a message from a mailbox.
Definition: chmboxes.c:415
MSG_JOB_NULL
#define MSG_JOB_NULL
Dispatcher return code in case of a JOB_NUL has been received.
Definition: chjobs.h:48
jobs_queue_t
struct ch_jobs_queue jobs_queue_t
Type of a jobs queue.
mailbox_t
Structure representing a mailbox object.
Definition: chmboxes.h:52
chMBPostAheadTimeout
msg_t chMBPostAheadTimeout(mailbox_t *mbp, msg_t msg, sysinterval_t timeout)
Posts an high priority message into a mailbox.
Definition: chmboxes.c:290
chGuardedPoolAllocTimeoutS
void * chGuardedPoolAllocTimeoutS(guarded_memory_pool_t *gmp, sysinterval_t timeout)
Allocates an object from a guarded memory pool.
Definition: chmempools.c:275
chGuardedPoolFree
void chGuardedPoolFree(guarded_memory_pool_t *gmp, void *objp)
Releases an object into a guarded memory pool.
Definition: chmempools.c:325
chMBPostAheadTimeoutS
msg_t chMBPostAheadTimeoutS(mailbox_t *mbp, msg_t msg, sysinterval_t timeout)
Posts an high priority message into a mailbox.
Definition: chmboxes.c:319
chJobPostAheadI
static void chJobPostAheadI(jobs_queue_t *jqp, job_descriptor_t *jp)
Posts an high priority job object.
Definition: chjobs.h:277
chMBPostAheadI
msg_t chMBPostAheadI(mailbox_t *mbp, msg_t msg)
Posts an high priority message into a mailbox.
Definition: chmboxes.c:368