|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.