        -:    0:Source:../../../os/rt/include/chsys.h
        -:    0:Programs:17
        -:    1:/*
        -:    2:    ChibiOS - Copyright (C) 2006..2015 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    chsys.h
        -:   22: * @brief   System related macros and structures.
        -:   23: *
        -:   24: * @addtogroup system
        -:   25: * @{
        -:   26: */
        -:   27:
        -:   28:#ifndef _CHSYS_H_
        -:   29:#define _CHSYS_H_
        -:   30:
        -:   31:/*lint -sem(chSysHalt, r_no)*/
        -:   32:
        -:   33:/*===========================================================================*/
        -:   34:/* Module constants.                                                         */
        -:   35:/*===========================================================================*/
        -:   36:
        -:   37:/**
        -:   38: * @name    Masks of executable integrity checks.
        -:   39: * @{
        -:   40: */
        -:   41:#define CH_INTEGRITY_RLIST                  1U
        -:   42:#define CH_INTEGRITY_VTLIST                 2U
        -:   43:#define CH_INTEGRITY_REGISTRY               4U
        -:   44:#define CH_INTEGRITY_PORT                   8U
        -:   45:/** @} */
        -:   46:
        -:   47:/*===========================================================================*/
        -:   48:/* Module pre-compile time settings.                                         */
        -:   49:/*===========================================================================*/
        -:   50:
        -:   51:/*===========================================================================*/
        -:   52:/* Derived constants and error checks.                                       */
        -:   53:/*===========================================================================*/
        -:   54:
        -:   55:/*===========================================================================*/
        -:   56:/* Module data structures and types.                                         */
        -:   57:/*===========================================================================*/
        -:   58:
        -:   59:/*===========================================================================*/
        -:   60:/* Module macros.                                                            */
        -:   61:/*===========================================================================*/
        -:   62:
        -:   63:/**
        -:   64: * @name    ISRs abstraction macros
        -:   65: */
        -:   66:/**
        -:   67: * @brief   Priority level validation macro.
        -:   68: * @details This macro determines if the passed value is a valid priority
        -:   69: *          level for the underlying architecture.
        -:   70: *
        -:   71: * @param[in] prio      the priority level
        -:   72: * @return              Priority range result.
        -:   73: * @retval false        if the priority is invalid or if the architecture
        -:   74: *                      does not support priorities.
        -:   75: * @retval true         if the priority is valid.
        -:   76: */
        -:   77:#if defined(PORT_IRQ_IS_VALID_PRIORITY) || defined(__DOXYGEN__)
        -:   78:#define CH_IRQ_IS_VALID_PRIORITY(prio)                                      \
        -:   79:  PORT_IRQ_IS_VALID_PRIORITY(prio)
        -:   80:#else
        -:   81:#define CH_IRQ_IS_VALID_PRIORITY(prio) false
        -:   82:#endif
        -:   83:
        -:   84:/**
        -:   85: * @brief   Priority level validation macro.
        -:   86: * @details This macro determines if the passed value is a valid priority
        -:   87: *          level that cannot preempt the kernel critical zone.
        -:   88: *
        -:   89: * @param[in] prio      the priority level
        -:   90: * @return              Priority range result.
        -:   91: * @retval false        if the priority is invalid or if the architecture
        -:   92: *                      does not support priorities.
        -:   93: * @retval true         if the priority is valid.
        -:   94: */
        -:   95:#if defined(PORT_IRQ_IS_VALID_KERNEL_PRIORITY) || defined(__DOXYGEN__)
        -:   96:#define CH_IRQ_IS_VALID_KERNEL_PRIORITY(prio)                               \
        -:   97:  PORT_IRQ_IS_VALID_KERNEL_PRIORITY(prio)
        -:   98:#else
        -:   99:#define CH_IRQ_IS_VALID_KERNEL_PRIORITY(prio) false
        -:  100:#endif
        -:  101:
        -:  102:/**
        -:  103: * @brief   IRQ handler enter code.
        -:  104: * @note    Usually IRQ handlers functions are also declared naked.
        -:  105: * @note    On some architectures this macro can be empty.
        -:  106: *
        -:  107: * @special
        -:  108: */
        -:  109:#define CH_IRQ_PROLOGUE()                                                   \
        -:  110:  PORT_IRQ_PROLOGUE();                                                      \
        -:  111:  _stats_increase_irq();                                                    \
        -:  112:  _dbg_check_enter_isr()
        -:  113:
        -:  114:/**
        -:  115: * @brief   IRQ handler exit code.
        -:  116: * @note    Usually IRQ handlers function are also declared naked.
        -:  117: * @note    This macro usually performs the final reschedule by using
        -:  118: *          @p chSchIsPreemptionRequired() and @p chSchDoReschedule().
        -:  119: *
        -:  120: * @special
        -:  121: */
        -:  122:#define CH_IRQ_EPILOGUE()                                                   \
        -:  123:  _dbg_check_leave_isr();                                                   \
        -:  124:  PORT_IRQ_EPILOGUE()
        -:  125:
        -:  126:/**
        -:  127: * @brief   Standard normal IRQ handler declaration.
        -:  128: * @note    @p id can be a function name or a vector number depending on the
        -:  129: *          port implementation.
        -:  130: *
        -:  131: * @special
        -:  132: */
        -:  133:#define CH_IRQ_HANDLER(id) PORT_IRQ_HANDLER(id)
        -:  134:/** @} */
        -:  135:
        -:  136:/**
        -:  137: * @name    Fast ISRs abstraction macros
        -:  138: */
        -:  139:/**
        -:  140: * @brief   Standard fast IRQ handler declaration.
        -:  141: * @note    @p id can be a function name or a vector number depending on the
        -:  142: *          port implementation.
        -:  143: * @note    Not all architectures support fast interrupts.
        -:  144: *
        -:  145: * @special
        -:  146: */
        -:  147:#define CH_FAST_IRQ_HANDLER(id) PORT_FAST_IRQ_HANDLER(id)
        -:  148:/** @} */
        -:  149:
        -:  150:/**
        -:  151: * @name    Time conversion utilities for the realtime counter
        -:  152: * @{
        -:  153: */
        -:  154:/**
        -:  155: * @brief   Seconds to realtime counter.
        -:  156: * @details Converts from seconds to realtime counter cycles.
        -:  157: * @note    The macro assumes that @p freq >= @p 1.
        -:  158: *
        -:  159: * @param[in] freq      clock frequency, in Hz, of the realtime counter
        -:  160: * @param[in] sec       number of seconds
        -:  161: * @return              The number of cycles.
        -:  162: *
        -:  163: * @api
        -:  164: */
        -:  165:#define S2RTC(freq, sec) ((freq) * (sec))
        -:  166:
        -:  167:/**
        -:  168: * @brief   Milliseconds to realtime counter.
        -:  169: * @details Converts from milliseconds to realtime counter cycles.
        -:  170: * @note    The result is rounded upward to the next millisecond boundary.
        -:  171: * @note    The macro assumes that @p freq >= @p 1000.
        -:  172: *
        -:  173: * @param[in] freq      clock frequency, in Hz, of the realtime counter
        -:  174: * @param[in] msec      number of milliseconds
        -:  175: * @return              The number of cycles.
        -:  176: *
        -:  177: * @api
        -:  178: */
        -:  179:#define MS2RTC(freq, msec) (rtcnt_t)((((freq) + 999UL) / 1000UL) * (msec))
        -:  180:
        -:  181:/**
        -:  182: * @brief   Microseconds to realtime counter.
        -:  183: * @details Converts from microseconds to realtime counter cycles.
        -:  184: * @note    The result is rounded upward to the next microsecond boundary.
        -:  185: * @note    The macro assumes that @p freq >= @p 1000000.
        -:  186: *
        -:  187: * @param[in] freq      clock frequency, in Hz, of the realtime counter
        -:  188: * @param[in] usec      number of microseconds
        -:  189: * @return              The number of cycles.
        -:  190: *
        -:  191: * @api
        -:  192: */
        -:  193:#define US2RTC(freq, usec) (rtcnt_t)((((freq) + 999999UL) / 1000000UL) * (usec))
        -:  194:
        -:  195:/**
        -:  196: * @brief   Realtime counter cycles to seconds.
        -:  197: * @details Converts from realtime counter cycles number to seconds.
        -:  198: * @note    The result is rounded up to the next second boundary.
        -:  199: * @note    The macro assumes that @p freq >= @p 1.
        -:  200: *
        -:  201: * @param[in] freq      clock frequency, in Hz, of the realtime counter
        -:  202: * @param[in] n         number of cycles
        -:  203: * @return              The number of seconds.
        -:  204: *
        -:  205: * @api
        -:  206: */
        -:  207:#define RTC2S(freq, n) ((((n) - 1UL) / (freq)) + 1UL)
        -:  208:
        -:  209:/**
        -:  210: * @brief   Realtime counter cycles to milliseconds.
        -:  211: * @details Converts from realtime counter cycles number to milliseconds.
        -:  212: * @note    The result is rounded up to the next millisecond boundary.
        -:  213: * @note    The macro assumes that @p freq >= @p 1000.
        -:  214: *
        -:  215: * @param[in] freq      clock frequency, in Hz, of the realtime counter
        -:  216: * @param[in] n         number of cycles
        -:  217: * @return              The number of milliseconds.
        -:  218: *
        -:  219: * @api
        -:  220: */
        -:  221:#define RTC2MS(freq, n) ((((n) - 1UL) / ((freq) / 1000UL)) + 1UL)
        -:  222:
        -:  223:/**
        -:  224: * @brief   Realtime counter cycles to microseconds.
        -:  225: * @details Converts from realtime counter cycles number to microseconds.
        -:  226: * @note    The result is rounded up to the next microsecond boundary.
        -:  227: * @note    The macro assumes that @p freq >= @p 1000000.
        -:  228: *
        -:  229: * @param[in] freq      clock frequency, in Hz, of the realtime counter
        -:  230: * @param[in] n         number of cycles
        -:  231: * @return              The number of microseconds.
        -:  232: *
        -:  233: * @api
        -:  234: */
        -:  235:#define RTC2US(freq, n) ((((n) - 1UL) / ((freq) / 1000000UL)) + 1UL)
        -:  236:/** @} */
        -:  237:
        -:  238:/**
        -:  239: * @brief   Returns the current value of the system real time counter.
        -:  240: * @note    This function is only available if the port layer supports the
        -:  241: *          option @p PORT_SUPPORTS_RT.
        -:  242: *
        -:  243: * @return              The value of the system realtime counter of
        -:  244: *                      type rtcnt_t.
        -:  245: *
        -:  246: * @xclass
        -:  247: */
        -:  248:#if (PORT_SUPPORTS_RT == TRUE) || defined(__DOXYGEN__)
        -:  249:#define chSysGetRealtimeCounterX() (rtcnt_t)port_rt_get_counter_value()
        -:  250:#endif
        -:  251:
        -:  252:/**
        -:  253: * @brief   Performs a context switch.
        -:  254: * @note    Not a user function, it is meant to be invoked by the scheduler
        -:  255: *          itself or from within the port layer.
        -:  256: *
        -:  257: * @param[in] ntp       the thread to be switched in
        -:  258: * @param[in] otp       the thread to be switched out
        -:  259: *
        -:  260: * @special
        -:  261: */
        -:  262:#define chSysSwitch(ntp, otp) {                                             \
        -:  263:                                                                            \
        -:  264:  _dbg_trace(otp);                                                          \
        -:  265:  _stats_ctxswc(ntp, otp);                                                  \
        -:  266:  CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp);                                     \
        -:  267:  port_switch(ntp, otp);                                                    \
        -:  268:}
        -:  269:
        -:  270:/*===========================================================================*/
        -:  271:/* External declarations.                                                    */
        -:  272:/*===========================================================================*/
        -:  273:
        -:  274:#ifdef __cplusplus
        -:  275:extern "C" {
        -:  276:#endif
        -:  277:  void chSysInit(void);
        -:  278:  void chSysHalt(const char *reason);
        -:  279:  bool chSysIntegrityCheckI(unsigned testmask);
        -:  280:  void chSysTimerHandlerI(void);
        -:  281:  syssts_t chSysGetStatusAndLockX(void);
        -:  282:  void chSysRestoreStatusX(syssts_t sts);
        -:  283:#if PORT_SUPPORTS_RT
        -:  284:  bool chSysIsCounterWithinX(rtcnt_t cnt, rtcnt_t start, rtcnt_t end);
        -:  285:  void chSysPolledDelayX(rtcnt_t cycles);
        -:  286:#endif
        -:  287:#ifdef __cplusplus
        -:  288:}
        -:  289:#endif
        -:  290:
        -:  291:/*===========================================================================*/
        -:  292:/* Module inline functions.                                                  */
        -:  293:/*===========================================================================*/
        -:  294:
        -:  295:/**
        -:  296: * @brief   Raises the system interrupt priority mask to the maximum level.
        -:  297: * @details All the maskable interrupt sources are disabled regardless their
        -:  298: *          hardware priority.
        -:  299: * @note    Do not invoke this API from within a kernel lock.
        -:  300: *
        -:  301: * @special
        -:  302: */
        -:  303:static inline void chSysDisable(void) {
        -:  304:
        -:  305:  port_disable();
        -:  306:  _dbg_check_disable();
        -:  307:}
        -:  308:
        -:  309:/**
        -:  310: * @brief   Raises the system interrupt priority mask to system level.
        -:  311: * @details The interrupt sources that should not be able to preempt the kernel
        -:  312: *          are disabled, interrupt sources with higher priority are still
        -:  313: *          enabled.
        -:  314: * @note    Do not invoke this API from within a kernel lock.
        -:  315: * @note    This API is no replacement for @p chSysLock(), the @p chSysLock()
        -:  316: *          could do more than just disable the interrupts.
        -:  317: *
        -:  318: * @special
        -:  319: */
        -:  320:static inline void chSysSuspend(void) {
        -:  321:
        -:  322:  port_suspend();
        -:  323:  _dbg_check_suspend();
        -:  324:}
        -:  325:
        -:  326:/**
        -:  327: * @brief   Lowers the system interrupt priority mask to user level.
        -:  328: * @details All the interrupt sources are enabled.
        -:  329: * @note    Do not invoke this API from within a kernel lock.
        -:  330: * @note    This API is no replacement for @p chSysUnlock(), the
        -:  331: *          @p chSysUnlock() could do more than just enable the interrupts.
        -:  332: *
        -:  333: * @special
        -:  334: */
