Annotation of Gnu-Mach/ddb/db_task_thread.c, revision 1.1.1.3

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.