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) 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.5  93/01/14  17:25:54  danner
   30  *      Removed `static' from db_lookup_task_id so can be used elsewhere.
   31  *      [92/12/02            jfriedl]
   32  *      64bit cleanup.
   33  *      [92/11/30            af]
   34  * 
   35  * Revision 2.4  92/08/03  17:32:11  jfriedl
   36  *      removed silly prototypes
   37  *      [92/08/02            jfriedl]
   38  * 
   39  * Revision 2.3  92/05/21  17:07:54  jfriedl
   40  *      tried prototypes.
   41  *      [92/05/20            jfriedl]
   42  * 
   43  * Revision 2.2  91/10/09  16:03:04  af
   44  *      Created for task/thread handling.
   45  *      [91/08/29            tak]
   46  * 
   47  */
   48 
   49 #include <machine/db_machdep.h>
   50 #include <ddb/db_task_thread.h>
   51 #include <ddb/db_variables.h>
   52 
   53 
   54 
   55 /*
   56  * Following constants are used to prevent infinite loop of task
   57  * or thread search due to the incorrect list.
   58  */
   59 #define DB_MAX_TASKID   0x10000         /* max # of tasks */
   60 #define DB_MAX_THREADID 0x10000         /* max # of threads in a task */
   61 #define DB_MAX_PSETS    0x10000         /* max # of processor sets */
   62 
   63 task_t          db_default_task;        /* default target task */
   64 thread_t        db_default_thread;      /* default target thread */
   65 
   66 /*
   67  * search valid task queue, and return the queue position as the task id
   68  */
   69 int
   70 db_lookup_task(target_task)
   71         task_t target_task;
   72 {
   73         register task_t task;
   74         register task_id;
   75         register processor_set_t pset;
   76         register npset = 0;
   77 
   78         task_id = 0;
   79         if (queue_first(&all_psets) == 0)
   80             return(-1);
   81         queue_iterate(&all_psets, pset, processor_set_t, all_psets) {
   82             if (npset++ >= DB_MAX_PSETS)
   83                 return(-1);
   84             if (queue_first(&pset->tasks) == 0)
   85                 continue;
   86             queue_iterate(&pset->tasks, task, task_t, pset_tasks) {
   87                 if (target_task == task)
   88                     return(task_id);
   89                 if (task_id++ >= DB_MAX_TASKID)
   90                     return(-1);
   91             }
   92         }
   93         return(-1);
   94 }
   95 
   96 /*
   97  * search thread queue of the task, and return the queue position
   98  */
   99 int
  100 db_lookup_task_thread(task, target_thread)
  101         task_t   task;
  102         thread_t target_thread;
  103 {
  104         register thread_t thread;
  105         register thread_id;
  106 
  107         thread_id = 0;
  108         if (queue_first(&task->thread_list) == 0)
  109             return(-1);
  110         queue_iterate(&task->thread_list, thread, thread_t, thread_list) {
  111             if (target_thread == thread)
  112                 return(thread_id);
  113             if (thread_id++ >= DB_MAX_THREADID)
  114                 return(-1);
  115         }
  116         return(-1);
  117 }
  118 
  119 /*
  120  * search thread queue of every valid task, and return the queue position
  121  * as the thread id.
  122  */
  123 int
  124 db_lookup_thread(target_thread)
  125         thread_t target_thread;
  126 {
  127         register thread_id;
  128         register task_t task;
  129         register processor_set_t pset;
  130         register ntask = 0;
  131         register npset = 0;
  132 
  133         if (queue_first(&all_psets) == 0)
  134             return(-1);
  135         queue_iterate(&all_psets, pset, processor_set_t, all_psets) {
  136             if (npset++ >= DB_MAX_PSETS)
  137                 return(-1);
  138             if (queue_first(&pset->tasks) == 0)
  139                 continue;
  140             queue_iterate(&pset->tasks, task, task_t, pset_tasks) {
  141                 if (ntask++ > DB_MAX_TASKID)
  142                     return(-1);
  143                 if (task->thread_count == 0)
  144                     continue;
  145                 thread_id = db_lookup_task_thread(task, target_thread);
  146                 if (thread_id >= 0)
  147                     return(thread_id);
  148             }
  149         }
  150         return(-1);
  151 }
  152 
  153 /*
  154  * check the address is a valid thread address
  155  */
  156 boolean_t
  157 db_check_thread_address_valid(thread)
  158         thread_t thread;
  159 {
  160         if (db_lookup_thread(thread) < 0) {
  161             db_printf("Bad thread address 0x%x\n", thread);
  162             db_flush_lex();
  163             return(FALSE);
  164         } else
  165             return(TRUE);
  166 }
  167 
  168 /*
  169  * convert task_id(queue postion) to task address
  170  */
  171 task_t
  172 db_lookup_task_id(task_id)
  173         register task_id;
  174 {
  175         register task_t task;
  176         register processor_set_t pset;
  177         register npset = 0;
  178 
  179         if (task_id > DB_MAX_TASKID)
  180             return(TASK_NULL);
  181         if (queue_first(&all_psets) == 0)
  182             return(TASK_NULL);
  183         queue_iterate(&all_psets, pset, processor_set_t, all_psets) {
  184             if (npset++ >= DB_MAX_PSETS)
  185                 return(TASK_NULL);
  186             if (queue_first(&pset->tasks) == 0)
  187                 continue;
  188             queue_iterate(&pset->tasks, task, task_t, pset_tasks) {
  189                 if (task_id-- <= 0)
  190                         return(task);
  191             }
  192         }
  193         return(TASK_NULL);
  194 }
  195 
  196 /*
  197  * convert (task_id, thread_id) pair to thread address
  198  */
  199 static thread_t
  200 db_lookup_thread_id(task, thread_id)
  201         task_t   task;
  202         register thread_id;
  203 {
  204         register thread_t thread;
  205 
  206         
  207         if (thread_id > DB_MAX_THREADID)
  208             return(THREAD_NULL);
  209         if (queue_first(&task->thread_list) == 0)
  210             return(THREAD_NULL);
  211         queue_iterate(&task->thread_list, thread, thread_t, thread_list) {
  212             if (thread_id-- <= 0)
  213                 return(thread);
  214         }
  215         return(THREAD_NULL);
  216 }
  217 
  218 /*
  219  * get next parameter from a command line, and check it as a valid
  220  * thread address
  221  */
  222 boolean_t
  223 db_get_next_thread(threadp, position)
  224         thread_t        *threadp;
  225         int             position;
  226 {
  227         db_expr_t       value;
  228         thread_t        thread;
  229 
  230         *threadp = THREAD_NULL;
  231         if (db_expression(&value)) {
  232             thread = (thread_t) value;
  233             if (!db_check_thread_address_valid(thread)) {
  234                 db_flush_lex();
  235                 return(FALSE);
  236             }
  237         } else if (position <= 0) {
  238             thread = db_default_thread;
  239         } else
  240             return(FALSE);
  241         *threadp = thread;
  242         return(TRUE);
  243 }
  244 
  245 /*
  246  * check the default thread is still valid
  247  *      ( it is called in entering DDB session )
  248  */
  249 void
  250 db_init_default_thread()
  251 {
  252         if (db_lookup_thread(db_default_thread) < 0) {
  253             db_default_thread = THREAD_NULL;
  254             db_default_task = TASK_NULL;
  255         } else
  256             db_default_task = db_default_thread->task;
  257 }
  258 
  259 /*
  260  * set or get default thread which is used when /t or :t option is specified
  261  * in the command line
  262  */
  263 /* ARGSUSED */
  264 int
  265 db_set_default_thread(vp, valuep, flag)
  266         struct db_variable *vp;
  267         db_expr_t       *valuep;
  268         int             flag;
  269 {
  270         thread_t        thread;
  271 
  272         if (flag != DB_VAR_SET) {
  273             *valuep = (db_expr_t) db_default_thread;
  274             return(0);
  275         }
  276         thread = (thread_t) *valuep;
  277         if (thread != THREAD_NULL && !db_check_thread_address_valid(thread))
  278             db_error(0);
  279             /* NOTREACHED */
  280         db_default_thread = thread;
  281         if (thread)
  282                 db_default_task = thread->task;
  283         return(0);
  284 }
  285 
  286 /*
  287  * convert $taskXXX[.YYY] type DDB variable to task or thread address
  288  */
  289 int
  290 db_get_task_thread(vp, valuep, flag, ap)
  291         struct db_variable      *vp;
  292         db_expr_t               *valuep;
  293         int                     flag;
  294         db_var_aux_param_t      ap;
  295 {
  296         task_t   task;
  297         thread_t thread;
  298 
  299         if (flag != DB_VAR_GET) {
  300             db_error("Cannot set to $task variable\n");
  301             /* NOTREACHED */
  302         }
  303         if ((task = db_lookup_task_id(ap->suffix[0])) == TASK_NULL) {
  304             db_printf("no such task($task%d)\n", ap->suffix[0]);
  305             db_error(0);
  306             /* NOTREACHED */
  307         }
  308         if (ap->level <= 1) {
  309             *valuep = (db_expr_t) task;
  310             return(0);
  311         }
  312         if ((thread = db_lookup_thread_id(task, ap->suffix[1])) == THREAD_NULL){
  313             db_printf("no such thread($task%d.%d)\n", 
  314                                         ap->suffix[0], ap->suffix[1]);
  315             db_error(0);
  316             /* NOTREACHED */
  317         }
  318         *valuep = (db_expr_t) thread;
  319         return(0);
  320 }

Cache object: 77bf386690b8e6390ce1dc28d7f6447b


[ 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.