ChibiOS  21.6.0
chschd.c
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 rt/src/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 /* Module local types. */
41 /*===========================================================================*/
42 
43 /*===========================================================================*/
44 /* Module local variables. */
45 /*===========================================================================*/
46 
47 /*===========================================================================*/
48 /* Module local functions. */
49 /*===========================================================================*/
50 
51 /**
52  * @brief Inserts a thread in the Ready List placing it behind its peers.
53  * @details The thread is positioned behind all threads with higher or equal
54  * priority.
55  * @pre The thread must not be already inserted in any list through its
56  * @p next and @p prev or list corruption would occur.
57  * @post This function does not reschedule so a call to a rescheduling
58  * function must be performed before unlocking the kernel. Note that
59  * interrupt handlers always reschedule on exit so an explicit
60  * reschedule must not be performed in ISRs.
61  *
62  * @param[in] tp the thread to be made ready
63  * @return The thread pointer.
64  *
65  * @notapi
66  */
68 
69  chDbgAssert((tp->state != CH_STATE_READY) &&
70  (tp->state != CH_STATE_FINAL),
71  "invalid state");
72 
73  /* Tracing the event.*/
74  __trace_ready(tp, tp->u.rdymsg);
75 
76  /* The thread is marked ready.*/
77  tp->state = CH_STATE_READY;
78 
79  /* Insertion in the priority queue.*/
81  &tp->hdr.pqueue);
82 }
83 
84 /**
85  * @brief Inserts a thread in the Ready List placing it ahead its peers.
86  * @details The thread is positioned ahead all threads with higher or equal
87  * priority.
88  * @pre The thread must not be already inserted in any list through its
89  * @p next and @p prev or list corruption would occur.
90  * @post This function does not reschedule so a call to a rescheduling
91  * function must be performed before unlocking the kernel. Note that
92  * interrupt handlers always reschedule on exit so an explicit
93  * reschedule must not be performed in ISRs.
94  *
95  * @param[in] tp the thread to be made ready
96  * @return The thread pointer.
97  *
98  * @notapi
99  */
101 
102  chDbgAssert((tp->state != CH_STATE_READY) &&
103  (tp->state != CH_STATE_FINAL),
104  "invalid state");
105 
106  /* Tracing the event.*/
107  __trace_ready(tp, tp->u.rdymsg);
108 
109  /* The thread is marked ready.*/
110  tp->state = CH_STATE_READY;
111 
112  /* Insertion in the priority queue.*/
114  &tp->hdr.pqueue);
115 }
116 
117 /**
118  * @brief Switches to the first thread on the runnable queue.
119  * @details The current thread is positioned in the ready list behind all
120  * threads having the same priority. The thread regains its time
121  * quantum.
122  * @note Not a user function, it is meant to be invoked by the scheduler
123  * itself.
124  *
125  * @notapi
126  */
127 static void __sch_reschedule_behind(void) {
128  os_instance_t *oip = currcore;
130  thread_t *ntp;
131 
132  /* Picks the first thread from the ready queue and makes it current.*/
134  ntp->state = CH_STATE_CURRENT;
135  __instance_set_currthread(oip, ntp);
136 
137  /* Handling idle-leave hook.*/
138  if (otp->hdr.pqueue.prio == IDLEPRIO) {
140  }
141 
142 #if CH_CFG_TIME_QUANTUM > 0
143  /* It went behind peers so it gets a new time quantum.*/
145 #endif
146 
147  /* Placing in ready list behind peers.*/
148  otp = __sch_ready_behind(otp);
149 
150  /* Swap operation as tail call.*/
151  chSysSwitch(ntp, otp);
152 }
153 
154 /**
155  * @brief Switches to the first thread on the runnable queue.
156  * @details The current thread is positioned in the ready list ahead of all
157  * threads having the same priority.
158  * @note Not a user function, it is meant to be invoked by the scheduler
159  * itself.
160  *
161  * @notapi
162  */
163 static void __sch_reschedule_ahead(void) {
164  os_instance_t *oip = currcore;
166  thread_t *ntp;
167 
168  /* Picks the first thread from the ready queue and makes it current.*/
170  ntp->state = CH_STATE_CURRENT;
171  __instance_set_currthread(oip, ntp);
172 
173  /* Handling idle-leave hook.*/
174  if (otp->hdr.pqueue.prio == IDLEPRIO) {
176  }
177 
178  /* Placing in ready list ahead of peers.*/
179  otp = __sch_ready_ahead(otp);
180 
181  /* Swap operation as tail call.*/
182  chSysSwitch(ntp, otp);
183 }
184 
185 /*
186  * Timeout wakeup callback.
187  */
188 static void __sch_wakeup(virtual_timer_t *vtp, void *p) {
189  thread_t *tp = (thread_t *)p;
190 
191  (void)vtp;
192 
194  switch (tp->state) {
195  case CH_STATE_READY:
196  /* Handling the special case where the thread has been made ready by
197  another thread with higher priority.*/
199  return;
200  case CH_STATE_SUSPENDED:
201  *tp->u.wttrp = NULL;
202  break;
203 #if CH_CFG_USE_SEMAPHORES == TRUE
204  case CH_STATE_WTSEM:
206 #endif
207  /* Falls through.*/
208  case CH_STATE_QUEUED:
209  /* Falls through.*/
210 #if (CH_CFG_USE_CONDVARS == TRUE) && (CH_CFG_USE_CONDVARS_TIMEOUT == TRUE)
211  case CH_STATE_WTCOND:
212 #endif
213  /* States requiring dequeuing.*/
214  (void) ch_queue_dequeue(&tp->hdr.queue);
215  break;
216  default:
217  /* Any other state, nothing to do.*/
218  break;
219  }
220 
221  /* Standard message for timeout conditions.*/
222  tp->u.rdymsg = MSG_TIMEOUT;
223 
224  /* Goes behind peers because it went to sleep voluntarily.*/
225  (void) __sch_ready_behind(tp);
227 
228  return;
229 }
230 
231 /*===========================================================================*/
232 /* Module exported functions. */
233 /*===========================================================================*/
234 
235 #if (CH_CFG_OPTIMIZE_SPEED == FALSE) || defined(__DOXYGEN__)
236 /**
237  * @brief Inserts a thread into a priority ordered queue.
238  * @note The insertion is done by scanning the list from the highest
239  * priority toward the lowest.
240  *
241  * @param[in] qp the pointer to the threads list header
242  * @param[in] tp the pointer to the thread to be inserted in the list
243  *
244  * @notapi
245  */
247 
248  ch_queue_t *cp = qp;
249  do {
250  cp = cp->next;
251  } while ((cp != qp) &&
252  (((thread_t *)cp)->hdr.pqueue.prio >= ((thread_t *)tp)->hdr.pqueue.prio));
253  tp->next = cp;
254  tp->prev = cp->prev;
255  tp->prev->next = tp;
256  cp->prev = tp;
257 }
258 #endif /* CH_CFG_OPTIMIZE_SPEED */
259 
260 /**
261  * @brief Inserts a thread in the Ready List placing it behind its peers.
262  * @details The thread is positioned behind all threads with higher or equal
263  * priority.
264  * @pre The thread must not be already inserted in any list through its
265  * @p next and @p prev or list corruption would occur.
266  * @post This function does not reschedule so a call to a rescheduling
267  * function must be performed before unlocking the kernel. Note that
268  * interrupt handlers always reschedule on exit so an explicit
269  * reschedule must not be performed in ISRs.
270  *
271  * @param[in] tp the thread to be made ready
272  * @return The thread pointer.
273  *
274  * @iclass
275  */
277 
278  chDbgCheckClassI();
279  chDbgCheck(tp != NULL);
280 
281 #if CH_CFG_SMP_MODE == TRUE
282  if (tp->owner != currcore) {
283  /* Readying up the remote thread and triggering a reschedule on
284  the other core.*/
286  }
287 #endif
288 
289  return __sch_ready_behind(tp);
290 }
291 
292 /**
293  * @brief Puts the current thread to sleep into the specified state.
294  * @details The thread goes into a sleeping state. The possible
295  * @ref thread_states are defined into @p threads.h.
296  *
297  * @param[in] newstate the new thread state
298  *
299  * @sclass
300  */
301 void chSchGoSleepS(tstate_t newstate) {
302  os_instance_t *oip = currcore;
304  thread_t *ntp;
305 
306  chDbgCheckClassS();
307 
308  chDbgAssert(otp != chSysGetIdleThreadX(), "sleeping in idle thread");
309  chDbgAssert(otp->owner == oip, "invalid core");
310 
311  /* New state.*/
312  otp->state = newstate;
313 
314 #if CH_CFG_TIME_QUANTUM > 0
315  /* The thread is renouncing its remaining time slices so it will have a new
316  time quantum when it will wakeup.*/
318 #endif
319 
320  /* Next thread in ready list becomes current.*/
322  ntp->state = CH_STATE_CURRENT;
323  __instance_set_currthread(oip, ntp);
324 
325  /* Handling idle-enter hook.*/
326  if (ntp->hdr.pqueue.prio == IDLEPRIO) {
328  }
329 
330  /* Swap operation as tail call.*/
331  chSysSwitch(ntp, otp);
332 }
333 
334 /**
335  * @brief Puts the current thread to sleep into the specified state with
336  * timeout specification.
337  * @details The thread goes into a sleeping state, if it is not awakened
338  * explicitly within the specified timeout then it is forcibly
339  * awakened with a @p MSG_TIMEOUT low level message. The possible
340  * @ref thread_states are defined into @p threads.h.
341  *
342  * @param[in] newstate the new thread state
343  * @param[in] timeout the number of ticks before the operation timeouts, the
344  * special values are handled as follow:
345  * - @a TIME_INFINITE the thread enters an infinite sleep
346  * state, this is equivalent to invoking
347  * @p chSchGoSleepS() but, of course, less efficient.
348  * - @a TIME_IMMEDIATE this value is not allowed.
349  * .
350  * @return The wakeup message.
351  * @retval MSG_TIMEOUT if a timeout occurs.
352  *
353  * @sclass
354  */
357 
358  chDbgCheckClassS();
359 
360  if (TIME_INFINITE != timeout) {
361  virtual_timer_t vt;
362 
363  chVTDoSetI(&vt, timeout, __sch_wakeup, (void *)tp);
364  chSchGoSleepS(newstate);
365  if (chVTIsArmedI(&vt)) {
366  chVTDoResetI(&vt);
367  }
368  }
369  else {
370  chSchGoSleepS(newstate);
371  }
372 
373  return tp->u.rdymsg;
374 }
375 
376 /**
377  * @brief Wakes up a thread.
378  * @details The thread is inserted into the ready list or immediately made
379  * running depending on its relative priority compared to the current
380  * thread.
381  * @pre The thread must not be already inserted in any list through its
382  * @p next and @p prev or list corruption would occur.
383  * @note It is equivalent to a @p chSchReadyI() followed by a
384  * @p chSchRescheduleS() but much more efficient.
385  * @note The function assumes that the current thread has the highest
386  * priority.
387  *
388  * @param[in] ntp the thread to be made ready
389  * @param[in] msg the wakeup message
390  *
391  * @sclass
392  */
393 void chSchWakeupS(thread_t *ntp, msg_t msg) {
394  os_instance_t *oip = currcore;
396 
397  chDbgCheckClassS();
398 
399  chDbgAssert((oip->rlist.pqueue.next == &oip->rlist.pqueue) ||
400  (oip->rlist.current->hdr.pqueue.prio >= oip->rlist.pqueue.next->prio),
401  "priority order violation");
402 
403  /* Storing the message to be retrieved by the target thread when it will
404  restart execution.*/
405  ntp->u.rdymsg = msg;
406 
407 #if CH_CFG_SMP_MODE == TRUE
408  if (ntp->owner != oip) {
409  /* Readying up the remote thread and triggering a reschedule on
410  the other core.*/
412  (void) __sch_ready_behind(ntp);
413  return;
414  }
415 #endif
416 
417  /* If the woken thread has a not-greater priority than the current
418  one then it is just inserted in the ready list else it made
419  running immediately and the invoking thread goes in the ready
420  list instead.
421  Note, we are favoring the path where the woken thread has higher
422  priority.*/
423  if (unlikely(ntp->hdr.pqueue.prio <= otp->hdr.pqueue.prio)) {
424  (void) __sch_ready_behind(ntp);
425  }
426  else {
427  /* The old thread goes back in the ready list ahead of its peers
428  because it has not exhausted its time slice.*/
429  otp = __sch_ready_ahead(otp);
430 
431  /* Handling idle-leave hook.*/
432  if (otp->hdr.pqueue.prio == IDLEPRIO) {
434  }
435 
436  /* The extracted thread is marked as current.*/
437  ntp->state = CH_STATE_CURRENT;
438  __instance_set_currthread(oip, ntp);
439 
440  /* Swap operation as tail call.*/
441  chSysSwitch(ntp, otp);
442  }
443 }
444 
445 /**
446  * @brief Performs a reschedule if a higher priority thread is runnable.
447  * @details If a thread with a higher priority than the current thread is in
448  * the ready list then make the higher priority thread running.
449  * @note Only local threads are considered, other cores are signaled
450  * and perform a reschedule locally.
451  *
452  * @sclass
453  */
454 void chSchRescheduleS(void) {
455  os_instance_t *oip = currcore;
457 
458  chDbgCheckClassS();
459 
460  /* Note, we are favoring the path where the reschedule is necessary
461  because higher priority threads are ready.*/
462  if (likely(firstprio(&oip->rlist.pqueue) > tp->hdr.pqueue.prio)) {
464  }
465 }
466 
467 #if !defined(CH_SCH_IS_PREEMPTION_REQUIRED_HOOKED)
468 /**
469  * @brief Evaluates if preemption is required.
470  * @details The decision is taken by comparing the relative priorities and
471  * depending on the state of the round robin timeout counter.
472  * @note Not a user function, it is meant to be invoked from within
473  * the port layer in the IRQ-related preemption code.
474  *
475  * @retval true if there is a thread that must go in running state
476  * immediately.
477  * @retval false if preemption is not required.
478  *
479  * @special
480  */
482  os_instance_t *oip = currcore;
484 
485  tprio_t p1 = firstprio(&oip->rlist.pqueue);
486  tprio_t p2 = tp->hdr.pqueue.prio;
487 
488 #if CH_CFG_TIME_QUANTUM > 0
489  /* If the running thread has not reached its time quantum, reschedule only
490  if the first thread on the ready queue has a higher priority.
491  Otherwise, if the running thread has used up its time quantum, reschedule
492  if the first thread on the ready queue has equal or higher priority.*/
493  return (tp->ticks > (tslices_t)0) ? (p1 > p2) : (p1 >= p2);
494 #else
495  /* If the round robin preemption feature is not enabled then performs a
496  simpler comparison.*/
497  return p1 > p2;
498 #endif
499 }
500 #endif /* !defined(CH_SCH_IS_PREEMPTION_REQUIRED_HOOKED) */
501 
502 #if !defined(CH_SCH_DO_PREEMPTION_HOOKED)
503 /**
504  * @brief Switches to the first thread on the runnable queue.
505  * @details The current thread is positioned in the ready list behind or
506  * ahead of all threads having the same priority depending on
507  * if it used its whole time slice.
508  * @note Not a user function, it is meant to be invoked from within
509  * the port layer in the IRQ-related preemption code.
510  *
511  * @special
512  */
513 void chSchDoPreemption(void) {
514  os_instance_t *oip = currcore;
516  thread_t *ntp;
517 
518  /* Picks the first thread from the ready queue and makes it current.*/
520  ntp->state = CH_STATE_CURRENT;
521  __instance_set_currthread(oip, ntp);
522 
523  /* Handling idle-leave hook.*/
524  if (otp->hdr.pqueue.prio == IDLEPRIO) {
526  }
527 
528 #if CH_CFG_TIME_QUANTUM > 0
529  /* If CH_CFG_TIME_QUANTUM is enabled then there are two different scenarios
530  to handle on preemption: time quantum elapsed or not.*/
531  if (otp->ticks == (tslices_t)0) {
532 
533  /* The thread consumed its time quantum so it is enqueued behind threads
534  with same priority level, however, it acquires a new time quantum.*/
535  otp = __sch_ready_behind(otp);
536 
537  /* The thread being swapped out receives a new time quantum.*/
539  }
540  else {
541  /* The thread didn't consume all its time quantum so it is put ahead of
542  threads with equal priority and does not acquire a new time quantum.*/
543  otp = __sch_ready_ahead(otp);
544  }
545 #else /* !(CH_CFG_TIME_QUANTUM > 0) */
546  /* If the round-robin mechanism is disabled then the thread goes always
547  ahead of its peers.*/
548  otp = __sch_ready_ahead(otp);
549 #endif /* !(CH_CFG_TIME_QUANTUM > 0) */
550 
551  /* Swap operation as tail call.*/
552  chSysSwitch(ntp, otp);
553 }
554 #endif /* !defined(CH_SCH_DO_PREEMPTION_HOOKED) */
555 
556 #if !defined(CH_SCH_PREEMPTION_HOOKED)
557 /**
558  * @brief All-in-one preemption code.
559  * @note Not a user function, it is meant to be invoked from within
560  * the port layer in the IRQ-related preemption code.
561  *
562  * @special
563  */
564 void chSchPreemption(void) {
565  os_instance_t *oip = currcore;
567  tprio_t p1 = firstprio(&oip->rlist.pqueue);
568  tprio_t p2 = tp->hdr.pqueue.prio;
569 
570  /* Note, we are favoring the path where preemption is necessary
571  because higher priority threads are ready.*/
572 #if CH_CFG_TIME_QUANTUM > 0
573  if (tp->ticks > (tslices_t)0) {
574  if (likely(p1 > p2)) {
576  }
577  }
578  else {
579  if (likely(p1 >= p2)) {
581  }
582  }
583 #else /* CH_CFG_TIME_QUANTUM == 0 */
584  if (likely(p1 > p2)) {
586  }
587 #endif /* CH_CFG_TIME_QUANTUM == 0 */
588 }
589 #endif /* !defined(CH_SCH_PREEMPTION_HOOKED) */
590 
591 /**
592  * @brief Yields the time slot.
593  * @details Yields the CPU control to the next thread in the ready list with
594  * equal or higher priority, if any.
595  *
596  * @sclass
597  */
598 void chSchDoYieldS(void) {
599  os_instance_t *oip = currcore;
601 
602  chDbgCheckClassS();
603 
604  /* If this function has been called then it is likely there are threads
605  at same priority level.*/
606  if (likely(firstprio(&oip->rlist.pqueue) >= tp->hdr.pqueue.prio)) {
608  }
609 }
610 
611 /**
612  * @brief Makes runnable the fist thread in the ready list, does not
613  * reschedule internally.
614  * @details The current thread is positioned in the ready list ahead of all
615  * threads having the same priority.
616  * @note Not a user function, it is meant to be invoked by the scheduler
617  * itself.
618  *
619  * @return The pointer to the thread being switched in.
620  *
621  * @special
622  */
624  os_instance_t *oip = currcore;
626  thread_t *ntp;
627 
628  /* Picks the first thread from the ready queue and makes it current.*/
630  ntp->state = CH_STATE_CURRENT;
631  __instance_set_currthread(oip, ntp);
632 
633  /* Handling idle-leave hook.*/
634  if (otp->hdr.pqueue.prio == IDLEPRIO) {
636  }
637 
638  /* Placing in ready list ahead of peers.*/
639  (void) __sch_ready_ahead(otp);
640 
641  return ntp;
642 }
643 
644 /** @} */
CH_CFG_IDLE_LEAVE_HOOK
#define CH_CFG_IDLE_LEAVE_HOOK()
Idle thread leave hook.
Definition: rt/templates/chconf.h:763
IDLEPRIO
#define IDLEPRIO
Idle priority.
Definition: chschd.h:52
__instance_set_currthread
#define __instance_set_currthread(oip, tp)
Current thread pointer set macro.
Definition: chinstances.h:61
ch_thread::wttrp
thread_reference_t * wttrp
Pointer to a generic thread reference object.
Definition: chobjects.h:263
CH_STATE_READY
#define CH_STATE_READY
Waiting on the ready list.
Definition: chschd.h:62
tprio_t
uint32_t tprio_t
Definition: chearly.h:87
ch_queue::next
ch_queue_t * next
Next in the list/queue.
Definition: chlists.h:70
chSchReadyI
thread_t * chSchReadyI(thread_t *tp)
Inserts a thread in the Ready List placing it behind its peers.
Definition: chschd.c:276
__sch_reschedule_ahead
static void __sch_reschedule_ahead(void)
Switches to the first thread on the runnable queue.
Definition: chschd.c:163
ch_thread::pqueue
ch_priority_queue_t pqueue
Threads ordered queues element.
Definition: chobjects.h:172
chSemFastSignalI
#define chSemFastSignalI(sp)
Increases the semaphore counter.
Definition: nil/include/chsem.h:176
currcore
#define currcore
Access to current core's instance structure.
Definition: chsys.h:90
ch_thread::rdymsg
msg_t rdymsg
Thread wakeup code.
Definition: chobjects.h:242
CH_CFG_TIME_QUANTUM
#define CH_CFG_TIME_QUANTUM
Round robin interval.
Definition: rt/templates/chconf.h:128
chVTIsArmedI
static bool chVTIsArmedI(const virtual_timer_t *vtp)
Returns true if the specified timer is armed.
Definition: chvt.h:248
chSysUnlockFromISR
#define chSysUnlockFromISR()
Leaves the kernel lock state from within an interrupt handler.
Definition: nil/include/ch.h:1088
chDbgAssert
#define chDbgAssert(c, r)
Condition assertion.
Definition: chdebug.h:144
CH_CFG_IDLE_ENTER_HOOK
#define CH_CFG_IDLE_ENTER_HOOK()
Idle thread enter hook.
Definition: rt/templates/chconf.h:753
CH_STATE_SUSPENDED
#define CH_STATE_SUSPENDED
Suspended state.
Definition: chschd.h:66
ch_ready_list::current
thread_t * current
The currently running thread.
Definition: chobjects.h:357
chSysLockFromISR
#define chSysLockFromISR()
Enters the kernel lock state from within an interrupt handler.
Definition: nil/include/ch.h:1070
chSysSwitch
#define chSysSwitch(ntp, otp)
Performs a context switch.
Definition: chsys.h:305
ch_os_instance
System instance data structure.
Definition: chobjects.h:394
CH_STATE_WTCOND
#define CH_STATE_WTCOND
On a cond.variable.
Definition: chschd.h:70
tstate_t
uint8_t tstate_t
Definition: chearly.h:84
msg_t
int32_t msg_t
Definition: chearly.h:88
chSchGoSleepTimeoutS
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:355
likely
#define likely(x)
Marks a boolean expression as likely true.
Definition: chearly.h:178
chDbgCheck
#define chDbgCheck(c)
Function parameters check.
Definition: chdebug.h:118
chSchPreemption
void chSchPreemption(void)
All-in-one preemption code.
Definition: chschd.c:564
chSchDoYieldS
void chSchDoYieldS(void)
Yields the time slot.
Definition: chschd.c:598
ch_pqueue_insert_ahead
static ch_priority_queue_t * ch_pqueue_insert_ahead(ch_priority_queue_t *pqp, ch_priority_queue_t *p)
Inserts an element in the priority queue placing it ahead of its peers.
Definition: chlists.h:402
ch_thread
Structure representing a thread.
Definition: chobjects.h:156
__sch_ready_behind
static thread_t * __sch_ready_behind(thread_t *tp)
Inserts a thread in the Ready List placing it behind its peers.
Definition: chschd.c:67
chSchGoSleepS
void chSchGoSleepS(tstate_t newstate)
Puts the current thread to sleep into the specified state.
Definition: chschd.c:301
CH_STATE_CURRENT
#define CH_STATE_CURRENT
Currently running.
Definition: chschd.h:64
ch_thread::hdr
union ch_thread::@0 hdr
Shared list headers.
ch_thread::ticks
tslices_t ticks
Number of ticks remaining to this thread.
Definition: chobjects.h:221
tslices_t
uint8_t tslices_t
Definition: chearly.h:86
ch_pqueue_remove_highest
static ch_priority_queue_t * ch_pqueue_remove_highest(ch_priority_queue_t *pqp)
Removes the highest priority element from a priority queue and returns it.
Definition: chlists.h:352
CH_STATE_FINAL
#define CH_STATE_FINAL
Thread terminated.
Definition: chschd.h:81
ch_pqueue_insert_behind
static ch_priority_queue_t * ch_pqueue_insert_behind(ch_priority_queue_t *pqp, ch_priority_queue_t *p)
Inserts an element in the priority queue placing it behind its peers.
Definition: chlists.h:373
ch_thread::u
union ch_thread::@1 u
State-specific fields.
ch_queue
Structure representing a generic bidirectional linked list header and element.
Definition: chlists.h:69
TIME_INFINITE
#define TIME_INFINITE
Infinite interval specification for all functions with a timeout specification.
Definition: chtime.h:55
chSchRescheduleS
void chSchRescheduleS(void)
Performs a reschedule if a higher priority thread is runnable.
Definition: chschd.c:454
firstprio
#define firstprio(rlp)
Returns the priority of the first thread on the given ready list.
Definition: chschd.h:130
__instance_get_currthread
#define __instance_get_currthread(oip)
Current thread pointer get macro.
Definition: chinstances.h:56
ch_sch_prio_insert
void ch_sch_prio_insert(ch_queue_t *qp, ch_queue_t *tp)
Inserts a thread into a priority ordered queue.
Definition: chschd.c:246
ch_virtual_timer
Structure representing a Virtual Timer.
Definition: chobjects.h:75
chSysNotifyInstance
static void chSysNotifyInstance(os_instance_t *oip)
Notifies an OS instance to check for reschedule.
Definition: chsys.h:515
chSchSelectFirstI
thread_t * chSchSelectFirstI(void)
Makes runnable the fist thread in the ready list, does not reschedule internally.
Definition: chschd.c:623
chSchDoPreemption
void chSchDoPreemption(void)
Switches to the first thread on the runnable queue.
Definition: chschd.c:513
chSchIsPreemptionRequired
bool chSchIsPreemptionRequired(void)
Evaluates if preemption is required.
Definition: chschd.c:481
sysinterval_t
uint64_t sysinterval_t
Type of time interval.
Definition: chtime.h:119
ch_priority_queue::next
ch_priority_queue_t * next
Next in the queue.
Definition: chlists.h:86
chVTDoResetI
void chVTDoResetI(virtual_timer_t *vtp)
Disables a Virtual Timer.
Definition: chvt.c:241
CH_STATE_QUEUED
#define CH_STATE_QUEUED
On a queue.
Definition: chschd.h:67
__sch_ready_ahead
static thread_t * __sch_ready_ahead(thread_t *tp)
Inserts a thread in the Ready List placing it ahead its peers.
Definition: chschd.c:100
ch_thread::queue
ch_queue_t queue
Threads queues element.
Definition: chobjects.h:168
ch_thread::state
tstate_t state
Current thread state.
Definition: chobjects.h:206
ch_thread::wtsemp
struct ch_semaphore * wtsemp
Pointer to a generic semaphore object.
Definition: chobjects.h:277
__trace_ready
void __trace_ready(thread_t *tp, msg_t msg)
Inserts in the circular debug trace buffer a ready record.
Definition: chtrace.c:107
unlikely
#define unlikely(x)
Marks a boolean expression as likely false.
Definition: chearly.h:191
__sch_reschedule_behind
static void __sch_reschedule_behind(void)
Switches to the first thread on the runnable queue.
Definition: chschd.c:127
MSG_TIMEOUT
#define MSG_TIMEOUT
Wakeup caused by a timeout condition.
Definition: chschd.h:40
chVTDoSetI
void chVTDoSetI(virtual_timer_t *vtp, sysinterval_t delay, vtfunc_t vtfunc, void *par)
Enables a one-shot virtual timer.
Definition: chvt.c:179
ch_queue_dequeue
static ch_queue_t * ch_queue_dequeue(ch_queue_t *p)
Removes an element from a queue and returns it.
Definition: chlists.h:318
ch_os_instance::rlist
ready_list_t rlist
Ready list header.
Definition: chobjects.h:398
ch_thread::owner
os_instance_t * owner
OS instance owner of this thread.
Definition: chobjects.h:187
ch_priority_queue::prio
tprio_t prio
Priority of this element.
Definition: chlists.h:88
ch_ready_list::pqueue
ch_priority_queue_t pqueue
Threads ordered queues header.
Definition: chobjects.h:353
CH_STATE_WTSEM
#define CH_STATE_WTSEM
On a semaphore.
Definition: chschd.h:68
chSchWakeupS
void chSchWakeupS(thread_t *ntp, msg_t msg)
Wakes up a thread.
Definition: chschd.c:393
chSysGetIdleThreadX
static thread_t * chSysGetIdleThreadX(void)
Returns a pointer to the idle thread.
Definition: chsys.h:534