123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716 |
- #ifndef CHSCHD_H
- #define CHSCHD_H
- #define MSG_OK (msg_t)0
- #define MSG_TIMEOUT (msg_t)-1
- #define MSG_RESET (msg_t)-2
- #define NOPRIO (tprio_t)0
- #define IDLEPRIO (tprio_t)1
- #define LOWPRIO (tprio_t)2
- #define NORMALPRIO (tprio_t)128
- #define HIGHPRIO (tprio_t)255
- #define CH_STATE_READY (tstate_t)0
- #define CH_STATE_CURRENT (tstate_t)1
- #define CH_STATE_WTSTART (tstate_t)2
- #define CH_STATE_SUSPENDED (tstate_t)3
- #define CH_STATE_QUEUED (tstate_t)4
- #define CH_STATE_WTSEM (tstate_t)5
- #define CH_STATE_WTMTX (tstate_t)6
- #define CH_STATE_WTCOND (tstate_t)7
- #define CH_STATE_SLEEPING (tstate_t)8
- #define CH_STATE_WTEXIT (tstate_t)9
- #define CH_STATE_WTOREVT (tstate_t)10
- #define CH_STATE_WTANDEVT (tstate_t)11
- #define CH_STATE_SNDMSGQ (tstate_t)12
- #define CH_STATE_SNDMSG (tstate_t)13
- #define CH_STATE_WTMSG (tstate_t)14
- #define CH_STATE_FINAL (tstate_t)15
- #define CH_STATE_NAMES \
- "READY", "CURRENT", "WTSTART", "SUSPENDED", "QUEUED", "WTSEM", "WTMTX", \
- "WTCOND", "SLEEPING", "WTEXIT", "WTOREVT", "WTANDEVT", "SNDMSGQ", \
- "SNDMSG", "WTMSG", "FINAL"
- #define CH_FLAG_MODE_MASK (tmode_t)3U
- #define CH_FLAG_MODE_STATIC (tmode_t)0U
- #define CH_FLAG_MODE_HEAP (tmode_t)1U
- #define CH_FLAG_MODE_MPOOL (tmode_t)2U
- #define CH_FLAG_TERMINATE (tmode_t)4U
- struct ch_threads_list {
- thread_t *next;
- };
- struct ch_threads_queue {
- thread_t *next;
- thread_t *prev;
- };
- struct ch_thread {
- threads_queue_t queue;
- tprio_t prio;
- struct port_context ctx;
- #if (CH_CFG_USE_REGISTRY == TRUE) || defined(__DOXYGEN__)
- thread_t *newer;
- thread_t *older;
- #endif
-
- #if (CH_CFG_USE_REGISTRY == TRUE) || defined(__DOXYGEN__)
-
- const char *name;
- #endif
- #if (CH_DBG_ENABLE_STACK_CHECK == TRUE) || (CH_CFG_USE_DYNAMIC == TRUE) || \
- defined(__DOXYGEN__)
-
- stkalign_t *wabase;
- #endif
-
- tstate_t state;
-
- tmode_t flags;
- #if (CH_CFG_USE_REGISTRY == TRUE) || defined(__DOXYGEN__)
-
- trefs_t refs;
- #endif
-
- #if (CH_CFG_TIME_QUANTUM > 0) || defined(__DOXYGEN__)
- tslices_t ticks;
- #endif
- #if (CH_DBG_THREADS_PROFILING == TRUE) || defined(__DOXYGEN__)
-
- volatile systime_t time;
- #endif
-
- union {
-
- msg_t rdymsg;
-
- msg_t exitcode;
-
- void *wtobjp;
-
- thread_reference_t *wttrp;
- #if (CH_CFG_USE_MESSAGES == TRUE) || defined(__DOXYGEN__)
-
- msg_t sentmsg;
- #endif
- #if (CH_CFG_USE_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
-
- struct ch_semaphore *wtsemp;
- #endif
- #if (CH_CFG_USE_MUTEXES == TRUE) || defined(__DOXYGEN__)
-
- struct ch_mutex *wtmtxp;
- #endif
- #if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__)
-
- eventmask_t ewmask;
- #endif
- } u;
- #if (CH_CFG_USE_WAITEXIT == TRUE) || defined(__DOXYGEN__)
-
- threads_list_t waiting;
- #endif
- #if (CH_CFG_USE_MESSAGES == TRUE) || defined(__DOXYGEN__)
-
- threads_queue_t msgqueue;
- #endif
- #if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__)
-
- eventmask_t epending;
- #endif
- #if (CH_CFG_USE_MUTEXES == TRUE) || defined(__DOXYGEN__)
-
- struct ch_mutex *mtxlist;
-
- tprio_t realprio;
- #endif
- #if ((CH_CFG_USE_DYNAMIC == TRUE) && (CH_CFG_USE_MEMPOOLS == TRUE)) || \
- defined(__DOXYGEN__)
-
- void *mpool;
- #endif
- #if (CH_DBG_STATISTICS == TRUE) || defined(__DOXYGEN__)
-
- time_measurement_t stats;
- #endif
- #if defined(CH_CFG_THREAD_EXTRA_FIELDS)
-
- CH_CFG_THREAD_EXTRA_FIELDS
- #endif
- };
- struct ch_virtual_timer {
- virtual_timer_t *next;
- virtual_timer_t *prev;
- sysinterval_t delta;
- vtfunc_t func;
- void *par;
- };
- struct ch_virtual_timers_list {
- virtual_timer_t *next;
- virtual_timer_t *prev;
- sysinterval_t delta;
- #if (CH_CFG_ST_TIMEDELTA == 0) || defined(__DOXYGEN__)
- volatile systime_t systime;
- #endif
- #if (CH_CFG_ST_TIMEDELTA > 0) || defined(__DOXYGEN__)
-
- systime_t lasttime;
- #endif
- };
- struct ch_ready_list {
- threads_queue_t queue;
- tprio_t prio;
- struct port_context ctx;
- #if (CH_CFG_USE_REGISTRY == TRUE) || defined(__DOXYGEN__)
- thread_t *newer;
- thread_t *older;
- #endif
-
- thread_t *current;
- };
- struct ch_system_debug {
-
- const char * volatile panic_msg;
- #if (CH_DBG_SYSTEM_STATE_CHECK == TRUE) || defined(__DOXYGEN__)
-
- cnt_t isr_cnt;
-
- cnt_t lock_cnt;
- #endif
- #if (CH_DBG_TRACE_MASK != CH_DBG_TRACE_MASK_DISABLED) || defined(__DOXYGEN__)
-
- ch_trace_buffer_t trace_buffer;
- #endif
- };
- struct ch_system {
-
- ready_list_t rlist;
-
- virtual_timers_list_t vtlist;
-
- system_debug_t dbg;
-
- thread_t mainthread;
- #if (CH_CFG_USE_TM == TRUE) || defined(__DOXYGEN__)
-
- tm_calibration_t tm;
- #endif
- #if (CH_DBG_STATISTICS == TRUE) || defined(__DOXYGEN__)
-
- kernel_stats_t kernel_stats;
- #endif
- CH_CFG_SYSTEM_EXTRA_FIELDS
- };
- #define firstprio(rlp) ((rlp)->next->prio)
- #define currp ch.rlist.current
- #if !defined(__DOXYGEN__)
- extern ch_system_t ch;
- #endif
- #ifdef __cplusplus
- extern "C" {
- #endif
- void _scheduler_init(void);
- thread_t *chSchReadyI(thread_t *tp);
- thread_t *chSchReadyAheadI(thread_t *tp);
- void chSchGoSleepS(tstate_t newstate);
- msg_t chSchGoSleepTimeoutS(tstate_t newstate, sysinterval_t timeout);
- void chSchWakeupS(thread_t *ntp, msg_t msg);
- void chSchRescheduleS(void);
- bool chSchIsPreemptionRequired(void);
- void chSchDoRescheduleBehind(void);
- void chSchDoRescheduleAhead(void);
- void chSchDoReschedule(void);
- #if CH_CFG_OPTIMIZE_SPEED == FALSE
- void queue_prio_insert(thread_t *tp, threads_queue_t *tqp);
- void queue_insert(thread_t *tp, threads_queue_t *tqp);
- thread_t *queue_fifo_remove(threads_queue_t *tqp);
- thread_t *queue_lifo_remove(threads_queue_t *tqp);
- thread_t *queue_dequeue(thread_t *tp);
- void list_insert(thread_t *tp, threads_list_t *tlp);
- thread_t *list_remove(threads_list_t *tlp);
- #endif
- #ifdef __cplusplus
- }
- #endif
- static inline void list_init(threads_list_t *tlp) {
- tlp->next = (thread_t *)tlp;
- }
- static inline bool list_isempty(threads_list_t *tlp) {
- return (bool)(tlp->next == (thread_t *)tlp);
- }
- static inline bool list_notempty(threads_list_t *tlp) {
- return (bool)(tlp->next != (thread_t *)tlp);
- }
- static inline void queue_init(threads_queue_t *tqp) {
- tqp->next = (thread_t *)tqp;
- tqp->prev = (thread_t *)tqp;
- }
- static inline bool queue_isempty(const threads_queue_t *tqp) {
- return (bool)(tqp->next == (const thread_t *)tqp);
- }
- static inline bool queue_notempty(const threads_queue_t *tqp) {
- return (bool)(tqp->next != (const thread_t *)tqp);
- }
- #if CH_CFG_OPTIMIZE_SPEED == TRUE
- static inline void list_insert(thread_t *tp, threads_list_t *tlp) {
- tp->queue.next = tlp->next;
- tlp->next = tp;
- }
- static inline thread_t *list_remove(threads_list_t *tlp) {
- thread_t *tp = tlp->next;
- tlp->next = tp->queue.next;
- return tp;
- }
- static inline void queue_prio_insert(thread_t *tp, threads_queue_t *tqp) {
- thread_t *cp = (thread_t *)tqp;
- do {
- cp = cp->queue.next;
- } while ((cp != (thread_t *)tqp) && (cp->prio >= tp->prio));
- tp->queue.next = cp;
- tp->queue.prev = cp->queue.prev;
- tp->queue.prev->queue.next = tp;
- cp->queue.prev = tp;
- }
- static inline void queue_insert(thread_t *tp, threads_queue_t *tqp) {
- tp->queue.next = (thread_t *)tqp;
- tp->queue.prev = tqp->prev;
- tp->queue.prev->queue.next = tp;
- tqp->prev = tp;
- }
- static inline thread_t *queue_fifo_remove(threads_queue_t *tqp) {
- thread_t *tp = tqp->next;
- tqp->next = tp->queue.next;
- tqp->next->queue.prev = (thread_t *)tqp;
- return tp;
- }
- static inline thread_t *queue_lifo_remove(threads_queue_t *tqp) {
- thread_t *tp = tqp->prev;
- tqp->prev = tp->queue.prev;
- tqp->prev->queue.next = (thread_t *)tqp;
- return tp;
- }
- static inline thread_t *queue_dequeue(thread_t *tp) {
- tp->queue.prev->queue.next = tp->queue.next;
- tp->queue.next->queue.prev = tp->queue.prev;
- return tp;
- }
- #endif
- static inline bool chSchIsRescRequiredI(void) {
- chDbgCheckClassI();
- return firstprio(&ch.rlist.queue) > currp->prio;
- }
- static inline bool chSchCanYieldS(void) {
- chDbgCheckClassS();
- return firstprio(&ch.rlist.queue) >= currp->prio;
- }
- static inline void chSchDoYieldS(void) {
- chDbgCheckClassS();
- if (chSchCanYieldS()) {
- chSchDoRescheduleBehind();
- }
- }
- static inline void chSchPreemption(void) {
- tprio_t p1 = firstprio(&ch.rlist.queue);
- tprio_t p2 = currp->prio;
- #if CH_CFG_TIME_QUANTUM > 0
- if (currp->ticks > (tslices_t)0) {
- if (p1 > p2) {
- chSchDoRescheduleAhead();
- }
- }
- else {
- if (p1 >= p2) {
- chSchDoRescheduleBehind();
- }
- }
- #else
- if (p1 > p2) {
- chSchDoRescheduleAhead();
- }
- #endif
- }
- #endif
|