function chSysEnable called 1 returned 100% blocks executed 100%
        1:  335:static inline void chSysEnable(void) {
        -:  336:
        -:  337:  _dbg_check_enable();
        1:  338:  port_enable();
call    0 returned 100%
        1:  339:}
        -:  340:
        -:  341:/**
        -:  342: * @brief   Enters the kernel lock state.
        -:  343: *
        -:  344: * @special
        -:  345: */
function chSysLock called 1 returned 100% blocks executed 100%
function chSysLock called 61454040 returned 100% blocks executed 100%
function chSysLock called 6347867 returned 100% blocks executed 100%
function chSysLock called 23 returned 100% blocks executed 100%
function chSysLock called 95493486 returned 100% blocks executed 100%
function chSysLock called 75355093 returned 100% blocks executed 100%
function chSysLock called 15 returned 100% blocks executed 100%
function chSysLock called 35 returned 100% blocks executed 100%
function chSysLock called 76220250 returned 100% blocks executed 100%
function chSysLock called 16 returned 100% blocks executed 100%
function chSysLock called 36970690 returned 100% blocks executed 100%
function chSysLock called 2 returned 100% blocks executed 100%
function chSysLock called 41 returned 100% blocks executed 100%
351841559:  346:static inline void chSysLock(void)  {
        -:  347:
351841559:  348:  port_lock();
call    0 returned 100%
call    1 returned 100%
call    2 returned 100%
call    3 returned 100%
call    4 returned 100%
call    5 returned 100%
call    6 returned 100%
call    7 returned 100%
call    8 returned 100%
call    9 returned 100%
call   10 returned 100%
call   11 returned 100%
call   12 returned 100%
        -:  349:  _stats_start_measure_crit_thd();
        -:  350:  _dbg_check_lock();
351841559:  351:}
        -:  352:
        -:  353:/**
        -:  354: * @brief   Leaves the kernel lock state.
        -:  355: *
        -:  356: * @special
        -:  357: */
