ChibiOS/RT  5.1.0
chschd.h
Go to the documentation of this file.
1 /*
2  ChibiOS - Copyright (C) 2006..2018 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; either version 3 of the License, or
9  (at your option) any later version.
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 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 /** @} */
109 /*===========================================================================*/
110 /* Module pre-compile time settings. */
111 /*===========================================================================*/
113 /*===========================================================================*/
114 /* Derived constants and error checks. */
115 /*===========================================================================*/
116 
117 /*===========================================================================*/
118 /* Module data structures and types. */
119 /*===========================================================================*/
120 
121 /**
122  * @brief Generic threads single link list, it works like a stack.
123  */
124 struct ch_threads_list {
125  thread_t *next; /**< @brief Next in the list/queue. */
126 };
127 
128 /**
129  * @brief Generic threads bidirectional linked list header and element.
130  */
131 struct ch_threads_queue {
132  thread_t *next; /**< @brief Next in the list/queue. */
133  thread_t *prev; /**< @brief Previous in the queue. */
134 };
136 /**
137  * @brief Structure representing a thread.
138  * @note Not all the listed fields are always needed, by switching off some
139  * not needed ChibiOS/RT subsystems it is possible to save RAM space
140  * by shrinking this structure.
141  */
142 struct ch_thread {
143  threads_queue_t queue; /**< @brief Threads queue header. */
144  tprio_t prio; /**< @brief Thread priority. */
145  struct port_context ctx; /**< @brief Processor context. */
146 #if (CH_CFG_USE_REGISTRY == TRUE) || defined(__DOXYGEN__)
147  thread_t *newer; /**< @brief Newer registry element. */
148  thread_t *older; /**< @brief Older registry element. */
149 #endif
150  /* End of the fields shared with the ReadyList structure. */
151 #if (CH_CFG_USE_REGISTRY == TRUE) || defined(__DOXYGEN__)
152  /**
153  * @brief Thread name or @p NULL.
154  */
155  const char *name;
156 #endif
157 #if (CH_DBG_ENABLE_STACK_CHECK == TRUE) || (CH_CFG_USE_DYNAMIC == TRUE) || \
158  defined(__DOXYGEN__)
159  /**
160  * @brief Working area base address.
161  * @note This pointer is used for stack overflow checks and for
162  * dynamic threading.
163  */
164  stkalign_t *wabase;
165 #endif
166  /**
167  * @brief Current thread state.
168  */
169  tstate_t state;
170  /**
171  * @brief Various thread flags.
172  */
173  tmode_t flags;
174 #if (CH_CFG_USE_REGISTRY == TRUE) || defined(__DOXYGEN__)
175  /**
176  * @brief References to this thread.
177  */
178  trefs_t refs;
179 #endif
180  /**
181  * @brief Number of ticks remaining to this thread.
182  */
183 #if (CH_CFG_TIME_QUANTUM > 0) || defined(__DOXYGEN__)
184  tslices_t ticks;
185 #endif
186 #if (CH_DBG_THREADS_PROFILING == TRUE) || defined(__DOXYGEN__)
187  /**
188  * @brief Thread consumed time in ticks.
189  * @note This field can overflow.
190  */
191  volatile systime_t time;
192 #endif
193  /**
194  * @brief State-specific fields.
195  * @note All the fields declared in this union are only valid in the
196  * specified state or condition and are thus volatile.
197  */
198  union {
199  /**
200  * @brief Thread wakeup code.
201  * @note This field contains the low level message sent to the thread
202  * by the waking thread or interrupt handler. The value is valid
203  * after exiting the @p chSchWakeupS() function.
204  */
205  msg_t rdymsg;
206  /**
207  * @brief Thread exit code.
208  * @note The thread termination code is stored in this field in order
209  * to be retrieved by the thread performing a @p chThdWait() on
210  * this thread.
211  */
212  msg_t exitcode;
213  /**
214  * @brief Pointer to a generic "wait" object.
215  * @note This field is used to get a generic pointer to a synchronization
216  * object and is valid when the thread is in one of the wait
217  * states.
218  */
219  void *wtobjp;
220  /**
221  * @brief Pointer to a generic thread reference object.
222  * @note This field is used to get a pointer to a synchronization
223  * object and is valid when the thread is in @p CH_STATE_SUSPENDED
224  * state.
225  */
226  thread_reference_t *wttrp;
227 #if (CH_CFG_USE_MESSAGES == TRUE) || defined(__DOXYGEN__)
228  /**
229  * @brief Thread sent message.
230  */
231  msg_t sentmsg;
232 #endif
233 #if (CH_CFG_USE_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
234  /**
235  * @brief Pointer to a generic semaphore object.
236  * @note This field is used to get a pointer to a synchronization
237  * object and is valid when the thread is in @p CH_STATE_WTSEM
238  * state.
239  */
240  struct ch_semaphore *wtsemp;
241 #endif
242 #if (CH_CFG_USE_MUTEXES == TRUE) || defined(__DOXYGEN__)
243  /**
244  * @brief Pointer to a generic mutex object.
245  * @note This field is used to get a pointer to a synchronization
246  * object and is valid when the thread is in @p CH_STATE_WTMTX
247  * state.
248  */
249  struct ch_mutex *wtmtxp;
250 #endif
251 #if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__)
252  /**
253  * @brief Enabled events mask.
254  * @note This field is only valid while the thread is in the
255  * @p CH_STATE_WTOREVT or @p CH_STATE_WTANDEVT states.
256  */
257  eventmask_t ewmask;
258 #endif
259  } u;
260 #if (CH_CFG_USE_WAITEXIT == TRUE) || defined(__DOXYGEN__)
261  /**
262  * @brief Termination waiting list.
263  */
264  threads_list_t waiting;
265 #endif
266 #if (CH_CFG_USE_MESSAGES == TRUE) || defined(__DOXYGEN__)
267  /**
268  * @brief Messages queue.
269  */
270  threads_queue_t msgqueue;
271 #endif
272 #if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__)
273  /**
274  * @brief Pending events mask.
275  */
276  eventmask_t epending;
277 #endif
278 #if (CH_CFG_USE_MUTEXES == TRUE) || defined(__DOXYGEN__)
279  /**
280  * @brief List of the mutexes owned by this thread.
281  * @note The list is terminated by a @p NULL in this field.
282  */
283  struct ch_mutex *mtxlist;
284  /**
285  * @brief Thread's own, non-inherited, priority.
286  */
287  tprio_t realprio;
288 #endif
289 #if ((CH_CFG_USE_DYNAMIC == TRUE) && (CH_CFG_USE_MEMPOOLS == TRUE)) || \
290  defined(__DOXYGEN__)
291  /**
292  * @brief Memory Pool where the thread workspace is returned.
293  */
294  void *mpool;
295 #endif
296 #if (CH_DBG_STATISTICS == TRUE) || defined(__DOXYGEN__)
297  /**
298  * @brief Thread statistics.
299  */
300  time_measurement_t stats;
301 #endif
302 #if defined(CH_CFG_THREAD_EXTRA_FIELDS)
303  /* Extra fields defined in chconf.h.*/
305 #endif
306 };
307 
308 /**
309  * @extends virtual_timers_list_t
310  *
311  * @brief Virtual Timer descriptor structure.
312  */
313 struct ch_virtual_timer {
314  virtual_timer_t *next; /**< @brief Next timer in the list. */
315  virtual_timer_t *prev; /**< @brief Previous timer in the list. */
316  sysinterval_t delta; /**< @brief Time delta before timeout. */
317  vtfunc_t func; /**< @brief Timer callback function
318  pointer. */
319  void *par; /**< @brief Timer callback function
320  parameter. */
321 };
322 
323 /**
324  * @brief Virtual timers list header.
325  * @note The timers list is implemented as a double link bidirectional list
326  * in order to make the unlink time constant, the reset of a virtual
327  * timer is often used in the code.
328  */
329 struct ch_virtual_timers_list {
330  virtual_timer_t *next; /**< @brief Next timer in the delta
331  list. */
332  virtual_timer_t *prev; /**< @brief Last timer in the delta
333  list. */
334  sysinterval_t delta; /**< @brief Must be initialized to -1. */
335 #if (CH_CFG_ST_TIMEDELTA == 0) || defined(__DOXYGEN__)
336  volatile systime_t systime; /**< @brief System Time counter. */
337 #endif
338 #if (CH_CFG_ST_TIMEDELTA > 0) || defined(__DOXYGEN__)
339  /**
340  * @brief System time of the last tick event.
341  */
342  systime_t lasttime; /**< @brief System time of the last
343  tick event. */
344 #endif
345 };
346 
347 /**
348  * @extends threads_queue_t
349  */
350 struct ch_ready_list {
351  threads_queue_t queue; /**< @brief Threads queue. */
352  tprio_t prio; /**< @brief This field must be
353  initialized to zero. */
354  struct port_context ctx; /**< @brief Not used, present because
355  offsets. */
356 #if (CH_CFG_USE_REGISTRY == TRUE) || defined(__DOXYGEN__)
357  thread_t *newer; /**< @brief Newer registry element. */
358  thread_t *older; /**< @brief Older registry element. */
359 #endif
360  /* End of the fields shared with the thread_t structure.*/
361  thread_t *current; /**< @brief The currently running
362  thread. */
363 };
364 
365 /**
366  * @brief System debug data structure.
367  */
368 struct ch_system_debug {
369  /**
370  * @brief Pointer to the panic message.
371  * @details This pointer is meant to be accessed through the debugger, it is
372  * written once and then the system is halted.
373  * @note Accesses to this pointer must never be optimized out so the
374  * field itself is declared volatile.
375  */
376  const char * volatile panic_msg;
377 #if (CH_DBG_SYSTEM_STATE_CHECK == TRUE) || defined(__DOXYGEN__)
378  /**
379  * @brief ISR nesting level.
380  */
381  cnt_t isr_cnt;
382  /**
383  * @brief Lock nesting level.
384  */
385  cnt_t lock_cnt;
386 #endif
387 #if (CH_DBG_TRACE_MASK != CH_DBG_TRACE_MASK_DISABLED) || defined(__DOXYGEN__)
388  /**
389  * @brief Public trace buffer.
390  */
391  ch_trace_buffer_t trace_buffer;
392 #endif
393 };
394 
395 /**
396  * @brief System data structure.
397  * @note This structure contain all the data areas used by the OS except
398  * stacks.
399  */
400 struct ch_system {
401  /**
402  * @brief Ready list header.
403  */
404  ready_list_t rlist;
405  /**
406  * @brief Virtual timers delta list header.
407  */
408  virtual_timers_list_t vtlist;
409  /**
410  * @brief System debug.
411  */
412  system_debug_t dbg;
413  /**
414  * @brief Main thread descriptor.
415  */
416  thread_t mainthread;
417 #if (CH_CFG_USE_TM == TRUE) || defined(__DOXYGEN__)
418  /**
419  * @brief Time measurement calibration data.
420  */
421  tm_calibration_t tm;
422 #endif
423 #if (CH_DBG_STATISTICS == TRUE) || defined(__DOXYGEN__)
424  /**
425  * @brief Global kernel statistics.
426  */
427  kernel_stats_t kernel_stats;
428 #endif
430 };
431 
432 /*===========================================================================*/
433 /* Module macros. */
434 /*===========================================================================*/
435 
436 /**
437  * @brief Returns the priority of the first thread on the given ready list.
438  *
439  * @notapi
440  */
441 #define firstprio(rlp) ((rlp)->next->prio)
442 
443 /**
444  * @brief Current thread pointer access macro.
445  * @note This macro is not meant to be used in the application code but
446  * only from within the kernel, use @p chThdGetSelfX() instead.
447  */
448 #define currp ch.rlist.current
449 
450 /*===========================================================================*/
451 /* External declarations. */
452 /*===========================================================================*/
453 
454 #if !defined(__DOXYGEN__)
455 extern ch_system_t ch;
456 #endif
457 
458 /*
459  * Scheduler APIs.
460  */
461 #ifdef __cplusplus
462 extern "C" {
463 #endif
464  void _scheduler_init(void);
467  void chSchGoSleepS(tstate_t newstate);
468  msg_t chSchGoSleepTimeoutS(tstate_t newstate, sysinterval_t timeout);
469  void chSchWakeupS(thread_t *ntp, msg_t msg);
470  void chSchRescheduleS(void);
471  bool chSchIsPreemptionRequired(void);
472  void chSchDoRescheduleBehind(void);
473  void chSchDoRescheduleAhead(void);
474  void chSchDoReschedule(void);
475 #if CH_CFG_OPTIMIZE_SPEED == FALSE
477  void queue_insert(thread_t *tp, threads_queue_t *tqp);
481  void list_insert(thread_t *tp, threads_list_t *tlp);
483 #endif /* CH_CFG_OPTIMIZE_SPEED == FALSE */
484 #ifdef __cplusplus
485 }
486 #endif
487 
488 /*===========================================================================*/
489 /* Module inline functions. */
490 /*===========================================================================*/
491 
492 /**
493  * @brief Threads list initialization.
494  *
495  * @param[in] tlp pointer to the threads list object
496  *
497  * @notapi
498  */
499 static inline void list_init(threads_list_t *tlp) {
500 
501  tlp->next = (thread_t *)tlp;
502 }
503 
504 /**
505  * @brief Evaluates to @p true if the specified threads list is empty.
506  *
507  * @param[in] tlp pointer to the threads list object
508  * @return The status of the list.
509  *
510  * @notapi
511  */
512 static inline bool list_isempty(threads_list_t *tlp) {
513 
514  return (bool)(tlp->next == (thread_t *)tlp);
515 }
516 
517 /**
518  * @brief Evaluates to @p true if the specified threads list is not empty.
519  *
520  * @param[in] tlp pointer to the threads list object
521  * @return The status of the list.
522  *
523  * @notapi
524  */
525 static inline bool list_notempty(threads_list_t *tlp) {
526 
527  return (bool)(tlp->next != (thread_t *)tlp);
528 }
529 
530 /**
531  * @brief Threads queue initialization.
532  *
533  * @param[in] tqp pointer to the threads queue object
534  *
535  * @notapi
536  */
537 static inline void queue_init(threads_queue_t *tqp) {
538 
539  tqp->next = (thread_t *)tqp;
540  tqp->prev = (thread_t *)tqp;
541 }
542 
543 /**
544  * @brief Evaluates to @p true if the specified threads queue is empty.
545  *
546  * @param[in] tqp pointer to the threads queue object
547  * @return The status of the queue.
548  *
549  * @notapi
550  */
551 static inline bool queue_isempty(const threads_queue_t *tqp) {
552 
553  return (bool)(tqp->next == (const thread_t *)tqp);
554 }
555 
556 /**
557  * @brief Evaluates to @p true if the specified threads queue is not empty.
558  *
559  * @param[in] tqp pointer to the threads queue object
560  * @return The status of the queue.
561  *
562  * @notapi
563  */
564 static inline bool queue_notempty(const threads_queue_t *tqp) {
565 
566  return (bool)(tqp->next != (const thread_t *)tqp);
567 }
568 
569 /* If the performance code path has been chosen then all the following
570  functions are inlined into the various kernel modules.*/
571 #if CH_CFG_OPTIMIZE_SPEED == TRUE
572 static inline void list_insert(thread_t *tp, threads_list_t *tlp) {
573 
574  tp->queue.next = tlp->next;
575  tlp->next = tp;
576 }
577 
578 static inline thread_t *list_remove(threads_list_t *tlp) {
579 
580  thread_t *tp = tlp->next;
581  tlp->next = tp->queue.next;
582 
583  return tp;
584 }
585 
586 static inline void queue_prio_insert(thread_t *tp, threads_queue_t *tqp) {
587 
588  thread_t *cp = (thread_t *)tqp;
589  do {
590  cp = cp->queue.next;
591  } while ((cp != (thread_t *)tqp) && (cp->prio >= tp->prio));
592  tp->queue.next = cp;
593  tp->queue.prev = cp->queue.prev;
594  tp->queue.prev->queue.next = tp;
595  cp->queue.prev = tp;
596 }
597 
598 static inline void queue_insert(thread_t *tp, threads_queue_t *tqp) {
599 
600  tp->queue.next = (thread_t *)tqp;
601  tp->queue.prev = tqp->prev;
602  tp->queue.prev->queue.next = tp;
603  tqp->prev = tp;
604 }
605 
606 static inline thread_t *queue_fifo_remove(threads_queue_t *tqp) {
607  thread_t *tp = tqp->next;
608 
609  tqp->next = tp->queue.next;
610  tqp->next->queue.prev = (thread_t *)tqp;
611 
612  return tp;
613 }
614 
615 static inline thread_t *queue_lifo_remove(threads_queue_t *tqp) {
616  thread_t *tp = tqp->prev;
617 
618  tqp->prev = tp->queue.prev;
619  tqp->prev->queue.next = (thread_t *)tqp;
620 
621  return tp;
622 }
623 
624 static inline thread_t *queue_dequeue(thread_t *tp) {
625 
626  tp->queue.prev->queue.next = tp->queue.next;
627  tp->queue.next->queue.prev = tp->queue.prev;
628 
629  return tp;
630 }
631 #endif /* CH_CFG_OPTIMIZE_SPEED == TRUE */
632 
633 /**
634  * @brief Determines if the current thread must reschedule.
635  * @details This function returns @p true if there is a ready thread with
636  * higher priority.
637  *
638  * @return The priorities situation.
639  * @retval false if rescheduling is not necessary.
640  * @retval true if there is a ready thread at higher priority.
641  *
642  * @iclass
643  */
644 static inline bool chSchIsRescRequiredI(void) {
645 
647 
648  return firstprio(&ch.rlist.queue) > currp->prio;
649 }
650 
651 /**
652  * @brief Determines if yielding is possible.
653  * @details This function returns @p true if there is a ready thread with
654  * equal or higher priority.
655  *
656  * @return The priorities situation.
657  * @retval false if yielding is not possible.
658  * @retval true if there is a ready thread at equal or higher priority.
659  *
660  * @sclass
661  */
662 static inline bool chSchCanYieldS(void) {
663 
665 
666  return firstprio(&ch.rlist.queue) >= currp->prio;
667 }
668 
669 /**
670  * @brief Yields the time slot.
671  * @details Yields the CPU control to the next thread in the ready list with
672  * equal or higher priority, if any.
673  *
674  * @sclass
675  */
676 static inline void chSchDoYieldS(void) {
677 
679 
680  if (chSchCanYieldS()) {
682  }
683 }
684 
685 /**
686  * @brief Inline-able preemption code.
687  * @details This is the common preemption code, this function must be invoked
688  * exclusively from the port layer.
689  *
690  * @special
691  */
692 static inline void chSchPreemption(void) {
693  tprio_t p1 = firstprio(&ch.rlist.queue);
694  tprio_t p2 = currp->prio;
695 
696 #if CH_CFG_TIME_QUANTUM > 0
697  if (currp->ticks > (tslices_t)0) {
698  if (p1 > p2) {
700  }
701  }
702  else {
703  if (p1 >= p2) {
705  }
706  }
707 #else /* CH_CFG_TIME_QUANTUM == 0 */
708  if (p1 > p2) {
710  }
711 #endif /* CH_CFG_TIME_QUANTUM == 0 */
712 }
713 
714 #endif /* CHSCHD_H */
715 
716 /** @} */
void _scheduler_init(void)
Scheduler initialization.
Definition: chschd.c:65
Trace buffer header.
Definition: chtrace.h:175
void chDbgCheckClassS(void)
S-class functions context check.
Definition: chdebug.c:250
System debug data structure.
Definition: chschd.h:379
static void chSchPreemption(void)
Inline-able preemption code.
Definition: chschd.h:703
uint64_t systime_t
Type of system time.
Definition: chtime.h:138
uint64_t sysinterval_t
Type of time interval.
Definition: chtime.h:150
tprio_t prio
Thread priority.
Definition: chschd.h:155
void chSchDoRescheduleBehind(void)
Switches to the first thread on the runnable queue.
Definition: chschd.c:507
thread_t * chSchReadyI(thread_t *tp)
Inserts a thread in the Ready List placing it behind its peers.
Definition: chschd.c:218
void queue_prio_insert(thread_t *tp, threads_queue_t *tqp)
Inserts a thread into a priority ordered queue.
Definition: chschd.c:86
Type of a time measurement calibration data.
Definition: chtm.h:56
#define firstprio(rlp)
Returns the priority of the first thread on the given ready list.
Definition: chschd.h:452
Generic threads bidirectional linked list header and element.
Definition: chschd.h:142
#define currp
Current thread pointer access macro.
Definition: chschd.h:459
#define CH_CFG_SYSTEM_EXTRA_FIELDS
System structure extension.
Definition: chconf.h:573
Type of a Time Measurement object.
Definition: chtm.h:72
static void list_init(threads_list_t *tlp)
Threads list initialization.
Definition: chschd.h:510
static void chSchDoYieldS(void)
Yields the time slot.
Definition: chschd.h:687
Mutex structure.
Definition: chmtx.h:57
void chDbgCheckClassI(void)
I-class functions context check.
Definition: chdebug.c:235
struct ch_ready_list ready_list_t
Type of a ready list header.
Definition: chsystypes.h:76
thread_t * next
Next in the list/queue.
Definition: chschd.h:136
void chSchRescheduleS(void)
Performs a reschedule if a higher priority thread is runnable.
Definition: chschd.c:456
static bool list_notempty(threads_list_t *tlp)
Evaluates to true if the specified threads list is not empty.
Definition: chschd.h:536
thread_t * next
Next in the list/queue.
Definition: chschd.h:143
void(* vtfunc_t)(void *p)
Type of a Virtual Timer callback function.
Definition: chsystypes.h:81
Virtual timers list header.
Definition: chschd.h:340
bool chSchIsPreemptionRequired(void)
Evaluates if preemption is required.
Definition: chschd.c:479
void chSchGoSleepS(tstate_t newstate)
Puts the current thread to sleep into the specified state.
Definition: chschd.c:289
static void queue_init(threads_queue_t *tqp)
Threads queue initialization.
Definition: chschd.h:548
msg_t chSchGoSleepTimeoutS(tstate_t newstate, sysinterval_t timeout)
Puts the current thread to sleep into the specified state with timeout specification.
Definition: chschd.c:375
thread_t * list_remove(threads_list_t *tlp)
Pops a thread from the top of a stack list and returns it.
Definition: chschd.c:193
Semaphore structure.
Definition: chsem.h:52
static bool chSchIsRescRequiredI(void)
Determines if the current thread must reschedule.
Definition: chschd.h:655
ready_list_t rlist
Ready list header.
Definition: chschd.h:415
ch_system_t ch
System data structures.
Definition: chschd.c:42
static bool chSchCanYieldS(void)
Determines if yielding is possible.
Definition: chschd.h:673
Generic threads single link list, it works like a stack.
Definition: chschd.h:135
void queue_insert(thread_t *tp, threads_queue_t *tqp)
Inserts a thread into a queue.
Definition: chschd.c:106
thread_t * prev
Previous in the queue.
Definition: chschd.h:144
thread_t * queue_lifo_remove(threads_queue_t *tqp)
Removes the last-out thread from a queue and returns it.
Definition: chschd.c:143
static bool queue_isempty(const threads_queue_t *tqp)
Evaluates to true if the specified threads queue is empty.
Definition: chschd.h:562
void chSchDoRescheduleAhead(void)
Switches to the first thread on the runnable queue.
Definition: chschd.c:540
#define CH_CFG_THREAD_EXTRA_FIELDS
Threads descriptor structure extension.
Definition: chconf.h:589
Virtual Timer descriptor structure.
Definition: chschd.h:324
Type of a kernel statistics structure.
Definition: chstats.h:56
static bool list_isempty(threads_list_t *tlp)
Evaluates to true if the specified threads list is empty.
Definition: chschd.h:523
thread_t * queue_dequeue(thread_t *tp)
Removes a thread from a queue and returns it.
Definition: chschd.c:162
static bool queue_notempty(const threads_queue_t *tqp)
Evaluates to true if the specified threads queue is not empty.
Definition: chschd.h:575
void chSchWakeupS(thread_t *ntp, msg_t msg)
Wakes up a thread.
Definition: chschd.c:412
thread_t * chSchReadyAheadI(thread_t *tp)
Inserts a thread in the Ready List placing it ahead its peers.
Definition: chschd.c:257
void list_insert(thread_t *tp, threads_list_t *tlp)
Pushes a thread_t on top of a stack list.
Definition: chschd.c:178
thread_t * queue_fifo_remove(threads_queue_t *tqp)
Removes the first-out thread from a queue and returns it.
Definition: chschd.c:124
threads_queue_t queue
Threads queue header.
Definition: chschd.h:154
void chSchDoReschedule(void)
Switches to the first thread on the runnable queue.
Definition: chschd.c:570
System data structure.
Definition: chschd.h:411
Structure representing a thread.
Definition: chschd.h:153