        -:    0:Source:../../../os/rt/src/chregistry.c
        -:    0:Programs:14
        -:    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    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:
        -:   48:#include <string.h>
        -:   49:
        -:   50:#include "ch.h"
        -:   51:
        -:   52:#if (CH_CFG_USE_REGISTRY == TRUE) || defined(__DOXYGEN__)
        -:   53:
        -:   54:/*===========================================================================*/
        -:   55:/* Module exported variables.                                                */
        -:   56:/*===========================================================================*/
        -:   57:
        -:   58:/*===========================================================================*/
        -:   59:/* Module local types.                                                       */
        -:   60:/*===========================================================================*/
        -:   61:
        -:   62:/*===========================================================================*/
        -:   63:/* Module local variables.                                                   */
        -:   64:/*===========================================================================*/
        -:   65:
        -:   66:/*===========================================================================*/
        -:   67:/* Module local functions.                                                   */
        -:   68:/*===========================================================================*/
        -:   69:
        -:   70:#define _offsetof(st, m)                                                    \
        -:   71:  /*lint -save -e9005 -e9033 -e413 [11.8, 10.8 1.3] Normal pointers
        -:   72:    arithmetic, it is safe.*/                                               \
        -:   73:  ((size_t)((char *)&((st *)0)->m - (char *)0))                             \
        -:   74:  /*lint -restore*/
        -:   75:
        -:   76:/*===========================================================================*/
        -:   77:/* Module exported functions.                                                */
        -:   78:/*===========================================================================*/
        -:   79:
        -:   80:/*
        -:   81: * OS signature in ROM plus debug-related information.
        -:   82: */
        -:   83:ROMCONST chdebug_t ch_debug = {
        -:   84:  {'m', 'a', 'i', 'n'},
        -:   85:  (uint8_t)0,
        -:   86:  (uint8_t)sizeof (chdebug_t),
        -:   87:  (uint16_t)(((unsigned)CH_KERNEL_MAJOR << 11U) |
        -:   88:             ((unsigned)CH_KERNEL_MINOR << 6U) |
        -:   89:             ((unsigned)CH_KERNEL_PATCH << 0U)),
        -:   90:  (uint8_t)sizeof (void *),
        -:   91:  (uint8_t)sizeof (systime_t),
        -:   92:  (uint8_t)sizeof (thread_t),
        -:   93:  (uint8_t)_offsetof(thread_t, prio),
        -:   94:  (uint8_t)_offsetof(thread_t, ctx),
        -:   95:  (uint8_t)_offsetof(thread_t, newer),
        -:   96:  (uint8_t)_offsetof(thread_t, older),
        -:   97:  (uint8_t)_offsetof(thread_t, name),
        -:   98:#if (CH_DBG_ENABLE_STACK_CHECK == TRUE) || (CH_CFG_USE_DYNAMIC == TRUE)
        -:   99:  (uint8_t)_offsetof(thread_t, wabase),
        -:  100:#else
        -:  101:  (uint8_t)0,
        -:  102:#endif
        -:  103:  (uint8_t)_offsetof(thread_t, state),
        -:  104:  (uint8_t)_offsetof(thread_t, flags),
        -:  105:#if CH_CFG_USE_DYNAMIC == TRUE
        -:  106:  (uint8_t)_offsetof(thread_t, refs),
        -:  107:#else
        -:  108:  (uint8_t)0,
        -:  109:#endif
        -:  110:#if CH_CFG_TIME_QUANTUM > 0
        -:  111:  (uint8_t)_offsetof(thread_t, preempt),
        -:  112:#else
        -:  113:  (uint8_t)0,
        -:  114:#endif
        -:  115:#if CH_DBG_THREADS_PROFILING == TRUE
        -:  116:  (uint8_t)_offsetof(thread_t, time)
        -:  117:#else
        -:  118:  (uint8_t)0
        -:  119:#endif
        -:  120:};
        -:  121:
        -:  122:/**
        -:  123: * @brief   Returns the first thread in the system.
        -:  124: * @details Returns the most ancient thread in the system, usually this is
        -:  125: *          the main thread unless it terminated. A reference is added to the
        -:  126: *          returned thread in order to make sure its status is not lost.
        -:  127: * @note    This function cannot return @p NULL because there is always at
        -:  128: *          least one thread in the system.
        -:  129: *
        -:  130: * @return              A reference to the most ancient thread.
        -:  131: *
        -:  132: * @api
        -:  133: */
function chRegFirstThread called 0 returned 0% blocks executed 0%
    #####:  134:thread_t *chRegFirstThread(void) {
        -:  135:  thread_t *tp;
        -:  136:
    #####:  137:  chSysLock();
call    0 never executed
    #####:  138:  tp = ch.rlist.newer;
        -:  139:#if CH_CFG_USE_DYNAMIC == TRUE
    #####:  140:  tp->refs++;
        -:  141:#endif
    #####:  142:  chSysUnlock();
call    0 never executed
        -:  143:
    #####:  144:  return tp;
unconditional  0 never executed
        -:  145:}
        -:  146:
        -:  147:/**
        -:  148: * @brief   Returns the thread next to the specified one.
        -:  149: * @details The reference counter of the specified thread is decremented and
        -:  150: *          the reference counter of the returned thread is incremented.
        -:  151: *
        -:  152: * @param[in] tp        pointer to the thread
        -:  153: * @return              A reference to the next thread.
        -:  154: * @retval NULL         if there is no next thread.
        -:  155: *
        -:  156: * @api
        -:  157: */
function chRegNextThread called 0 returned 0% blocks executed 0%
    #####:  158:thread_t *chRegNextThread(thread_t *tp) {
        -:  159:  thread_t *ntp;
        -:  160:
    #####:  161:  chSysLock();