function chSysUnlock called 1 returned 100% blocks executed 83%
function chSysUnlock called 46520837 returned 100% blocks executed 83%
function chSysUnlock called 6347867 returned 100% blocks executed 83%
function chSysUnlock called 23 returned 100% blocks executed 83%
function chSysUnlock called 95493486 returned 100% blocks executed 83%
function chSysUnlock called 75355093 returned 100% blocks executed 83%
function chSysUnlock called 15 returned 100% blocks executed 83%
function chSysUnlock called 35 returned 100% blocks executed 83%
function chSysUnlock called 76220250 returned 100% blocks executed 83%
function chSysUnlock called 16 returned 100% blocks executed 83%
function chSysUnlock called 36970690 returned 100% blocks executed 83%
function chSysUnlock called 2 returned 100% blocks executed 83%
function chSysUnlock called 41 returned 100% blocks executed 83%
336908356:  358:static inline void chSysUnlock(void) {
unconditional  0 taken 100%
unconditional  1 taken 100%
unconditional  2 taken 100%
unconditional  3 taken 100%
unconditional  4 taken 100%
unconditional  5 taken 100%
unconditional  6 taken 100%
unconditional  7 taken 100%
unconditional  8 taken 100%
unconditional  9 taken 100%
unconditional 10 taken 100%
unconditional 11 taken 100%
unconditional 12 taken 100%
        -:  359:
        -:  360:  _dbg_check_unlock();
        -:  361:  _stats_stop_measure_crit_thd();
        -:  362:
        -:  363:  /* The following condition can be triggered by the use of i-class functions
        -:  364:     in a critical section not followed by a chSchResceduleS(), this means
        -:  365:     that the current thread has a lower priority than the next thread in
        -:  366:     the ready list.*/
336908356:  367:  chDbgAssert((ch.rlist.r_queue.p_next == (thread_t *)&ch.rlist.r_queue) ||
branch  0 taken 100% (fallthrough)
branch  1 taken 0%
branch  2 taken 0% (fallthrough)
branch  3 taken 100%
call    4 never executed
unconditional  5 never executed
branch  6 taken 100% (fallthrough)
branch  7 taken 0%
branch  8 taken 0% (fallthrough)
branch  9 taken 100%
call   10 never executed
unconditional 11 never executed
branch 12 taken 100% (fallthrough)
branch 13 taken 0%
branch 14 taken 0% (fallthrough)
branch 15 taken 100%
call   16 never executed
unconditional 17 never executed
branch 18 taken 100% (fallthrough)
branch 19 taken 0%
branch 20 taken 0% (fallthrough)
branch 21 taken 100%
call   22 never executed
unconditional 23 never executed
branch 24 taken 100% (fallthrough)
branch 25 taken 0%
branch 26 taken 0% (fallthrough)
branch 27 taken 100%
call   28 never executed
unconditional 29 never executed
branch 30 taken 100% (fallthrough)
branch 31 taken 0%
branch 32 taken 0% (fallthrough)
branch 33 taken 100%
call   34 never executed
unconditional 35 never executed
branch 36 taken 100% (fallthrough)
branch 37 taken 0%
branch 38 taken 0% (fallthrough)
branch 39 taken 100%
call   40 never executed
unconditional 41 never executed
branch 42 taken 100% (fallthrough)
branch 43 taken 0%
branch 44 taken 0% (fallthrough)
branch 45 taken 100%
call   46 never executed
unconditional 47 never executed
branch 48 taken 100% (fallthrough)
branch 49 taken 0%
branch 50 taken 0% (fallthrough)
branch 51 taken 100%
call   52 never executed
unconditional 53 never executed
branch 54 taken 100% (fallthrough)
branch 55 taken 0%
branch 56 taken 0% (fallthrough)
branch 57 taken 100%
call   58 never executed
unconditional 59 never executed
branch 60 taken 100% (fallthrough)
branch 61 taken 0%
branch 62 taken 0% (fallthrough)
branch 63 taken 100%
call   64 never executed
unconditional 65 never executed
branch 66 taken 100% (fallthrough)
branch 67 taken 0%
branch 68 taken 0% (fallthrough)
branch 69 taken 100%
call   70 never executed
unconditional 71 never executed
branch 72 taken 100% (fallthrough)
branch 73 taken 0%
branch 74 taken 0% (fallthrough)
branch 75 taken 100%
call   76 never executed
unconditional 77 never executed
        -:  368:              (ch.rlist.r_current->p_prio >= ch.rlist.r_queue.p_next->p_prio),
        -:  369:              "priority order violation");
        -:  370:
336908356:  371:  port_unlock();
call    0 returned 100%
call    1 returned 100%
call    2 returned 100%
call    3 returned 100%
call    4 returned 100%
call    5 returned 100%
call    6 returned 100%
call    7 returned 100%
call    8 returned 100%
call    9 returned 100%
call   10 returned 100%
call   11 returned 100%
call   12 returned 100%
336908356:  372:}
        -:  373:
        -:  374:/**
        -:  375: * @brief   Enters the kernel lock state from within an interrupt handler.
        -:  376: * @note    This API may do nothing on some architectures, it is required
        -:  377: *          because on ports that support preemptable interrupt handlers
        -:  378: *          it is required to raise the interrupt mask to the same level of
        -:  379: *          the system mutual exclusion zone.<br>
        -:  380: *          It is good practice to invoke this API before invoking any I-class
        -:  381: *          syscall from an interrupt handler.
        -:  382: * @note    This API must be invoked exclusively from interrupt handlers.
        -:  383: *
        -:  384: * @special
        -:  385: */
