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

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