|
|
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: #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: 1.1.1.2 ! root 187: 1.1 root 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){ 1.1.1.2 ! root 294: db_printf("no such thread($task%d.%d)\n", 1.1 root 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: 1.1.1.2 ! root 303: #endif /* MACH_KDB */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.