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