function chSysLockFromISR called 73 returned 100% blocks executed 100%
function chSysLockFromISR called 61 returned 100% blocks executed 100%
      134:  386:static inline void chSysLockFromISR(void) {
        -:  387:
      134:  388:  port_lock_from_isr();
call    0 returned 100%
call    1 returned 100%
        -:  389:  _stats_start_measure_crit_isr();
        -:  390:  _dbg_check_lock_from_isr();
      134:  391:}
        -:  392:
        -:  393:/**
        -:  394: * @brief   Leaves the kernel lock state from within an interrupt handler.
        -:  395: *
        -:  396: * @note    This API may do nothing on some architectures, it is required
        -:  397: *          because on ports that support preemptable interrupt handlers
        -:  398: *          it is required to raise the interrupt mask to the same level of
        -:  399: *          the system mutual exclusion zone.<br>
        -:  400: *          It is good practice to invoke this API after invoking any I-class
        -:  401: *          syscall from an interrupt handler.
        -:  402: * @note    This API must be invoked exclusively from interrupt handlers.
        -:  403: *
        -:  404: * @special
        -:  405: */
function chSysUnlockFromISR called 73 returned 100% blocks executed 100%
function chSysUnlockFromISR called 61 returned 100% blocks executed 100%
      134:  406:static inline void chSysUnlockFromISR(void) {
        -:  407:
        -:  408:  _dbg_check_unlock_from_isr();
        -:  409:  _stats_stop_measure_crit_isr();
      134:  410:  port_unlock_from_isr();
call    0 returned 100%
call    1 returned 100%
      134:  411:}
        -:  412:
        -:  413:/**
        -:  414: * @brief   Unconditionally enters the kernel lock state.
        -:  415: * @note    Can be called without previous knowledge of the current lock state.
        -:  416: *          The final state is "s-locked".
        -:  417: *
        -:  418: * @special
        -:  419: */
        -:  420:static inline void chSysUnconditionalLock(void) {
        -:  421:
        -:  422:  if (port_irq_enabled(port_get_irq_status())) {
        -:  423:    chSysLock();
        -:  424:  }
        -:  425:}
        -:  426:
        -:  427:/**
        -:  428: * @brief   Unconditionally leaves the kernel lock state.
        -:  429: * @note    Can be called without previous knowledge of the current lock state.
        -:  430: *          The final state is "normal".
        -:  431: *
        -:  432: * @special
        -:  433: */
        -:  434:static inline void chSysUnconditionalUnlock(void) {
        -:  435:
        -:  436:  if (!port_irq_enabled(port_get_irq_status())) {
        -:  437:    chSysUnlock();
        -:  438:  }
        -:  439:}
        -:  440:
        -:  441:#if (CH_CFG_NO_IDLE_THREAD == FALSE) || defined(__DOXYGEN__)
        -:  442:/**
        -:  443: * @brief   Returns a pointer to the idle thread.
        -:  444: * @pre     In order to use this function the option @p CH_CFG_NO_IDLE_THREAD
        -:  445: *          must be disabled.
        -:  446: * @note    The reference counter of the idle thread is not incremented but
        -:  447: *          it is not strictly required being the idle thread a static
        -:  448: *          object.
        -:  449: *
        -:  450: * @return              Pointer to the idle thread.
        -:  451: *
        -:  452: * @xclass
        -:  453: */
        -:  454:static inline thread_t *chSysGetIdleThreadX(void) {
        -:  455:
        -:  456:  return ch.rlist.r_queue.p_prev;
        -:  457:}
        -:  458:#endif /* CH_CFG_NO_IDLE_THREAD == FALSE */
        -:  459:
        -:  460:#endif /* _CHSYS_H_ */
        -:  461:
        -:  462:/** @} */