call    0 never executed
    #####:  162:  ntp = tp->newer;
        -:  163:  /*lint -save -e9087 -e740 [11.3, 1.3] Cast required by list handling.*/
    #####:  164:  if (ntp == (thread_t *)&ch.rlist) {
branch  0 never executed
branch  1 never executed
        -:  165:  /*lint -restore*/
    #####:  166:    ntp = NULL;
unconditional  0 never executed
        -:  167:  }
        -:  168:#if CH_CFG_USE_DYNAMIC == TRUE
        -:  169:  else {
        -:  170:    chDbgAssert(ntp->refs < (trefs_t)255, "too many references");
    #####:  171:    ntp->refs++;
unconditional  0 never executed
        -:  172:  }
        -:  173:#endif
    #####:  174:  chSysUnlock();
call    0 never executed
        -:  175:#if CH_CFG_USE_DYNAMIC == TRUE
    #####:  176:  chThdRelease(tp);
call    0 never executed
        -:  177:#endif
        -:  178:
    #####:  179:  return ntp;
unconditional  0 never executed
        -:  180:}
        -:  181:
        -:  182:/**
        -:  183: * @brief   Retrieves a thread pointer by name.
        -:  184: * @note    The reference counter of the found thread is increased by one so
        -:  185: *          it cannot be disposed incidentally after the pointer has been
        -:  186: *          returned.
        -:  187: *
        -:  188: * @param[in] name      the thread name
        -:  189: * @return              A pointer to the found thread.
        -:  190: * @retval NULL         if a matching thread has not been found.
        -:  191: *
        -:  192: * @api
        -:  193: */
function chRegFindThreadByName called 0 returned 0% blocks executed 0%
    #####:  194:thread_t *chRegFindThreadByName(const char *name) {
        -:  195:  thread_t *ctp;
        -:  196:
        -:  197:  /* Scanning registry.*/
    #####:  198:  ctp = chRegFirstThread();
call    0 never executed
unconditional  1 never executed
        -:  199:  do {
    #####:  200:    if (strcmp(chRegGetThreadNameX(ctp), name) == 0) {
call    0 never executed
branch  1 never executed
branch  2 never executed
    #####:  201:      return ctp;
unconditional  0 never executed
        -:  202:    }
    #####:  203:    ctp = chRegNextThread(ctp);
call    0 never executed
    #####:  204:  } while (ctp != NULL);
branch  0 never executed
branch  1 never executed
        -:  205:
    #####:  206:  return NULL;
unconditional  0 never executed
        -:  207:}
        -:  208:
        -:  209:/**
        -:  210: * @brief   Confirms that a pointer is a valid thread pointer.
        -:  211: * @note    The reference counter of the found thread is increased by one so
        -:  212: *          it cannot be disposed incidentally after the pointer has been
        -:  213: *          returned.
        -:  214: *
        -:  215: * @param[in] tp        pointer to the thread
        -:  216: * @return              A pointer to the found thread.
        -:  217: * @retval NULL         if a matching thread has not been found.
        -:  218: *
        -:  219: * @api
        -:  220: */
function chRegFindThreadByPointer called 0 returned 0% blocks executed 0%
    #####:  221:thread_t *chRegFindThreadByPointer(thread_t *tp) {
        -:  222:  thread_t *ctp;
        -:  223:
        -:  224:  /* Scanning registry.*/
    #####:  225:  ctp = chRegFirstThread();
call    0 never executed
unconditional  1 never executed
        -:  226:  do {
    #####:  227:    if (ctp == tp) {
branch  0 never executed
branch  1 never executed
    #####:  228:      return ctp;
unconditional  0 never executed
        -:  229:    }
    #####:  230:    ctp = chRegNextThread(ctp);
call    0 never executed
    #####:  231:  } while (ctp != NULL);
branch  0 never executed
branch  1 never executed
        -:  232:
    #####:  233:  return NULL;
unconditional  0 never executed
        -:  234:}
        -:  235:
        -:  236:#if (CH_DBG_ENABLE_STACK_CHECK == TRUE) || (CH_CFG_USE_DYNAMIC == TRUE) ||  \
        -:  237:    defined(__DOXYGEN__)
        -:  238:/**
        -:  239: * @brief   Confirms that a working area is being used by some active thread.
        -:  240: * @note    The reference counter of the found thread is increased by one so
        -:  241: *          it cannot be disposed incidentally after the pointer has been
        -:  242: *          returned.
        -:  243: *
        -:  244: * @param[in] wa        pointer to a static working area
        -:  245: * @return              A pointer to the found thread.
        -:  246: * @retval NULL         if a matching thread has not been found.
        -:  247: *
        -:  248: * @api
        -:  249: */
function chRegFindThreadByWorkingArea called 0 returned 0% blocks executed 0%
    #####:  250:thread_t *chRegFindThreadByWorkingArea(stkalign_t *wa) {
        -:  251:  thread_t *ctp;
        -:  252:
        -:  253:  /* Scanning registry.*/
    #####:  254:  ctp = chRegFirstThread();
call    0 never executed
unconditional  1 never executed
        -:  255:  do {
    #####:  256:    if (chThdGetWorkingAreaX(ctp) == wa) {
call    0 never executed
branch  1 never executed
branch  2 never executed
    #####:  257:      return ctp;
unconditional  0 never executed
        -:  258:    }
    #####:  259:    ctp = chRegNextThread(ctp);
call    0 never executed
    #####:  260:  } while (ctp != NULL);
branch  0 never executed
branch  1 never executed
        -:  261:
    #####:  262:  return NULL;
unconditional  0 never executed
        -:  263:}
        -:  264:#endif
        -:  265:
        -:  266:#endif /* CH_CFG_USE_REGISTRY == TRUE */
        -:  267:
        -:  268:/** @} */
