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

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)
1.1.1.4 ! root       55:        const task_t target_task;
1.1       root       56: {
1.1.1.4 ! root       57:        task_t task;
        !            58:        int task_id;
        !            59:        processor_set_t pset;
        !            60:        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)
1.1.1.4 ! root       85:        const task_t     task;
        !            86:        const thread_t target_thread;
1.1       root       87: {
1.1.1.4 ! root       88:        thread_t thread;
        !            89:        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)
1.1.1.4 ! root      109:        const thread_t target_thread;
1.1       root      110: {
1.1.1.4 ! root      111:        int thread_id;
        !           112:        task_t task;
        !           113:        processor_set_t pset;
        !           114:        int ntask = 0;
        !           115:        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)
1.1.1.4 ! root      142:        const thread_t thread;
1.1       root      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: /*
1.1.1.4 ! root      153:  * convert task_id(queue position) to task address
1.1       root      154:  */
                    155: task_t
1.1.1.4 ! root      156: db_lookup_task_id(int task_id)
1.1       root      157: {
1.1.1.4 ! root      158:        task_t task;
        !           159:        processor_set_t pset;
        !           160:        int npset = 0;
1.1       root      161: 
                    162:        if (task_id > DB_MAX_TASKID)
                    163:            return(TASK_NULL);
                    164:        if (queue_first(&all_psets) == 0)
                    165:            return(TASK_NULL);
                    166:        queue_iterate(&all_psets, pset, processor_set_t, all_psets) {
                    167:            if (npset++ >= DB_MAX_PSETS)
                    168:                return(TASK_NULL);
                    169:            if (queue_first(&pset->tasks) == 0)
                    170:                continue;
                    171:            queue_iterate(&pset->tasks, task, task_t, pset_tasks) {
                    172:                if (task_id-- <= 0)
                    173:                        return(task);
                    174:            }
                    175:        }
                    176:        return(TASK_NULL);
                    177: }
                    178: 
                    179: /*
                    180:  * convert (task_id, thread_id) pair to thread address
                    181:  */
                    182: static thread_t
1.1.1.4 ! root      183: db_lookup_thread_id(
        !           184:        task_t  task,
        !           185:        int     thread_id)
1.1       root      186: {
1.1.1.4 ! root      187:        thread_t thread;
1.1       root      188: 
1.1.1.2   root      189: 
1.1       root      190:        if (thread_id > DB_MAX_THREADID)
                    191:            return(THREAD_NULL);
                    192:        if (queue_first(&task->thread_list) == 0)
                    193:            return(THREAD_NULL);
                    194:        queue_iterate(&task->thread_list, thread, thread_t, thread_list) {
                    195:            if (thread_id-- <= 0)
                    196:                return(thread);
                    197:        }
                    198:        return(THREAD_NULL);
                    199: }
                    200: 
                    201: /*
                    202:  * get next parameter from a command line, and check it as a valid
                    203:  * thread address
                    204:  */
                    205: boolean_t
1.1.1.4 ! root      206: db_get_next_thread(
        !           207:        thread_t        *threadp,
        !           208:        int             position)
1.1       root      209: {
                    210:        db_expr_t       value;
                    211:        thread_t        thread;
                    212: 
                    213:        *threadp = THREAD_NULL;
                    214:        if (db_expression(&value)) {
                    215:            thread = (thread_t) value;
                    216:            if (!db_check_thread_address_valid(thread)) {
                    217:                db_flush_lex();
                    218:                return(FALSE);
                    219:            }
                    220:        } else if (position <= 0) {
                    221:            thread = db_default_thread;
                    222:        } else
                    223:            return(FALSE);
                    224:        *threadp = thread;
                    225:        return(TRUE);
                    226: }
                    227: 
                    228: /*
                    229:  * check the default thread is still valid
                    230:  *     ( it is called in entering DDB session )
                    231:  */
                    232: void
1.1.1.3   root      233: db_init_default_thread(void)
1.1       root      234: {
                    235:        if (db_lookup_thread(db_default_thread) < 0) {
                    236:            db_default_thread = THREAD_NULL;
                    237:            db_default_task = TASK_NULL;
                    238:        } else
                    239:            db_default_task = db_default_thread->task;
                    240: }
                    241: 
                    242: /*
                    243:  * set or get default thread which is used when /t or :t option is specified
                    244:  * in the command line
                    245:  */
                    246: /* ARGSUSED */
1.1.1.4 ! root      247: void
        !           248: db_set_default_thread(vp, valuep, flag, ap)
        !           249:        struct db_variable      *vp;
        !           250:        db_expr_t               *valuep;
        !           251:        int                     flag;
        !           252:        db_var_aux_param_t      ap;
1.1       root      253: {
                    254:        thread_t        thread;
                    255: 
                    256:        if (flag != DB_VAR_SET) {
                    257:            *valuep = (db_expr_t) db_default_thread;
1.1.1.4 ! root      258:            return;
1.1       root      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;
1.1.1.4 ! root      267:        return;
1.1       root      268: }
                    269: 
                    270: /*
                    271:  * convert $taskXXX[.YYY] type DDB variable to task or thread address
                    272:  */
1.1.1.4 ! root      273: void
        !           274: db_get_task_thread(
        !           275:        struct db_variable      *vp,
        !           276:        db_expr_t               *valuep,
        !           277:        int                     flag,
        !           278:        db_var_aux_param_t      ap)
1.1       root      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;
1.1.1.4 ! root      294:            return;
1.1       root      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;
1.1.1.4 ! root      303:        return;
1.1       root      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.