Annotation of Gnu-Mach/ddb/db_task_thread.c, revision 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.