        -:    0:Source:../../../os/rt/src/chregistry.c
        -:    0:Programs:15
        -:    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    chregistry.c
        -:   22: * @brief   Threads registry code.
        -:   23: *
        -:   24: * @addtogroup registry
        -:   25: * @details Threads Registry related APIs and services.
        -:   26: *          <h2>Operation mode</h2>
        -:   27: *          The Threads Registry is a double linked list that holds all the
        -:   28: *          active threads in the system.<br>
        -:   29: *          Operations defined for the registry:
        -:   30: *          - <b>First</b>, returns the first, in creation order, active thread
        -:   31: *            in the system.
        -:   32: *          - <b>Next</b>, returns the next, in creation order, active thread
        -:   33: *            in the system.
        -:   34: *          .
        -:   35: *          The registry is meant to be mainly a debug feature, for example,
        -:   36: *          using the registry a debugger can enumerate the active threads
        -:   37: *          in any given moment or the shell can print the active threads
        -:   38: *          and their state.<br>
        -:   39: *          Another possible use is for centralized threads memory management,
        -:   40: *          terminating threads can pulse an event source and an event handler
        -:   41: *          can perform a scansion of the registry in order to recover the
        -:   42: *          memory.
        -:   43: * @pre     In order to use the threads registry the @p CH_CFG_USE_REGISTRY
        -:   44: *          option must be enabled in @p chconf.h.
        -:   45: * @{
        -:   46: */
        -:   47:#include "ch.h"
        -:   48:
        -:   49:#if (CH_CFG_USE_REGISTRY == TRUE) || defined(__DOXYGEN__)
        -:   50:
        -:   51:/*===========================================================================*/
        -:   52:/* Module exported variables.                                                */
        -:   53:/*===========================================================================*/
        -:   54:
        -:   55:/*===========================================================================*/
        -:   56:/* Module local types.                                                       */
        -:   57:/*===========================================================================*/
        -:   58:
        -:   59:/*===========================================================================*/
        -:   60:/* Module local variables.                                                   */
        -:   61:/*===========================================================================*/
        -:   62:
        -:   63:/*===========================================================================*/
        -:   64:/* Module local functions.                                                   */
        -:   65:/*===========================================================================*/
        -:   66:
        -:   67:#define _offsetof(st, m)                                                    \
        -:   68:  /*lint -save -e9005 -e9033 -e413 [11.8, 10.8 1.3] Normal pointers
        -:   69:    arithmetic, it is safe.*/                                               \
        -:   70:  ((size_t)((char *)&((st *)0)->m - (char *)0))                             \
        -:   71:  /*lint -restore*/
        -:   72:
        -:   73:/*===========================================================================*/
        -:   74:/* Module exported functions.                                                */
        -:   75:/*===========================================================================*/
        -:   76:
        -:   77:/*
        -:   78: * OS signature in ROM plus debug-related information.
        -:   79: */
        -:   80:ROMCONST chdebug_t ch_debug = {
        -:   81:  {'m', 'a', 'i', 'n'},
        -:   82:  (uint8_t)0,
        -:   83:  (uint8_t)sizeof (chdebug_t),
        -:   84:  (uint16_t)(((unsigned)CH_KERNEL_MAJOR << 11U) |
        -:   85:             ((unsigned)CH_KERNEL_MINOR << 6U) |
        -:   86:             ((unsigned)CH_KERNEL_PATCH << 0U)),
        -:   87:  (uint8_t)sizeof (void *),
        -:   88:  (uint8_t)sizeof (systime_t),
        -:   89:  (uint8_t)sizeof (thread_t),
        -:   90:  (uint8_t)_offsetof(thread_t, p_prio),
        -:   91:  (uint8_t)_offsetof(thread_t, p_ctx),
        -:   92:  (uint8_t)_offsetof(thread_t, p_newer),
        -:   93:  (uint8_t)_offsetof(thread_t, p_older),
        -:   94:  (uint8_t)_offsetof(thread_t, p_name),
        -:   95:#if CH_DBG_ENABLE_STACK_CHECK == TRUE
        -:   96:  (uint8_t)_offsetof(thread_t, p_stklimit),
        -:   97:#else
        -:   98:  (uint8_t)0,
        -:   99:#endif
        -:  100:  (uint8_t)_offsetof(thread_t, p_state),
        -:  101:  (uint8_t)_offsetof(thread_t, p_flags),
        -:  102:#if CH_CFG_USE_DYNAMIC == TRUE
        -:  103:  (uint8_t)_offsetof(thread_t, p_refs),
        -:  104:#else
        -:  105:  (uint8_t)0,
        -:  106:#endif
        -:  107:#if CH_CFG_TIME_QUANTUM > 0
        -:  108:  (uint8_t)_offsetof(thread_t, p_preempt),
        -:  109:#else
        -:  110:  (uint8_t)0,
        -:  111:#endif
        -:  112:#if CH_DBG_THREADS_PROFILING == TRUE
        -:  113:  (uint8_t)_offsetof(thread_t, p_time)
        -:  114:#else
        -:  115:  (uint8_t)0
        -:  116:#endif
        -:  117:};
        -:  118:
        -:  119:/**
        -:  120: * @brief   Returns the first thread in the system.
        -:  121: * @details Returns the most ancient thread in the system, usually this is
        -:  122: *          the main thread unless it terminated. A reference is added to the
        -:  123: *          returned thread in order to make sure its status is not lost.
        -:  124: * @note    This function cannot return @p NULL because there is always at
        -:  125: *          least one thread in the system.
        -:  126: *
        -:  127: * @return              A reference to the most ancient thread.
        -:  128: *
        -:  129: * @api
        -:  130: */
function chRegFirstThread called 6 returned 100% blocks executed 100%
        6:  131:thread_t *chRegFirstThread(void) {
        -:  132:  thread_t *tp;
        -:  133:
        6:  134:  chSysLock();
call    0 returned 100%
        6:  135:  tp = ch.rlist.r_newer;
        -:  136:#if CH_CFG_USE_DYNAMIC == TRUE
        6:  137:  tp->p_refs++;
        -:  138:#endif
        6:  139:  chSysUnlock();
call    0 returned 100%
        -:  140:
        6:  141:  return tp;
unconditional  0 taken 100%
        -:  142:}
        -:  143:
        -:  144:/**
        -:  145: * @brief   Returns the thread next to the specified one.
        -:  146: * @details The reference counter of the specified thread is decremented and
        -:  147: *          the reference counter of the returned thread is incremented.
        -:  148: *
        -:  149: * @param[in] tp        pointer to the thread
        -:  150: * @return              A reference to the next thread.
        -:  151: * @retval NULL         if there is no next thread.
        -:  152: *
        -:  153: * @api
        -:  154: */
function chRegNextThread called 17 returned 100% blocks executed 100%
       17:  155:thread_t *chRegNextThread(thread_t *tp) {
        -:  156:  thread_t *ntp;
        -:  157:
       17:  158:  chSysLock();
call    0 returned 100%
       17:  159:  ntp = tp->p_newer;
        -:  160:  /*lint -save -e9087 -e740 [11.3, 1.3] Cast required by list handling.*/
       17:  161:  if (ntp == (thread_t *)&ch.rlist) {
branch  0 taken 35% (fallthrough)
branch  1 taken 65%
        -:  162:  /*lint -restore*/
        6:  163:    ntp = NULL;
unconditional  0 taken 100%
        -:  164:  }
        -:  165:#if CH_CFG_USE_DYNAMIC == TRUE
        -:  166:  else {
        -:  167:    chDbgAssert(ntp->p_refs < (trefs_t)255, "too many references");
       11:  168:    ntp->p_refs++;
unconditional  0 taken 100%
        -:  169:  }
        -:  170:#endif
       17:  171:  chSysUnlock();
call    0 returned 100%
        -:  172:#if CH_CFG_USE_DYNAMIC == TRUE
       17:  173:  chThdRelease(tp);
call    0 returned 100%
        -:  174:#endif
        -:  175:
       17:  176:  return ntp;
unconditional  0 taken 100%
        -:  177:}
        -:  178:
        -:  179:#endif /* CH_CFG_USE_REGISTRY == TRUE */
        -:  180:
        -:  181:/** @} */
