diff options
Diffstat (limited to 'lib/chibios/os/rt/include/chschd.h')
-rw-r--r-- | lib/chibios/os/rt/include/chschd.h | 600 |
1 files changed, 600 insertions, 0 deletions
diff --git a/lib/chibios/os/rt/include/chschd.h b/lib/chibios/os/rt/include/chschd.h new file mode 100644 index 000000000..ff4c7abb4 --- /dev/null +++ b/lib/chibios/os/rt/include/chschd.h | |||
@@ -0,0 +1,600 @@ | |||
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 rt/include/chschd.h | ||
22 | * @brief Scheduler macros and structures. | ||
23 | * | ||
24 | * @addtogroup scheduler | ||
25 | * @{ | ||
26 | */ | ||
27 | |||
28 | #ifndef CHSCHD_H | ||
29 | #define CHSCHD_H | ||
30 | |||
31 | /*===========================================================================*/ | ||
32 | /* Module constants. */ | ||
33 | /*===========================================================================*/ | ||
34 | |||
35 | /** | ||
36 | * @name Wakeup status codes | ||
37 | * @{ | ||
38 | */ | ||
39 | #define MSG_OK (msg_t)0 /**< @brief Normal wakeup message. */ | ||
40 | #define MSG_TIMEOUT (msg_t)-1 /**< @brief Wakeup caused by a timeout | ||
41 | condition. */ | ||
42 | #define MSG_RESET (msg_t)-2 /**< @brief Wakeup caused by a reset | ||
43 | condition. */ | ||
44 | /** @} */ | ||
45 | |||
46 | /** | ||
47 | * @name Priority constants | ||
48 | * @{ | ||
49 | */ | ||
50 | #define NOPRIO (tprio_t)0 /**< @brief Ready list header | ||
51 | priority. */ | ||
52 | #define IDLEPRIO (tprio_t)1 /**< @brief Idle priority. */ | ||
53 | #define LOWPRIO (tprio_t)2 /**< @brief Lowest priority. */ | ||
54 | #define NORMALPRIO (tprio_t)128 /**< @brief Normal priority. */ | ||
55 | #define HIGHPRIO (tprio_t)255 /**< @brief Highest priority. */ | ||
56 | /** @} */ | ||
57 | |||
58 | /** | ||
59 | * @name Thread states | ||
60 | * @{ | ||
61 | */ | ||
62 | #define CH_STATE_READY (tstate_t)0 /**< @brief Waiting on the | ||
63 | ready list. */ | ||
64 | #define CH_STATE_CURRENT (tstate_t)1 /**< @brief Currently running. */ | ||
65 | #define CH_STATE_WTSTART (tstate_t)2 /**< @brief Just created. */ | ||
66 | #define CH_STATE_SUSPENDED (tstate_t)3 /**< @brief Suspended state. */ | ||
67 | #define CH_STATE_QUEUED (tstate_t)4 /**< @brief On a queue. */ | ||
68 | #define CH_STATE_WTSEM (tstate_t)5 /**< @brief On a semaphore. */ | ||
69 | #define CH_STATE_WTMTX (tstate_t)6 /**< @brief On a mutex. */ | ||
70 | #define CH_STATE_WTCOND (tstate_t)7 /**< @brief On a cond.variable.*/ | ||
71 | #define CH_STATE_SLEEPING (tstate_t)8 /**< @brief Sleeping. */ | ||
72 | #define CH_STATE_WTEXIT (tstate_t)9 /**< @brief Waiting a thread. */ | ||
73 | #define CH_STATE_WTOREVT (tstate_t)10 /**< @brief One event. */ | ||
74 | #define CH_STATE_WTANDEVT (tstate_t)11 /**< @brief Several events. */ | ||
75 | #define CH_STATE_SNDMSGQ (tstate_t)12 /**< @brief Sending a message, | ||
76 | in queue. */ | ||
77 | #define CH_STATE_SNDMSG (tstate_t)13 /**< @brief Sent a message, | ||
78 | waiting answer. */ | ||
79 | #define CH_STATE_WTMSG (tstate_t)14 /**< @brief Waiting for a | ||
80 | message. */ | ||
81 | #define CH_STATE_FINAL (tstate_t)15 /**< @brief Thread terminated. */ | ||
82 | |||
83 | /** | ||
84 | * @brief Thread states as array of strings. | ||
85 | * @details Each element in an array initialized with this macro can be | ||
86 | * indexed using the numeric thread state values. | ||
87 | */ | ||
88 | #define CH_STATE_NAMES \ | ||
89 | "READY", "CURRENT", "WTSTART", "SUSPENDED", "QUEUED", "WTSEM", "WTMTX", \ | ||
90 | "WTCOND", "SLEEPING", "WTEXIT", "WTOREVT", "WTANDEVT", "SNDMSGQ", \ | ||
91 | "SNDMSG", "WTMSG", "FINAL" | ||
92 | /** @} */ | ||
93 | |||
94 | /** | ||
95 | * @name Thread flags and attributes | ||
96 | * @{ | ||
97 | */ | ||
98 | #define CH_FLAG_MODE_MASK (tmode_t)3U /**< @brief Thread memory mode | ||
99 | mask. */ | ||
100 | #define CH_FLAG_MODE_STATIC (tmode_t)0U /**< @brief Static thread. */ | ||
101 | #define CH_FLAG_MODE_HEAP (tmode_t)1U /**< @brief Thread allocated | ||
102 | from a Memory Heap. */ | ||
103 | #define CH_FLAG_MODE_MPOOL (tmode_t)2U /**< @brief Thread allocated | ||
104 | from a Memory Pool. */ | ||
105 | #define CH_FLAG_TERMINATE (tmode_t)4U /**< @brief Termination requested | ||
106 | flag. */ | ||
107 | /** @} */ | ||
108 | |||
109 | /*===========================================================================*/ | ||
110 | /* Module pre-compile time settings. */ | ||
111 | /*===========================================================================*/ | ||
112 | |||
113 | /*===========================================================================*/ | ||
114 | /* Derived constants and error checks. */ | ||
115 | /*===========================================================================*/ | ||
116 | |||
117 | /*===========================================================================*/ | ||
118 | /* Module data structures and types. */ | ||
119 | /*===========================================================================*/ | ||
120 | |||
121 | /** | ||
122 | * @brief Structure representing a threads queue. | ||
123 | */ | ||
124 | struct ch_threads_queue { | ||
125 | ch_queue_t queue; /**< @brief Threads queue header. */ | ||
126 | }; | ||
127 | |||
128 | /** | ||
129 | * @brief Structure representing a thread. | ||
130 | * @note Not all the listed fields are always needed, by switching off some | ||
131 | * not needed ChibiOS/RT subsystems it is possible to save RAM space | ||
132 | * by shrinking this structure. | ||
133 | */ | ||
134 | struct ch_thread { | ||
135 | union { | ||
136 | ch_list_t list; /**< @brief Threads lists element. */ | ||
137 | ch_queue_t queue; /**< @brief Threads queues element. */ | ||
138 | ch_priority_queue_t pqueue; /**< @brief Threads ordered queues | ||
139 | element. */ | ||
140 | } hdr; | ||
141 | struct port_context ctx; /**< @brief Processor context. */ | ||
142 | #if (CH_CFG_USE_REGISTRY == TRUE) || defined(__DOXYGEN__) | ||
143 | thread_t *newer; /**< @brief Newer registry element. */ | ||
144 | thread_t *older; /**< @brief Older registry element. */ | ||
145 | #endif | ||
146 | /* End of the fields shared with the ReadyList structure. */ | ||
147 | #if (CH_CFG_USE_REGISTRY == TRUE) || defined(__DOXYGEN__) | ||
148 | /** | ||
149 | * @brief Thread name or @p NULL. | ||
150 | */ | ||
151 | const char *name; | ||
152 | #endif | ||
153 | #if (CH_DBG_ENABLE_STACK_CHECK == TRUE) || (CH_CFG_USE_DYNAMIC == TRUE) || \ | ||
154 | defined(__DOXYGEN__) | ||
155 | /** | ||
156 | * @brief Working area base address. | ||
157 | * @note This pointer is used for stack overflow checks and for | ||
158 | * dynamic threading. | ||
159 | */ | ||
160 | stkalign_t *wabase; | ||
161 | #endif | ||
162 | /** | ||
163 | * @brief Current thread state. | ||
164 | */ | ||
165 | tstate_t state; | ||
166 | /** | ||
167 | * @brief Various thread flags. | ||
168 | */ | ||
169 | tmode_t flags; | ||
170 | #if (CH_CFG_USE_REGISTRY == TRUE) || defined(__DOXYGEN__) | ||
171 | /** | ||
172 | * @brief References to this thread. | ||
173 | */ | ||
174 | trefs_t refs; | ||
175 | #endif | ||
176 | /** | ||
177 | * @brief Number of ticks remaining to this thread. | ||
178 | */ | ||
179 | #if (CH_CFG_TIME_QUANTUM > 0) || defined(__DOXYGEN__) | ||
180 | tslices_t ticks; | ||
181 | #endif | ||
182 | #if (CH_DBG_THREADS_PROFILING == TRUE) || defined(__DOXYGEN__) | ||
183 | /** | ||
184 | * @brief Thread consumed time in ticks. | ||
185 | * @note This field can overflow. | ||
186 | */ | ||
187 | volatile systime_t time; | ||
188 | #endif | ||
189 | /** | ||
190 | * @brief State-specific fields. | ||
191 | * @note All the fields declared in this union are only valid in the | ||
192 | * specified state or condition and are thus volatile. | ||
193 | */ | ||
194 | union { | ||
195 | /** | ||
196 | * @brief Thread wakeup code. | ||
197 | * @note This field contains the low level message sent to the thread | ||
198 | * by the waking thread or interrupt handler. The value is valid | ||
199 | * after exiting the @p chSchWakeupS() function. | ||
200 | */ | ||
201 | msg_t rdymsg; | ||
202 | /** | ||
203 | * @brief Thread exit code. | ||
204 | * @note The thread termination code is stored in this field in order | ||
205 | * to be retrieved by the thread performing a @p chThdWait() on | ||
206 | * this thread. | ||
207 | */ | ||
208 | msg_t exitcode; | ||
209 | /** | ||
210 | * @brief Pointer to a generic "wait" object. | ||
211 | * @note This field is used to get a generic pointer to a synchronization | ||
212 | * object and is valid when the thread is in one of the wait | ||
213 | * states. | ||
214 | */ | ||
215 | void *wtobjp; | ||
216 | /** | ||
217 | * @brief Pointer to a generic thread reference object. | ||
218 | * @note This field is used to get a pointer to a synchronization | ||
219 | * object and is valid when the thread is in @p CH_STATE_SUSPENDED | ||
220 | * state. | ||
221 | */ | ||
222 | thread_reference_t *wttrp; | ||
223 | #if (CH_CFG_USE_MESSAGES == TRUE) || defined(__DOXYGEN__) | ||
224 | /** | ||
225 | * @brief Thread sent message. | ||
226 | */ | ||
227 | msg_t sentmsg; | ||
228 | #endif | ||
229 | #if (CH_CFG_USE_SEMAPHORES == TRUE) || defined(__DOXYGEN__) | ||
230 | /** | ||
231 | * @brief Pointer to a generic semaphore object. | ||
232 | * @note This field is used to get a pointer to a synchronization | ||
233 | * object and is valid when the thread is in @p CH_STATE_WTSEM | ||
234 | * state. | ||
235 | */ | ||
236 | struct ch_semaphore *wtsemp; | ||
237 | #endif | ||
238 | #if (CH_CFG_USE_MUTEXES == TRUE) || defined(__DOXYGEN__) | ||
239 | /** | ||
240 | * @brief Pointer to a generic mutex object. | ||
241 | * @note This field is used to get a pointer to a synchronization | ||
242 | * object and is valid when the thread is in @p CH_STATE_WTMTX | ||
243 | * state. | ||
244 | */ | ||
245 | struct ch_mutex *wtmtxp; | ||
246 | #endif | ||
247 | #if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__) | ||
248 | /** | ||
249 | * @brief Enabled events mask. | ||
250 | * @note This field is only valid while the thread is in the | ||
251 | * @p CH_STATE_WTOREVT or @p CH_STATE_WTANDEVT states. | ||
252 | */ | ||
253 | eventmask_t ewmask; | ||
254 | #endif | ||
255 | } u; | ||
256 | #if (CH_CFG_USE_WAITEXIT == TRUE) || defined(__DOXYGEN__) | ||
257 | /** | ||
258 | * @brief Termination waiting list. | ||
259 | */ | ||
260 | ch_list_t waiting; | ||
261 | #endif | ||
262 | #if (CH_CFG_USE_MESSAGES == TRUE) || defined(__DOXYGEN__) | ||
263 | /** | ||
264 | * @brief Messages queue. | ||
265 | */ | ||
266 | ch_queue_t msgqueue; | ||
267 | #endif | ||
268 | #if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__) | ||
269 | /** | ||
270 | * @brief Pending events mask. | ||
271 | */ | ||
272 | eventmask_t epending; | ||
273 | #endif | ||
274 | #if (CH_CFG_USE_MUTEXES == TRUE) || defined(__DOXYGEN__) | ||
275 | /** | ||
276 | * @brief List of the mutexes owned by this thread. | ||
277 | * @note The list is terminated by a @p NULL in this field. | ||
278 | */ | ||
279 | struct ch_mutex *mtxlist; | ||
280 | /** | ||
281 | * @brief Thread's own, non-inherited, priority. | ||
282 | */ | ||
283 | tprio_t realprio; | ||
284 | #endif | ||
285 | #if ((CH_CFG_USE_DYNAMIC == TRUE) && (CH_CFG_USE_MEMPOOLS == TRUE)) || \ | ||
286 | defined(__DOXYGEN__) | ||
287 | /** | ||
288 | * @brief Memory Pool where the thread workspace is returned. | ||
289 | */ | ||
290 | void *mpool; | ||
291 | #endif | ||
292 | #if (CH_DBG_STATISTICS == TRUE) || defined(__DOXYGEN__) | ||
293 | /** | ||
294 | * @brief Thread statistics. | ||
295 | */ | ||
296 | time_measurement_t stats; | ||
297 | #endif | ||
298 | #if defined(CH_CFG_THREAD_EXTRA_FIELDS) | ||
299 | /* Extra fields defined in chconf.h.*/ | ||
300 | CH_CFG_THREAD_EXTRA_FIELDS | ||
301 | #endif | ||
302 | }; | ||
303 | |||
304 | /** | ||
305 | * @brief Type of a Virtual Timer structure. | ||
306 | */ | ||
307 | typedef struct ch_delta_list delta_list_t; | ||
308 | |||
309 | /** | ||
310 | * @brief Virtual Timer delta list element and header structure. | ||
311 | */ | ||
312 | struct ch_delta_list { | ||
313 | delta_list_t *next; /**< @brief Next timer in the list. */ | ||
314 | delta_list_t *prev; /**< @brief Previous timer in the list. */ | ||
315 | sysinterval_t delta; /**< @brief Time delta before timeout. */ | ||
316 | }; | ||
317 | |||
318 | /** | ||
319 | * @brief Structure representing a Virtual Timer. | ||
320 | */ | ||
321 | struct ch_virtual_timer { | ||
322 | delta_list_t dlist; /**< @brief Delta list element. */ | ||
323 | vtfunc_t func; /**< @brief Timer callback function | ||
324 | pointer. */ | ||
325 | void *par; /**< @brief Timer callback function | ||
326 | parameter. */ | ||
327 | }; | ||
328 | |||
329 | /** | ||
330 | * @brief Structure representing a virtual timers list header. | ||
331 | * @note The timers list is implemented as a double link bidirectional list | ||
332 | * in order to make the unlink time constant, the reset of a virtual | ||
333 | * timer is often used in the code. | ||
334 | */ | ||
335 | struct ch_virtual_timers_list { | ||
336 | delta_list_t dlist; /**< @brief Delta list header. */ | ||
337 | #if (CH_CFG_ST_TIMEDELTA == 0) || defined(__DOXYGEN__) | ||
338 | volatile systime_t systime; /**< @brief System Time counter. */ | ||
339 | #endif | ||
340 | #if (CH_CFG_ST_TIMEDELTA > 0) || defined(__DOXYGEN__) | ||
341 | /** | ||
342 | * @brief System time of the last tick event. | ||
343 | */ | ||
344 | systime_t lasttime; /**< @brief System time of the last | ||
345 | tick event. */ | ||
346 | #endif | ||
347 | }; | ||
348 | |||
349 | /** | ||
350 | * @extends threads_queue_t | ||
351 | */ | ||
352 | struct ch_ready_list { | ||
353 | /** | ||
354 | * @brief Threads ordered queues header. | ||
355 | * @note The priority field must be initialized to zero. | ||
356 | */ | ||
357 | ch_priority_queue_t pqueue; | ||
358 | /** | ||
359 | * @brief Not used, present because offsets. | ||
360 | */ | ||
361 | struct port_context ctx; | ||
362 | #if (CH_CFG_USE_REGISTRY == TRUE) || defined(__DOXYGEN__) | ||
363 | /** | ||
364 | * @brief Newer registry element. | ||
365 | */ | ||
366 | thread_t *newer; | ||
367 | /** | ||
368 | * @brief Older registry element. | ||
369 | */ | ||
370 | thread_t *older; | ||
371 | #endif | ||
372 | /* End of the fields shared with the thread_t structure.*/ | ||
373 | /** | ||
374 | * @brief The currently running thread. | ||
375 | */ | ||
376 | thread_t *current; | ||
377 | }; | ||
378 | |||
379 | /** | ||
380 | * @brief System debug data structure. | ||
381 | */ | ||
382 | struct ch_system_debug { | ||
383 | /** | ||
384 | * @brief Pointer to the panic message. | ||
385 | * @details This pointer is meant to be accessed through the debugger, it is | ||
386 | * written once and then the system is halted. | ||
387 | * @note Accesses to this pointer must never be optimized out so the | ||
388 | * field itself is declared volatile. | ||
389 | */ | ||
390 | const char * volatile panic_msg; | ||
391 | #if (CH_DBG_SYSTEM_STATE_CHECK == TRUE) || defined(__DOXYGEN__) | ||
392 | /** | ||
393 | * @brief ISR nesting level. | ||
394 | */ | ||
395 | cnt_t isr_cnt; | ||
396 | /** | ||
397 | * @brief Lock nesting level. | ||
398 | */ | ||
399 | cnt_t lock_cnt; | ||
400 | #endif | ||
401 | #if (CH_DBG_TRACE_MASK != CH_DBG_TRACE_MASK_DISABLED) || defined(__DOXYGEN__) | ||
402 | /** | ||
403 | * @brief Public trace buffer. | ||
404 | */ | ||
405 | ch_trace_buffer_t trace_buffer; | ||
406 | #endif | ||
407 | }; | ||
408 | |||
409 | /** | ||
410 | * @brief System data structure. | ||
411 | * @note This structure contain all the data areas used by the OS except | ||
412 | * stacks. | ||
413 | */ | ||
414 | struct ch_system { | ||
415 | /** | ||
416 | * @brief Ready list header. | ||
417 | */ | ||
418 | ready_list_t rlist; | ||
419 | /** | ||
420 | * @brief Virtual timers delta list header. | ||
421 | */ | ||
422 | virtual_timers_list_t vtlist; | ||
423 | /** | ||
424 | * @brief System debug. | ||
425 | */ | ||
426 | system_debug_t dbg; | ||
427 | /** | ||
428 | * @brief Main thread descriptor. | ||
429 | */ | ||
430 | thread_t mainthread; | ||
431 | #if (CH_CFG_USE_TM == TRUE) || defined(__DOXYGEN__) | ||
432 | /** | ||
433 | * @brief Time measurement calibration data. | ||
434 | */ | ||
435 | tm_calibration_t tm; | ||
436 | #endif | ||
437 | #if (CH_DBG_STATISTICS == TRUE) || defined(__DOXYGEN__) | ||
438 | /** | ||
439 | * @brief Global kernel statistics. | ||
440 | */ | ||
441 | kernel_stats_t kernel_stats; | ||
442 | #endif | ||
443 | CH_CFG_SYSTEM_EXTRA_FIELDS | ||
444 | }; | ||
445 | |||
446 | /*===========================================================================*/ | ||
447 | /* Module macros. */ | ||
448 | /*===========================================================================*/ | ||
449 | |||
450 | /** | ||
451 | * @brief Returns the priority of the first thread on the given ready list. | ||
452 | * | ||
453 | * @notapi | ||
454 | */ | ||
455 | #define firstprio(rlp) ((rlp)->next->prio) | ||
456 | |||
457 | /** | ||
458 | * @brief Current thread pointer access macro. | ||
459 | * @note This macro is not meant to be used in the application code but | ||
460 | * only from within the kernel, use @p chThdGetSelfX() instead. | ||
461 | */ | ||
462 | #define currp ch.rlist.current | ||
463 | |||
464 | /*===========================================================================*/ | ||
465 | /* External declarations. */ | ||
466 | /*===========================================================================*/ | ||
467 | |||
468 | #if !defined(__DOXYGEN__) | ||
469 | extern ch_system_t ch; | ||
470 | #endif | ||
471 | |||
472 | /* | ||
473 | * Scheduler APIs. | ||
474 | */ | ||
475 | #ifdef __cplusplus | ||
476 | extern "C" { | ||
477 | #endif | ||
478 | void _scheduler_init(void); | ||
479 | thread_t *chSchReadyI(thread_t *tp); | ||
480 | thread_t *chSchReadyAheadI(thread_t *tp); | ||
481 | void chSchGoSleepS(tstate_t newstate); | ||
482 | msg_t chSchGoSleepTimeoutS(tstate_t newstate, sysinterval_t timeout); | ||
483 | void chSchWakeupS(thread_t *ntp, msg_t msg); | ||
484 | void chSchRescheduleS(void); | ||
485 | bool chSchIsPreemptionRequired(void); | ||
486 | void chSchDoRescheduleBehind(void); | ||
487 | void chSchDoRescheduleAhead(void); | ||
488 | void chSchDoReschedule(void); | ||
489 | #if CH_CFG_OPTIMIZE_SPEED == FALSE | ||
490 | void ch_sch_prio_insert(ch_queue_t *tp, ch_queue_t *qp); | ||
491 | #endif /* CH_CFG_OPTIMIZE_SPEED == FALSE */ | ||
492 | #ifdef __cplusplus | ||
493 | } | ||
494 | #endif | ||
495 | |||
496 | /*===========================================================================*/ | ||
497 | /* Module inline functions. */ | ||
498 | /*===========================================================================*/ | ||
499 | |||
500 | /* If the performance code path has been chosen then all the following | ||
501 | functions are inlined into the various kernel modules.*/ | ||
502 | #if CH_CFG_OPTIMIZE_SPEED == TRUE | ||
503 | static inline void ch_sch_prio_insert(ch_queue_t *tp, ch_queue_t *qp) { | ||
504 | |||
505 | ch_queue_t *cp = qp; | ||
506 | do { | ||
507 | cp = cp->next; | ||
508 | } while ((cp != qp) && | ||
509 | (((thread_t *)cp)->hdr.pqueue.prio >= ((thread_t *)tp)->hdr.pqueue.prio)); | ||
510 | tp->next = cp; | ||
511 | tp->prev = cp->prev; | ||
512 | tp->prev->next = tp; | ||
513 | cp->prev = tp; | ||
514 | } | ||
515 | #endif /* CH_CFG_OPTIMIZE_SPEED == TRUE */ | ||
516 | |||
517 | /** | ||
518 | * @brief Determines if the current thread must reschedule. | ||
519 | * @details This function returns @p true if there is a ready thread with | ||
520 | * higher priority. | ||
521 | * | ||
522 | * @return The priorities situation. | ||
523 | * @retval false if rescheduling is not necessary. | ||
524 | * @retval true if there is a ready thread at higher priority. | ||
525 | * | ||
526 | * @iclass | ||
527 | */ | ||
528 | static inline bool chSchIsRescRequiredI(void) { | ||
529 | |||
530 | chDbgCheckClassI(); | ||
531 | |||
532 | return firstprio(&ch.rlist.pqueue) > currp->hdr.pqueue.prio; | ||
533 | } | ||
534 | |||
535 | /** | ||
536 | * @brief Determines if yielding is possible. | ||
537 | * @details This function returns @p true if there is a ready thread with | ||
538 | * equal or higher priority. | ||
539 | * | ||
540 | * @return The priorities situation. | ||
541 | * @retval false if yielding is not possible. | ||
542 | * @retval true if there is a ready thread at equal or higher priority. | ||
543 | * | ||
544 | * @sclass | ||
545 | */ | ||
546 | static inline bool chSchCanYieldS(void) { | ||
547 | |||
548 | chDbgCheckClassS(); | ||
549 | |||
550 | return firstprio(&ch.rlist.pqueue) >= currp->hdr.pqueue.prio; | ||
551 | } | ||
552 | |||
553 | /** | ||
554 | * @brief Yields the time slot. | ||
555 | * @details Yields the CPU control to the next thread in the ready list with | ||
556 | * equal or higher priority, if any. | ||
557 | * | ||
558 | * @sclass | ||
559 | */ | ||
560 | static inline void chSchDoYieldS(void) { | ||
561 | |||
562 | chDbgCheckClassS(); | ||
563 | |||
564 | if (chSchCanYieldS()) { | ||
565 | chSchDoRescheduleBehind(); | ||
566 | } | ||
567 | } | ||
568 | |||
569 | /** | ||
570 | * @brief Inline-able preemption code. | ||
571 | * @details This is the common preemption code, this function must be invoked | ||
572 | * exclusively from the port layer. | ||
573 | * | ||
574 | * @special | ||
575 | */ | ||
576 | static inline void chSchPreemption(void) { | ||
577 | tprio_t p1 = firstprio(&ch.rlist.pqueue); | ||
578 | tprio_t p2 = currp->hdr.pqueue.prio; | ||
579 | |||
580 | #if CH_CFG_TIME_QUANTUM > 0 | ||
581 | if (currp->ticks > (tslices_t)0) { | ||
582 | if (p1 > p2) { | ||
583 | chSchDoRescheduleAhead(); | ||
584 | } | ||
585 | } | ||
586 | else { | ||
587 | if (p1 >= p2) { | ||
588 | chSchDoRescheduleBehind(); | ||
589 | } | ||
590 | } | ||
591 | #else /* CH_CFG_TIME_QUANTUM == 0 */ | ||
592 | if (p1 > p2) { | ||
593 | chSchDoRescheduleAhead(); | ||
594 | } | ||
595 | #endif /* CH_CFG_TIME_QUANTUM == 0 */ | ||
596 | } | ||
597 | |||
598 | #endif /* CHSCHD_H */ | ||
599 | |||
600 | /** @} */ | ||