Annotation of XNU/osfmk/ddb/db_task_thread.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * The contents of this file constitute Original Code as defined in and
        !             7:  * are subject to the Apple Public Source License Version 1.1 (the
        !             8:  * "License").  You may not use this file except in compliance with the
        !             9:  * License.  Please obtain a copy of the License at
        !            10:  * http://www.apple.com/publicsource and read it before using this file.
        !            11:  * 
        !            12:  * This Original Code and all software distributed under the License are
        !            13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            17:  * License for the specific language governing rights and limitations
        !            18:  * under the License.
        !            19:  * 
        !            20:  * @APPLE_LICENSE_HEADER_END@
        !            21:  */
        !            22: /*
        !            23:  * @OSF_COPYRIGHT@
        !            24:  */
        !            25: /*
        !            26:  * HISTORY
        !            27:  * 
        !            28:  * Revision 1.1.1.1  1998/09/22 21:05:48  wsanchez
        !            29:  * Import of Mac OS X kernel (~semeria)
        !            30:  *
        !            31:  * Revision 1.1.1.1  1998/03/07 02:26:09  wsanchez
        !            32:  * Import of OSF Mach kernel (~mburg)
        !            33:  *
        !            34:  * Revision 1.1.16.3  1996/01/09  19:16:26  devrcs
        !            35:  *     Make db_lookup_task_id() globally available (remove static).
        !            36:  *     Changed declarations of 'register foo' to 'register int foo'.
        !            37:  *     [1995/12/01  21:42:37  jfraser]
        !            38:  *
        !            39:  *     Merged '64-bit safe' changes from DEC alpha port.
        !            40:  *     [1995/11/21  18:03:48  jfraser]
        !            41:  *
        !            42:  * Revision 1.1.16.2  1994/09/23  01:21:59  ezf
        !            43:  *     change marker to not FREE
        !            44:  *     [1994/09/22  21:11:09  ezf]
        !            45:  * 
        !            46:  * Revision 1.1.16.1  1994/06/11  21:12:29  bolinger
        !            47:  *     Merge up to NMK17.2.
        !            48:  *     [1994/06/11  20:02:43  bolinger]
        !            49:  * 
        !            50:  * Revision 1.1.14.1  1994/02/08  10:59:02  bernadat
        !            51:  *     Added support of DB_VAR_SHOW.
        !            52:  *     [93/08/12            paire]
        !            53:  *     [94/02/08            bernadat]
        !            54:  * 
        !            55:  * Revision 1.1.12.3  1994/03/17  22:35:35  dwm
        !            56:  *     The infamous name change:  thread_activation + thread_shuttle = thread.
        !            57:  *     [1994/03/17  21:25:50  dwm]
        !            58:  * 
        !            59:  * Revision 1.1.12.2  1994/01/17  18:08:54  dwm
        !            60:  *     Add patchable integer force_act_lookup to force successful
        !            61:  *     lookup, to allow stack trace on orphaned act/thread pairs.
        !            62:  *     [1994/01/17  16:06:50  dwm]
        !            63:  * 
        !            64:  * Revision 1.1.12.1  1994/01/12  17:50:52  dwm
        !            65:  *     Coloc: initial restructuring to follow Utah model.
        !            66:  *     [1994/01/12  17:13:23  dwm]
        !            67:  * 
        !            68:  * Revision 1.1.3.3  1993/07/27  18:28:15  elliston
        !            69:  *     Add ANSI prototypes.  CR #9523.
        !            70:  *     [1993/07/27  18:13:06  elliston]
        !            71:  * 
        !            72:  * Revision 1.1.3.2  1993/06/02  23:12:39  jeffc
        !            73:  *     Added to OSF/1 R1.3 from NMK15.0.
        !            74:  *     [1993/06/02  20:57:24  jeffc]
        !            75:  * 
        !            76:  * Revision 1.1  1992/09/30  02:01:27  robert
        !            77:  *     Initial revision
        !            78:  * 
        !            79:  * $EndLog$
        !            80:  */
        !            81: /* CMU_HIST */
        !            82: /*
        !            83:  * Revision 2.2  91/10/09  16:03:04  af
        !            84:  *      Revision 2.1.3.1  91/10/05  13:07:50  jeffreyh
        !            85:  *             Created for task/thread handling.
        !            86:  *             [91/08/29            tak]
        !            87:  * 
        !            88:  * Revision 2.1.3.1  91/10/05  13:07:50  jeffreyh
        !            89:  *     Created for task/thread handling.
        !            90:  *     [91/08/29            tak]
        !            91:  * 
        !            92:  */
        !            93: /* CMU_ENDHIST */
        !            94: /* 
        !            95:  * Mach Operating System
        !            96:  * Copyright (c) 1991,1990 Carnegie Mellon University
        !            97:  * All Rights Reserved.
        !            98:  * 
        !            99:  * Permission to use, copy, modify and distribute this software and its
        !           100:  * documentation is hereby granted, provided that both the copyright
        !           101:  * notice and this permission notice appear in all copies of the
        !           102:  * software, derivative works or modified versions, and any portions
        !           103:  * thereof, and that both notices appear in supporting documentation.
        !           104:  * 
        !           105:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
        !           106:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
        !           107:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
        !           108:  * 
        !           109:  * Carnegie Mellon requests users of this software to return to
        !           110:  * 
        !           111:  *  Software Distribution Coordinator  or  [email protected]
        !           112:  *  School of Computer Science
        !           113:  *  Carnegie Mellon University
        !           114:  *  Pittsburgh PA 15213-3890
        !           115:  * 
        !           116:  * any improvements or extensions that they make and grant Carnegie Mellon
        !           117:  * the rights to redistribute these changes.
        !           118:  */
        !           119: /*
        !           120:  */
        !           121: 
        !           122: #include <kern/kern_types.h>
        !           123: #include <kern/processor.h>
        !           124: #include <machine/db_machdep.h>
        !           125: #include <ddb/db_task_thread.h>
        !           126: #include <ddb/db_variables.h>
        !           127: #include <ddb/db_command.h>
        !           128: #include <ddb/db_expr.h>
        !           129: #include <ddb/db_lex.h>
        !           130: #include <ddb/db_output.h>             /* For db_printf() */
        !           131: #include <ddb/db_sym.h>
        !           132: 
        !           133: /*
        !           134:  * Following constants are used to prevent infinite loop of task
        !           135:  * or thread search due to the incorrect list.
        !           136:  */
        !           137: #define        DB_MAX_TASKID   0x10000         /* max # of tasks */
        !           138: #define DB_MAX_THREADID        0x10000         /* max # of threads in a task */
        !           139: #define DB_MAX_PSETS   0x10000         /* max # of processor sets */
        !           140: 
        !           141: task_t         db_default_task;        /* default target task */
        !           142: thread_act_t   db_default_act;         /* default target thr_act */
        !           143: 
        !           144: 
        !           145: 
        !           146: /* Prototypes for functions local to this file.
        !           147:  */
        !           148: task_t db_lookup_task_id(register int task_id);
        !           149: 
        !           150: static thread_act_t db_lookup_act_id(
        !           151:        task_t   task,
        !           152:        register int thread_id);
        !           153: 
        !           154: 
        !           155: 
        !           156: /*
        !           157:  * search valid task queue, and return the queue position as the task id
        !           158:  */
        !           159: int
        !           160: db_lookup_task(task_t target_task)
        !           161: {
        !           162:        register task_t task;
        !           163:        register int task_id;
        !           164:        register processor_set_t pset;
        !           165:        register int npset = 0;
        !           166: 
        !           167:        task_id = 0;
        !           168:        if (queue_first(&all_psets) == 0)
        !           169:            return(-1);
        !           170:        queue_iterate(&all_psets, pset, processor_set_t, all_psets) {
        !           171:            if (npset++ >= DB_MAX_PSETS)
        !           172:                return(-1);
        !           173:            if (queue_first(&pset->tasks) == 0)
        !           174:                continue;
        !           175:            queue_iterate(&pset->tasks, task, task_t, pset_tasks) {
        !           176:                if (target_task == task)
        !           177:                    return(task_id);
        !           178:                if (task_id++ >= DB_MAX_TASKID)
        !           179:                    return(-1);
        !           180:            }
        !           181:        }
        !           182:        return(-1);
        !           183: }
        !           184: 
        !           185: /*
        !           186:  * search thread queue of the task, and return the queue position
        !           187:  */
        !           188: int
        !           189: db_lookup_task_act(
        !           190:        task_t          task,
        !           191:        thread_act_t    target_act)
        !           192: {
        !           193:        register thread_act_t thr_act;
        !           194:        register int act_id;
        !           195: 
        !           196:        act_id = 0;
        !           197:        if (queue_first(&task->thr_acts) == 0)
        !           198:            return(-1);
        !           199:        queue_iterate(&task->thr_acts, thr_act, thread_act_t, thr_acts) {
        !           200:            if (target_act == thr_act)
        !           201:                return(act_id);
        !           202:            if (act_id++ >= DB_MAX_THREADID)
        !           203:                return(-1);
        !           204:        }
        !           205:        return(-1);
        !           206: }
        !           207: 
        !           208: /*
        !           209:  * search thr_act queue of every valid task, and return the queue position
        !           210:  * as the thread id.
        !           211:  */
        !           212: int
        !           213: db_lookup_act(thread_act_t target_act)
        !           214: {
        !           215:        register int act_id;
        !           216:        register task_t task;
        !           217:        register processor_set_t pset;
        !           218:        register int ntask = 0;
        !           219:        register int npset = 0;
        !           220: 
        !           221:        if (queue_first(&all_psets) == 0)
        !           222:            return(-1);
        !           223:        queue_iterate(&all_psets, pset, processor_set_t, all_psets) {
        !           224:            if (npset++ >= DB_MAX_PSETS)
        !           225:                return(-1);
        !           226:            if (queue_first(&pset->tasks) == 0)
        !           227:                continue;
        !           228:            queue_iterate(&pset->tasks, task, task_t, pset_tasks) {
        !           229:                if (ntask++ > DB_MAX_TASKID)
        !           230:                    return(-1);
        !           231:                if (task->thr_act_count == 0)
        !           232:                    continue;
        !           233:                act_id = db_lookup_task_act(task, target_act);
        !           234:                if (act_id >= 0)
        !           235:                    return(act_id);
        !           236:            }
        !           237:        }
        !           238:        return(-1);
        !           239: }
        !           240: 
        !           241: /*
        !           242:  * check the address is a valid thread address
        !           243:  */
        !           244: int force_act_lookup = 0;
        !           245: boolean_t
        !           246: db_check_act_address_valid(thread_act_t thr_act)
        !           247: {
        !           248:        if (!force_act_lookup && db_lookup_act(thr_act) < 0) {
        !           249:            db_printf("Bad thr_act address 0x%x\n", thr_act);
        !           250:            db_flush_lex();
        !           251:            return(FALSE);
        !           252:        } else
        !           253:            return(TRUE);
        !           254: }
        !           255: 
        !           256: /*
        !           257:  * convert task_id(queue postion) to task address
        !           258:  */
        !           259: task_t
        !           260: db_lookup_task_id(register task_id)
        !           261: {
        !           262:        register task_t task;
        !           263:        register processor_set_t pset;
        !           264:        register int npset = 0;
        !           265: 
        !           266:        if (task_id > DB_MAX_TASKID)
        !           267:            return(TASK_NULL);
        !           268:        if (queue_first(&all_psets) == 0)
        !           269:            return(TASK_NULL);
        !           270:        queue_iterate(&all_psets, pset, processor_set_t, all_psets) {
        !           271:            if (npset++ >= DB_MAX_PSETS)
        !           272:                return(TASK_NULL);
        !           273:            if (queue_first(&pset->tasks) == 0)
        !           274:                continue;
        !           275:            queue_iterate(&pset->tasks, task, task_t, pset_tasks) {
        !           276:                if (task_id-- <= 0)
        !           277:                        return(task);
        !           278:            }
        !           279:        }
        !           280:        return(TASK_NULL);
        !           281: }
        !           282: 
        !           283: /*
        !           284:  * convert (task_id, act_id) pair to thr_act address
        !           285:  */
        !           286: static thread_act_t
        !           287: db_lookup_act_id(
        !           288:        task_t   task,
        !           289:        register int act_id)
        !           290: {
        !           291:        register thread_act_t thr_act;
        !           292: 
        !           293:        
        !           294:        if (act_id > DB_MAX_THREADID)
        !           295:            return(THR_ACT_NULL);
        !           296:        if (queue_first(&task->thr_acts) == 0)
        !           297:            return(THR_ACT_NULL);
        !           298:        queue_iterate(&task->thr_acts, thr_act, thread_act_t, thr_acts) {
        !           299:            if (act_id-- <= 0)
        !           300:                return(thr_act);
        !           301:        }
        !           302:        return(THR_ACT_NULL);
        !           303: }
        !           304: 
        !           305: /*
        !           306:  * get next parameter from a command line, and check it as a valid
        !           307:  * thread address
        !           308:  */
        !           309: boolean_t
        !           310: db_get_next_act(
        !           311:        thread_act_t    *actp,
        !           312:        int             position)
        !           313: {
        !           314:        db_expr_t       value;
        !           315:        thread_act_t    thr_act;
        !           316: 
        !           317:        *actp = THR_ACT_NULL;
        !           318:        if (db_expression(&value)) {
        !           319:            thr_act = (thread_act_t) value;
        !           320:            if (!db_check_act_address_valid(thr_act)) {
        !           321:                db_flush_lex();
        !           322:                return(FALSE);
        !           323:            }
        !           324:        } else if (position <= 0) {
        !           325:            thr_act = db_default_act;
        !           326:        } else
        !           327:            return(FALSE);
        !           328:        *actp = thr_act;
        !           329:        return(TRUE);
        !           330: }
        !           331: 
        !           332: /*
        !           333:  * check the default thread is still valid
        !           334:  *     ( it is called in entering DDB session )
        !           335:  */
        !           336: void
        !           337: db_init_default_act(void)
        !           338: {
        !           339:        if (db_lookup_act(db_default_act) < 0) {
        !           340:            db_default_act = THR_ACT_NULL;
        !           341:            db_default_task = TASK_NULL;
        !           342:        } else
        !           343:            db_default_task = db_default_act->task;
        !           344: }
        !           345: 
        !           346: /*
        !           347:  * set or get default thread which is used when /t or :t option is specified
        !           348:  * in the command line
        !           349:  */
        !           350: int
        !           351: db_set_default_act(
        !           352:        struct db_variable      *vp,
        !           353:        db_expr_t               *valuep,
        !           354:        int                     flag,
        !           355:        db_var_aux_param_t      ap)                     /* unused */
        !           356: {
        !           357:        thread_act_t    thr_act;
        !           358:        int             task_id;
        !           359:        int             act_id;
        !           360: 
        !           361:        if (flag == DB_VAR_SHOW) {
        !           362:            db_printf("%#n", db_default_act);
        !           363:            task_id = db_lookup_task(db_default_task);
        !           364:            if (task_id != -1) {
        !           365:                act_id = db_lookup_act(db_default_act);
        !           366:                if (act_id != -1) {
        !           367:                    db_printf(" (task%d.%d)", task_id, act_id);
        !           368:                }
        !           369:            }
        !           370:            return(0);
        !           371:        }
        !           372: 
        !           373:        if (flag != DB_VAR_SET) {
        !           374:            *valuep = (db_expr_t) db_default_act;
        !           375:            return(0);
        !           376:        }
        !           377:        thr_act = (thread_act_t) *valuep;
        !           378:        if (thr_act != THR_ACT_NULL && !db_check_act_address_valid(thr_act))
        !           379:            db_error(0);
        !           380:            /* NOTREACHED */
        !           381:        db_default_act = thr_act;
        !           382:        if (thr_act)
        !           383:                db_default_task = thr_act->task;
        !           384:        return(0);
        !           385: }
        !           386: 
        !           387: /*
        !           388:  * convert $taskXXX[.YYY] type DDB variable to task or thread address
        !           389:  */
        !           390: int
        !           391: db_get_task_act(
        !           392:        struct db_variable      *vp,
        !           393:        db_expr_t               *valuep,
        !           394:        int                     flag,
        !           395:        db_var_aux_param_t      ap)
        !           396: {
        !           397:        task_t                  task;
        !           398:        thread_act_t            thr_act;
        !           399:        int                     task_id;
        !           400: 
        !           401:        if (flag == DB_VAR_SHOW) {
        !           402:            db_printf("%#n", db_default_task);
        !           403:            task_id = db_lookup_task(db_default_task);
        !           404:            if (task_id != -1)
        !           405:                db_printf(" (task%d)", task_id);
        !           406:            return(0);
        !           407:        }
        !           408: 
        !           409:        if (flag != DB_VAR_GET) {
        !           410:            db_error("Cannot set to $task variable\n");
        !           411:            /* NOTREACHED */
        !           412:        }
        !           413:        if ((task = db_lookup_task_id(ap->suffix[0])) == TASK_NULL) {
        !           414:            db_printf("no such task($task%d)\n", ap->suffix[0]);
        !           415:            db_error(0);
        !           416:            /* NOTREACHED */
        !           417:        }
        !           418:        if (ap->level <= 1) {
        !           419:            *valuep = (db_expr_t) task;
        !           420:            return(0);
        !           421:        }
        !           422:        if ((thr_act = db_lookup_act_id(task, ap->suffix[1])) == THR_ACT_NULL){
        !           423:            db_printf("no such thr_act($task%d.%d)\n", 
        !           424:                                        ap->suffix[0], ap->suffix[1]);
        !           425:            db_error(0);
        !           426:            /* NOTREACHED */
        !           427:        }
        !           428:        *valuep = (db_expr_t) thr_act;
        !           429:        return(0);
        !           430: }

unix.superglobalmegacorp.com

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