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