The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/ddb/db_task_thread.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* 
    2  * Mach Operating System
    3  * Copyright (c) 1993,1992,1991,1990 Carnegie Mellon University
    4  * All Rights Reserved.
    5  * 
    6  * Permission to use, copy, modify and distribute this software and its
    7  * documentation is hereby granted, provided that both the copyright
    8  * notice and this permission notice appear in all copies of the
    9  * software, derivative works or modified versions, and any portions
   10  * thereof, and that both notices appear in supporting documentation.
   11  * 
   12  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
   13  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
   14  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   15  * 
   16  * Carnegie Mellon requests users of this software to return to
   17  * 
   18  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   19  *  School of Computer Science
   20  *  Carnegie Mellon University
   21  *  Pittsburgh PA 15213-3890
   22  * 
   23  * any improvements or extensions that they make and grant Carnegie Mellon
   24  * the rights to redistribute these changes.
   25  */
   26 /*
   27  * HISTORY
   28  * $Log:        db_task_thread.c,v $
   29  * Revision 2.6  93/11/17  16:25:42  dbg
   30  *      Added include of kern/processor.h.
   31  *      [93/04/10            dbg]
   32  * 
   33  * Revision 2.5  93/01/14  17:25:54  danner
   34  *      Removed `static' from db_lookup_task_id so can be used elsewhere.
   35  *      [92/12/02            jfriedl]
   36  *      64bit cleanup.
   37  *      [92/11/30            af]
   38  * 
   39  * Revision 2.4  92/08/03  17:32:11  jfriedl
   40  *      removed silly prototypes
   41  *      [92/08/02            jfriedl]
   42  * 
   43  * Revision 2.3  92/05/21  17:07:54  jfriedl
   44  *      tried prototypes.
   45  *      [92/05/20            jfriedl]
   46  * 
   47  * Revision 2.2  91/10/09  16:03:04  af
   48  *      Created for task/thread handling.
   49  *      [91/08/29            tak]
   50  * 
   51  */
   52 
   53 #include <machine/db_machdep.h>
   54 #include <ddb/db_command.h>
   55 #include <ddb/db_lex.h>
   56 #include <ddb/db_output.h>
   57 #include <ddb/db_task_thread.h>
   58 #include <ddb/db_variables.h>
   59 
   60 #include <kern/processor.h>
   61 
   62 
   63 /*
   64  * Following constants are used to prevent infinite loop of task
   65  * or thread search due to the incorrect list.
   66  */
   67 #define DB_MAX_TASKID   0x10000         /* max # of tasks */
   68 #define DB_MAX_THREADID 0x10000         /* max # of threads in a task */
   69 #define DB_MAX_PSETS    0x10000         /* max # of processor sets */
   70 
   71 task_t          db_default_task;        /* default target task */
   72 thread_t        db_default_thread;      /* default target thread */
   73 
   74 /*
   75  * search valid task queue, and return the queue position as the task id
   76  */
   77 int
   78 db_lookup_task(
   79         task_t target_task)
   80 {
   81         register task_t task;
   82         register task_id;
   83         register processor_set_t pset;
   84         register int npset = 0;
   85 
   86         task_id = 0;
   87         if (queue_first(&all_psets) == 0)
   88             return -1;
   89         queue_iterate(&all_psets, pset, processor_set_t, all_psets) {
   90             if (npset++ >= DB_MAX_PSETS)
   91                 return -1;
   92             if (queue_first(&pset->tasks) == 0)
   93                 continue;
   94             queue_iterate(&pset->tasks, task, task_t, pset_tasks) {
   95                 if (target_task == task)
   96                     return task_id;
   97                 if (task_id++ >= DB_MAX_TASKID)
   98                     return -1;
   99             }
  100         }
  101         return -1;
  102 }
  103 
  104 /*
  105  * search thread queue of the task, and return the queue position
  106  */
  107 int
  108 db_lookup_task_thread(
  109         task_t   task,
  110         thread_t target_thread)
  111 {
  112         register thread_t thread;
  113         register thread_id;
  114 
  115         thread_id = 0;
  116         if (queue_first(&task->thread_list) == 0)
  117             return -1;
  118         queue_iterate(&task->thread_list, thread, thread_t, thread_list) {
  119             if (target_thread == thread)
  120                 return thread_id;
  121             if (thread_id++ >= DB_MAX_THREADID)
  122                 return -1;
  123         }
  124         return -1;
  125 }
  126 
  127 /*
  128  * search thread queue of every valid task, and return the queue position
  129  * as the thread id.
  130  */
  131 int
  132 db_lookup_thread(
  133         thread_t target_thread)
  134 {
  135         register thread_id;
  136         register task_t task;
  137         register processor_set_t pset;
  138         register ntask = 0;
  139         register npset = 0;
  140 
  141         if (queue_first(&all_psets) == 0)
  142             return -1;
  143         queue_iterate(&all_psets, pset, processor_set_t, all_psets) {
  144             if (npset++ >= DB_MAX_PSETS)
  145                 return -1;
  146             if (queue_first(&pset->tasks) == 0)
  147                 continue;
  148             queue_iterate(&pset->tasks, task, task_t, pset_tasks) {
  149                 if (ntask++ > DB_MAX_TASKID)
  150                     return -1;
  151                 if (task->thread_count == 0)
  152                     continue;
  153                 thread_id = db_lookup_task_thread(task, target_thread);
  154                 if (thread_id >= 0)
  155                     return thread_id;
  156             }
  157         }
  158         return -1;
  159 }
  160 
  161 /*
  162  * check the address is a valid thread address
  163  */
  164 boolean_t
  165 db_check_thread_address_valid(
  166         db_addr_t       address)
  167 {
  168         if (db_lookup_thread((thread_t) address) < 0) {
  169             db_printf("Bad thread address %#x\n", address);
  170             db_flush_lex();
  171             return FALSE;
  172         } else
  173             return TRUE;
  174 }
  175 
  176 /*
  177  * convert task_id(queue postion) to task address
  178  */
  179 task_t
  180 db_lookup_task_id(
  181         register int task_id)
  182 {
  183         register task_t task;
  184         register processor_set_t pset;
  185         register int npset = 0;
  186 
  187         if (task_id > DB_MAX_TASKID)
  188             return TASK_NULL;
  189         if (queue_first(&all_psets) == 0)
  190             return TASK_NULL;
  191         queue_iterate(&all_psets, pset, processor_set_t, all_psets) {
  192             if (npset++ >= DB_MAX_PSETS)
  193                 return TASK_NULL;
  194             if (queue_first(&pset->tasks) == 0)
  195                 continue;
  196             queue_iterate(&pset->tasks, task, task_t, pset_tasks) {
  197                 if (task_id-- <= 0)
  198                         return task;
  199             }
  200         }
  201         return TASK_NULL;
  202 }
  203 
  204 /*
  205  * convert (task_id, thread_id) pair to thread address
  206  */
  207 static thread_t
  208 db_lookup_thread_id(
  209         task_t   task,
  210         register int thread_id)
  211 {
  212         register thread_t thread;
  213 
  214         
  215         if (thread_id > DB_MAX_THREADID)
  216             return THREAD_NULL;
  217         if (queue_first(&task->thread_list) == 0)
  218             return THREAD_NULL;
  219         queue_iterate(&task->thread_list, thread, thread_t, thread_list) {
  220             if (thread_id-- <= 0)
  221                 return thread;
  222         }
  223         return THREAD_NULL;
  224 }
  225 
  226 /*
  227  * get next parameter from a command line, and check it as a valid
  228  * thread address
  229  */
  230 boolean_t
  231 db_get_next_thread(
  232         thread_t        *threadp,
  233         int             position)
  234 {
  235         db_expr_t       value;
  236         thread_t        thread;
  237 
  238         *threadp = THREAD_NULL;
  239         if (db_expression(&value)) {
  240             if (!db_check_thread_address_valid(value)) {
  241                 db_flush_lex();
  242                 return FALSE;
  243             }
  244             thread = (thread_t) value;
  245         } else if (position <= 0) {
  246             thread = db_default_thread;
  247         } else
  248             return FALSE;
  249         *threadp = thread;
  250         return TRUE;
  251 }
  252 
  253 /*
  254  * check the default thread is still valid
  255  *      ( it is called in entering DDB session )
  256  */
  257 void
  258 db_init_default_thread(void)
  259 {
  260         if (db_lookup_thread(db_default_thread) < 0) {
  261             db_default_thread = THREAD_NULL;
  262             db_default_task = TASK_NULL;
  263         } else
  264             db_default_task = db_default_thread->task;
  265 }
  266 
  267 /*
  268  * set or get default thread which is used when /t or :t option is specified
  269  * in the command line
  270  */
  271 /* ARGSUSED */
  272 void
  273 db_set_default_thread(
  274         struct db_variable *vp,
  275         db_expr_t       *valuep,
  276         int             flag,
  277         db_var_aux_param_t ap)
  278 {
  279         thread_t        thread;
  280 
  281         if (flag != DB_VAR_SET) {
  282             *valuep = (db_expr_t) db_default_thread;
  283             return;
  284         }
  285         thread = (thread_t) *valuep;
  286         if (thread != THREAD_NULL &&
  287             !db_check_thread_address_valid((db_expr_t)thread))
  288         {
  289             db_error(0);
  290             /* NOTREACHED */
  291         }
  292         db_default_thread = thread;
  293         if (thread)
  294                 db_default_task = thread->task;
  295 }
  296 
  297 /*
  298  * convert $taskXXX[.YYY] type DDB variable to task or thread address
  299  */
  300 void
  301 db_get_task_thread(
  302         struct db_variable      *vp,
  303         db_expr_t               *valuep,
  304         int                     flag,
  305         db_var_aux_param_t      ap)
  306 {
  307         task_t   task;
  308         thread_t thread;
  309 
  310         if (flag != DB_VAR_GET) {
  311             db_error("Cannot set to $task variable\n");
  312             /* NOTREACHED */
  313         }
  314         if ((task = db_lookup_task_id(ap->suffix[0])) == TASK_NULL) {
  315             db_printf("no such task($task%d)\n", ap->suffix[0]);
  316             db_error(0);
  317             /* NOTREACHED */
  318         }
  319         if (ap->level <= 1) {
  320             *valuep = (db_expr_t) task;
  321             return;
  322         }
  323         if ((thread = db_lookup_thread_id(task, ap->suffix[1])) == THREAD_NULL){
  324             db_printf("no such thread($task%d.%d)\n", 
  325                                         ap->suffix[0], ap->suffix[1]);
  326             db_error(0);
  327             /* NOTREACHED */
  328         }
  329         *valuep = (db_expr_t) thread;
  330 }

Cache object: 20934ee66cbe4ae85cfb2a94730b0976


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.