ChibiOS/RT  6.0.3
chschd.c
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.c
22  * @brief Scheduler code.
23  *
24  * @addtogroup scheduler
25  * @details This module provides the default portable scheduler code.
26  * @{
27  */
28 
29 #include "ch.h"
30 
31 /*===========================================================================*/
32 /* Module local definitions. */
33 /*===========================================================================*/
34 
35 /*===========================================================================*/
36 /* Module exported variables. */
37 /*===========================================================================*/
38 
39 /**
40  * @brief System data structures.
41  */
43 
44 /*===========================================================================*/
45 /* Module local types. */
46 /*===========================================================================*/
47 
48 /*===========================================================================*/
49 /* Module local variables. */
50 /*===========================================================================*/
51 
52 /*===========================================================================*/
53 /* Module local functions. */
54 /*===========================================================================*/
55 
56 /*===========================================================================*/
57 /* Module exported functions. */
58 /*===========================================================================*/
59 
60 /**
61  * @brief Scheduler initialization.
62  *
63  * @notapi
64  */
65 void _scheduler_init(void) {
66 
67  queue_init(&ch.rlist.queue);
68  ch.rlist.prio = NOPRIO;
69 #if CH_CFG_USE_REGISTRY == TRUE
70  ch.rlist.newer = (thread_t *)&ch.rlist;
71  ch.rlist.older = (thread_t *)&ch.rlist;
72 #endif
73 }
74 
75 #if (CH_CFG_OPTIMIZE_SPEED == FALSE) || defined(__DOXYGEN__)
76 /**
77  * @brief Inserts a thread into a priority ordered queue.
78  * @note The insertion is done by scanning the list from the highest
79  * priority toward the lowest.
80  *
81  * @param[in] tp the pointer to the thread to be inserted in the list
82  * @param[in] tqp the pointer to the threads list header
83  *
84  * @notapi
85  */
87 
88  thread_t *cp = (thread_t *)tqp;
89  do {
90  cp = cp->queue.next;
91  } while ((cp != (thread_t *)tqp) && (cp->prio >= tp->prio));
92  tp->queue.next = cp;
93  tp->queue.prev = cp->queue.prev;
94  tp->queue.prev->queue.next = tp;
95  cp->queue.prev = tp;
96 }
97 
98 /**
99  * @brief Inserts a thread into a queue.
100  *
101  * @param[in] tp the pointer to the thread to be inserted in the list
102  * @param[in] tqp the pointer to the threads list header
103  *
104  * @notapi
105  */
107 
108  tp->queue.next = (thread_t *)tqp;
109  tp->queue.prev = tqp->prev;
110  tp->queue.prev->queue.next = tp;
111  tqp->prev = tp;
112 }
113 
114 /**
115  * @brief Removes the first-out thread from a queue and returns it.
116  * @note If the queue is priority ordered then this function returns the
117  * thread with the highest priority.
118  *
119  * @param[in] tqp the pointer to the threads list header
120  * @return The removed thread pointer.
121  *
122  * @notapi
123  */
125  thread_t *tp = tqp->next;
126 
127  tqp->next = tp->queue.next;
128  tqp->next->queue.prev = (thread_t *)tqp;
129 
130  return tp;
131 }
132 
133 /**
134  * @brief Removes the last-out thread from a queue and returns it.
135  * @note If the queue is priority ordered then this function returns the
136  * thread with the lowest priority.
137  *
138  * @param[in] tqp the pointer to the threads list header
139  * @return The removed thread pointer.
140  *
141  * @notapi
142  */
144  thread_t *tp = tqp->prev;
145 
146  tqp->prev = tp->queue.prev;
147  tqp->prev->queue.next = (thread_t *)tqp;
148 
149  return tp;
150 }
151 
152 /**
153  * @brief Removes a thread from a queue and returns it.
154  * @details The thread is removed from the queue regardless of its relative
155  * position and regardless the used insertion method.
156  *
157  * @param[in] tp the pointer to the thread to be removed from the queue
158  * @return The removed thread pointer.
159  *
160  * @notapi
161  */
163 
164  tp->queue.prev->queue.next = tp->queue.next;
165  tp->queue.next->queue.prev = tp->queue.prev;
166 
167  return tp;
168 }
169 
170 /**
171  * @brief Pushes a thread_t on top of a stack list.
172  *
173  * @param[in] tp the pointer to the thread to be inserted in the list
174  * @param[in] tlp the pointer to the threads list header
175  *
176  * @notapi
177  */
179 
180  tp->queue.next = tlp->next;
181  tlp->next = tp;
182 }
183 
184 /**
185  * @brief Pops a thread from the top of a stack list and returns it.
186  * @pre The list must be non-empty before calling this function.
187  *
188  * @param[in] tlp the pointer to the threads list header
189  * @return The removed thread pointer.
190  *
191  * @notapi
192  */
194 
195  thread_t *tp = tlp->next;
196  tlp->next = tp->queue.next;
197 
198  return tp;
199 }
200 #endif /* CH_CFG_OPTIMIZE_SPEED */
201 
202 /**
203  * @brief Inserts a thread in the Ready List placing it behind its peers.
204  * @details The thread is positioned behind all threads with higher or equal
205  * priority.
206  * @pre The thread must not be already inserted in any list through its
207  * @p next and @p prev or list corruption would occur.
208  * @post This function does not reschedule so a call to a rescheduling
209  * function must be performed before unlocking the kernel. Note that
210  * interrupt handlers always reschedule on exit so an explicit
211  * reschedule must not be performed in ISRs.
212  *
213  * @param[in] tp the thread to be made ready
214  * @return The thread pointer.
215  *
216  * @iclass
217  */
219  thread_t *cp;
220 
222  chDbgCheck(tp != NULL);
223  chDbgAssert((tp->state != CH_STATE_READY) &&
224  (tp->state != CH_STATE_FINAL),
225  "invalid state");
226 
227  tp->state = CH_STATE_READY;
228  cp = (thread_t *)&ch.rlist.queue;
229  do {
230  cp = cp->queue.next;
231  } while (cp->prio >= tp->prio);
232  /* Insertion on prev.*/
233  tp->queue.next = cp;
234  tp->queue.prev = cp->queue.prev;
235  tp->queue.prev->queue.next = tp;
236  cp->queue.prev = tp;
237 
238  return tp;
239 }
240 
241 /**
242  * @brief Inserts a thread in the Ready List placing it ahead its peers.
243  * @details The thread is positioned ahead all threads with higher or equal
244  * priority.
245  * @pre The thread must not be already inserted in any list through its
246  * @p next and @p prev or list corruption would occur.
247  * @post This function does not reschedule so a call to a rescheduling
248  * function must be performed before unlocking the kernel. Note that
249  * interrupt handlers always reschedule on exit so an explicit
250  * reschedule must not be performed in ISRs.
251  *
252  * @param[in] tp the thread to be made ready
253  * @return The thread pointer.
254  *
255  * @iclass
256  */
258  thread_t *cp;
259 
261  chDbgCheck(tp != NULL);
262  chDbgAssert((tp->state != CH_STATE_READY) &&
263  (tp->state != CH_STATE_FINAL),
264  "invalid state");
265 
266  tp->state = CH_STATE_READY;
267  cp = (thread_t *)&ch.rlist.queue;
268  do {
269  cp = cp->queue.next;
270  } while (cp->prio > tp->prio);
271  /* Insertion on prev.*/
272  tp->queue.next = cp;
273  tp->queue.prev = cp->queue.prev;
274  tp->queue.prev->queue.next = tp;
275  cp->queue.prev = tp;
276 
277  return tp;
278 }
279 
280 /**
281  * @brief Puts the current thread to sleep into the specified state.
282  * @details The thread goes into a sleeping state. The possible
283  * @ref thread_states are defined into @p threads.h.
284  *
285  * @param[in] newstate the new thread state
286  *
287  * @sclass
288  */
289 void chSchGoSleepS(tstate_t newstate) {
290  thread_t *otp = currp;
291 
293 
294  /* New state.*/
295  otp->state = newstate;
296 
297 #if CH_CFG_TIME_QUANTUM > 0
298  /* The thread is renouncing its remaining time slices so it will have a new
299  time quantum when it will wakeup.*/
300  otp->ticks = (tslices_t)CH_CFG_TIME_QUANTUM;
301 #endif
302 
303  /* Next thread in ready list becomes current.*/
304  currp = queue_fifo_remove(&ch.rlist.queue);
305  currp->state = CH_STATE_CURRENT;
306 
307  /* Handling idle-enter hook.*/
308  if (currp->prio == IDLEPRIO) {
310  }
311 
312  /* Swap operation as tail call.*/
313  chSysSwitch(currp, otp);
314 }
315 
316 /*
317  * Timeout wakeup callback.
318  */
319 static void wakeup(void *p) {
320  thread_t *tp = (thread_t *)p;
321 
323  switch (tp->state) {
324  case CH_STATE_READY:
325  /* Handling the special case where the thread has been made ready by
326  another thread with higher priority.*/
328  return;
329  case CH_STATE_SUSPENDED:
330  *tp->u.wttrp = NULL;
331  break;
332 #if CH_CFG_USE_SEMAPHORES == TRUE
333  case CH_STATE_WTSEM:
335 #endif
336  /* Falls through.*/
337  case CH_STATE_QUEUED:
338  /* Falls through.*/
339 #if (CH_CFG_USE_CONDVARS == TRUE) && (CH_CFG_USE_CONDVARS_TIMEOUT == TRUE)
340  case CH_STATE_WTCOND:
341 #endif
342  /* States requiring dequeuing.*/
343  (void) queue_dequeue(tp);
344  break;
345  default:
346  /* Any other state, nothing to do.*/
347  break;
348  }
349  tp->u.rdymsg = MSG_TIMEOUT;
350  (void) chSchReadyI(tp);
352 }
353 
354 /**
355  * @brief Puts the current thread to sleep into the specified state with
356  * timeout specification.
357  * @details The thread goes into a sleeping state, if it is not awakened
358  * explicitly within the specified timeout then it is forcibly
359  * awakened with a @p MSG_TIMEOUT low level message. The possible
360  * @ref thread_states are defined into @p threads.h.
361  *
362  * @param[in] newstate the new thread state
363  * @param[in] timeout the number of ticks before the operation timeouts, the
364  * special values are handled as follow:
365  * - @a TIME_INFINITE the thread enters an infinite sleep
366  * state, this is equivalent to invoking
367  * @p chSchGoSleepS() but, of course, less efficient.
368  * - @a TIME_IMMEDIATE this value is not allowed.
369  * .
370  * @return The wakeup message.
371  * @retval MSG_TIMEOUT if a timeout occurs.
372  *
373  * @sclass
374  */
375 msg_t chSchGoSleepTimeoutS(tstate_t newstate, sysinterval_t timeout) {
376 
378 
379  if (TIME_INFINITE != timeout) {
380  virtual_timer_t vt;
381 
382  chVTDoSetI(&vt, timeout, wakeup, currp);
383  chSchGoSleepS(newstate);
384  if (chVTIsArmedI(&vt)) {
385  chVTDoResetI(&vt);
386  }
387  }
388  else {
389  chSchGoSleepS(newstate);
390  }
391 
392  return currp->u.rdymsg;
393 }
394 
395 /**
396  * @brief Wakes up a thread.
397  * @details The thread is inserted into the ready list or immediately made
398  * running depending on its relative priority compared to the current
399  * thread.
400  * @pre The thread must not be already inserted in any list through its
401  * @p next and @p prev or list corruption would occur.
402  * @note It is equivalent to a @p chSchReadyI() followed by a
403  * @p chSchRescheduleS() but much more efficient.
404  * @note The function assumes that the current thread has the highest
405  * priority.
406  *
407  * @param[in] ntp the thread to be made ready
408  * @param[in] msg the wakeup message
409  *
410  * @sclass
411  */
412 void chSchWakeupS(thread_t *ntp, msg_t msg) {
413  thread_t *otp = currp;
414 
416 
417  chDbgAssert((ch.rlist.queue.next == (thread_t *)&ch.rlist.queue) ||
418  (ch.rlist.current->prio >= ch.rlist.queue.next->prio),
419  "priority order violation");
420 
421  /* Storing the message to be retrieved by the target thread when it will
422  restart execution.*/
423  ntp->u.rdymsg = msg;
424 
425  /* If the waken thread has a not-greater priority than the current
426  one then it is just inserted in the ready list else it made
427  running immediately and the invoking thread goes in the ready
428  list instead.*/
429  if (ntp->prio <= otp->prio) {
430  (void) chSchReadyI(ntp);
431  }
432  else {
433  otp = chSchReadyAheadI(otp);
434 
435  /* Handling idle-leave hook.*/
436  if (otp->prio == IDLEPRIO) {
438  }
439 
440  /* The extracted thread is marked as current.*/
441  currp = ntp;
442  ntp->state = CH_STATE_CURRENT;
443 
444  /* Swap operation as tail call.*/
445  chSysSwitch(ntp, otp);
446  }
447 }
448 
449 /**
450  * @brief Performs a reschedule if a higher priority thread is runnable.
451  * @details If a thread with a higher priority than the current thread is in
452  * the ready list then make the higher priority thread running.
453  *
454  * @sclass
455  */
456 void chSchRescheduleS(void) {
457 
459 
460  if (chSchIsRescRequiredI()) {
462  }
463 }
464 
465 #if !defined(CH_SCH_IS_PREEMPTION_REQUIRED_HOOKED)
466 /**
467  * @brief Evaluates if preemption is required.
468  * @details The decision is taken by comparing the relative priorities and
469  * depending on the state of the round robin timeout counter.
470  * @note Not a user function, it is meant to be invoked by the scheduler
471  * itself or from within the port layer.
472  *
473  * @retval true if there is a thread that must go in running state
474  * immediately.
475  * @retval false if preemption is not required.
476  *
477  * @special
478  */
480  tprio_t p1 = firstprio(&ch.rlist.queue);
481  tprio_t p2 = currp->prio;
482 
483 #if CH_CFG_TIME_QUANTUM > 0
484  /* If the running thread has not reached its time quantum, reschedule only
485  if the first thread on the ready queue has a higher priority.
486  Otherwise, if the running thread has used up its time quantum, reschedule
487  if the first thread on the ready queue has equal or higher priority.*/
488  return (currp->ticks > (tslices_t)0) ? (p1 > p2) : (p1 >= p2);
489 #else
490  /* If the round robin preemption feature is not enabled then performs a
491  simpler comparison.*/
492  return p1 > p2;
493 #endif
494 }
495 #endif /* !defined(CH_SCH_IS_PREEMPTION_REQUIRED_HOOKED) */
496 
497 /**
498  * @brief Switches to the first thread on the runnable queue.
499  * @details The current thread is positioned in the ready list behind all
500  * threads having the same priority. The thread regains its time
501  * quantum.
502  * @note Not a user function, it is meant to be invoked by the scheduler
503  * itself.
504  *
505  * @special
506  */
508  thread_t *otp = currp;
509 
510  /* Picks the first thread from the ready queue and makes it current.*/
511  currp = queue_fifo_remove(&ch.rlist.queue);
512  currp->state = CH_STATE_CURRENT;
513 
514  /* Handling idle-leave hook.*/
515  if (otp->prio == IDLEPRIO) {
517  }
518 
519 #if CH_CFG_TIME_QUANTUM > 0
520  /* It went behind peers so it gets a new time quantum.*/
521  otp->ticks = (tslices_t)CH_CFG_TIME_QUANTUM;
522 #endif
523 
524  /* Placing in ready list behind peers.*/
525  otp = chSchReadyI(otp);
526 
527  /* Swap operation as tail call.*/
528  chSysSwitch(currp, otp);
529 }
530 
531 /**
532  * @brief Switches to the first thread on the runnable queue.
533  * @details The current thread is positioned in the ready list ahead of all
534  * threads having the same priority.
535  * @note Not a user function, it is meant to be invoked by the scheduler
536  * itself.
537  *
538  * @special
539  */
541  thread_t *otp = currp;
542 
543  /* Picks the first thread from the ready queue and makes it current.*/
544  currp = queue_fifo_remove(&ch.rlist.queue);
545  currp->state = CH_STATE_CURRENT;
546 
547  /* Handling idle-leave hook.*/
548  if (otp->prio == IDLEPRIO) {
550  }
551 
552  /* Placing in ready list ahead of peers.*/
553  otp = chSchReadyAheadI(otp);
554 
555  /* Swap operation as tail call.*/
556  chSysSwitch(currp, otp);
557 }
558 
559 #if !defined(CH_SCH_DO_RESCHEDULE_HOOKED)
560 /**
561  * @brief Switches to the first thread on the runnable queue.
562  * @details The current thread is positioned in the ready list behind or
563  * ahead of all threads having the same priority depending on
564  * if it used its whole time slice.
565  * @note Not a user function, it is meant to be invoked by the scheduler
566  * itself or from within the port layer.
567  *
568  * @special
569  */
570 void chSchDoReschedule(void) {
571  thread_t *otp = currp;
572 
573  /* Picks the first thread from the ready queue and makes it current.*/
574  currp = queue_fifo_remove(&ch.rlist.queue);
575  currp->state = CH_STATE_CURRENT;
576 
577  /* Handling idle-leave hook.*/
578  if (otp->prio == IDLEPRIO) {
580  }
581 
582 #if CH_CFG_TIME_QUANTUM > 0
583  /* If CH_CFG_TIME_QUANTUM is enabled then there are two different scenarios
584  to handle on preemption: time quantum elapsed or not.*/
585  if (currp->ticks == (tslices_t)0) {
586 
587  /* The thread consumed its time quantum so it is enqueued behind threads
588  with same priority level, however, it acquires a new time quantum.*/
589  otp = chSchReadyI(otp);
590 
591  /* The thread being swapped out receives a new time quantum.*/
592  otp->ticks = (tslices_t)CH_CFG_TIME_QUANTUM;
593  }
594  else {
595  /* The thread didn't consume all its time quantum so it is put ahead of
596  threads with equal priority and does not acquire a new time quantum.*/
597  otp = chSchReadyAheadI(otp);
598  }
599 #else /* !(CH_CFG_TIME_QUANTUM > 0) */
600  /* If the round-robin mechanism is disabled then the thread goes always
601  ahead of its peers.*/
602  otp = chSchReadyAheadI(otp);
603 #endif /* !(CH_CFG_TIME_QUANTUM > 0) */
604 
605  /* Swap operation as tail call.*/
606  chSysSwitch(currp, otp);
607 }
608 #endif /* !defined(CH_SCH_DO_RESCHEDULE_HOOKED) */
609 
610 /** @} */
void _scheduler_init(void)
Scheduler initialization.
Definition: chschd.c:65
uint64_t sysinterval_t
Type of time interval.
Definition: chtime.h:119
tprio_t prio
Thread priority.
Definition: chschd.h:155
#define NOPRIO
Ready list header priority.
Definition: chschd.h:52
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
#define IDLEPRIO
Idle priority.
Definition: chschd.h:55
#define CH_STATE_SUSPENDED
Suspended state.
Definition: chschd.h:70
#define CH_STATE_CURRENT
Currently running.
Definition: chschd.h:68
#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
msg_t rdymsg
Thread wakeup code.
Definition: chschd.h:216
#define CH_STATE_WTCOND
On a cond.variable.
Definition: chschd.h:74
#define CH_CFG_IDLE_ENTER_HOOK()
Idle thread enter hook.
Definition: chconf.h:657
thread_t * next
Next in the list/queue.
Definition: chschd.h:136
#define MSG_TIMEOUT
Wakeup caused by a timeout condition.
Definition: chschd.h:40
static void chSemFastSignalI(semaphore_t *sp)
Increases the semaphore counter.
Definition: chsem.h:134
void chSchRescheduleS(void)
Performs a reschedule if a higher priority thread is runnable.
Definition: chschd.c:456
void chVTDoSetI(virtual_timer_t *vtp, sysinterval_t delay, vtfunc_t vtfunc, void *par)
Enables a virtual timer.
Definition: chvt.c:95
thread_t * next
Next in the list/queue.
Definition: chschd.h:143
#define chDbgCheck(c)
Function parameters check.
Definition: chdebug.h:101
void chVTDoResetI(virtual_timer_t *vtp)
Disables a Virtual Timer.
Definition: chvt.c:211
#define CH_STATE_FINAL
Thread terminated.
Definition: chschd.h:88
bool chSchIsPreemptionRequired(void)
Evaluates if preemption is required.
Definition: chschd.c:479
tslices_t ticks
Number of ticks remaining to this thread.
Definition: chschd.h:195
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
#define TIME_INFINITE
Infinite interval specification for all functions with a timeout specification.
Definition: chtime.h:55
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
static bool chSchIsRescRequiredI(void)
Determines if the current thread must reschedule.
Definition: chschd.h:655
static bool chVTIsArmedI(const virtual_timer_t *vtp)
Returns true if the specified timer is armed.
Definition: chvt.h:239
ready_list_t rlist
Ready list header.
Definition: chschd.h:415
ch_system_t ch
System data structures.
Definition: chschd.c:42
static void chSysUnlockFromISR(void)
Leaves the kernel lock state from within an interrupt handler.
Definition: chsys.h:413
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 void chSysLockFromISR(void)
Enters the kernel lock state from within an interrupt handler.
Definition: chsys.h:393
#define CH_STATE_READY
Waiting on the ready list.
Definition: chschd.h:65
void chSchDoRescheduleAhead(void)
Switches to the first thread on the runnable queue.
Definition: chschd.c:540
tstate_t state
Current thread state.
Definition: chschd.h:180
#define CH_STATE_WTSEM
On a semaphore.
Definition: chschd.h:72
Virtual Timer descriptor structure.
Definition: chschd.h:324
union ch_thread::@0 u
State-specific fields.
#define CH_CFG_TIME_QUANTUM
Round robin interval.
Definition: chconf.h:108
#define CH_CFG_IDLE_LEAVE_HOOK()
Idle thread leave hook.
Definition: chconf.h:667
struct ch_semaphore * wtsemp
Pointer to a generic semaphore object.
Definition: chschd.h:251
void chDbgCheckClassI(void)
I-class functions context check.
Definition: chdebug.c:233
thread_t * queue_dequeue(thread_t *tp)
Removes a thread from a queue and returns it.
Definition: chschd.c:162
void chSchWakeupS(thread_t *ntp, msg_t msg)
Wakes up a thread.
Definition: chschd.c:412
#define chDbgAssert(c, r)
Condition assertion.
Definition: chdebug.h:127
#define CH_STATE_QUEUED
On a queue.
Definition: chschd.h:71
void chDbgCheckClassS(void)
S-class functions context check.
Definition: chdebug.c:248
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_reference_t * wttrp
Pointer to a generic thread reference object.
Definition: chschd.h:237
ChibiOS/RT main include file.
thread_t * queue_fifo_remove(threads_queue_t *tqp)
Removes the first-out thread from a queue and returns it.
Definition: chschd.c:124
#define chSysSwitch(ntp, otp)
Performs a context switch.
Definition: chsys.h:266
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