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