]>
git.saurik.com Git - apple/xnu.git/blob - osfmk/ddb/db_task_thread.c
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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.
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
20 * @APPLE_LICENSE_HEADER_END@
26 * Mach Operating System
27 * Copyright (c) 1991,1990 Carnegie Mellon University
28 * All Rights Reserved.
30 * Permission to use, copy, modify and distribute this software and its
31 * documentation is hereby granted, provided that both the copyright
32 * notice and this permission notice appear in all copies of the
33 * software, derivative works or modified versions, and any portions
34 * thereof, and that both notices appear in supporting documentation.
36 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
37 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
38 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
40 * Carnegie Mellon requests users of this software to return to
42 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
43 * School of Computer Science
44 * Carnegie Mellon University
45 * Pittsburgh PA 15213-3890
47 * any improvements or extensions that they make and grant Carnegie Mellon
48 * the rights to redistribute these changes.
53 #include <kern/kern_types.h>
54 #include <kern/processor.h>
55 #include <machine/db_machdep.h>
56 #include <ddb/db_task_thread.h>
57 #include <ddb/db_variables.h>
58 #include <ddb/db_command.h>
59 #include <ddb/db_expr.h>
60 #include <ddb/db_lex.h>
61 #include <ddb/db_output.h> /* For db_printf() */
62 #include <ddb/db_sym.h>
65 * Following constants are used to prevent infinite loop of task
66 * or thread search due to the incorrect list.
68 #define DB_MAX_TASKID 0x10000 /* max # of tasks */
69 #define DB_MAX_THREADID 0x10000 /* max # of threads in a task */
70 #define DB_MAX_PSETS 0x10000 /* max # of processor sets */
72 task_t db_default_task
; /* default target task */
73 thread_t db_default_act
; /* default target thr_act */
77 /* Prototypes for functions local to this file.
79 task_t
db_lookup_task_id(register int task_id
);
81 static thread_t
db_lookup_act_id(
83 register int thread_id
);
88 * search valid task queue, and return the queue position as the task id
91 db_lookup_task(task_t target_task
)
95 register processor_set_t pset
= &default_pset
;
96 register int npset
= 0;
99 if (npset
++ >= DB_MAX_PSETS
)
101 if (queue_first(&pset
->tasks
) == 0)
103 queue_iterate(&pset
->tasks
, task
, task_t
, pset_tasks
) {
104 if (target_task
== task
)
106 if (task_id
++ >= DB_MAX_TASKID
)
113 * search thread queue of the task, and return the queue position
120 register thread_t thr_act
;
124 if (queue_first(&task
->threads
) == 0)
126 queue_iterate(&task
->threads
, thr_act
, thread_t
, task_threads
) {
127 if (target_act
== thr_act
)
129 if (act_id
++ >= DB_MAX_THREADID
)
136 * search thr_act queue of every valid task, and return the queue position
140 db_lookup_act(thread_t target_act
)
143 register task_t task
;
144 register processor_set_t pset
= &default_pset
;
145 register int ntask
= 0;
146 register int npset
= 0;
148 if (npset
++ >= DB_MAX_PSETS
)
150 if (queue_first(&pset
->tasks
) == 0)
152 queue_iterate(&pset
->tasks
, task
, task_t
, pset_tasks
) {
153 if (ntask
++ > DB_MAX_TASKID
)
155 if (task
->thread_count
== 0)
157 act_id
= db_lookup_task_act(task
, target_act
);
165 * check the address is a valid thread address
167 int force_act_lookup
= 0;
169 db_check_act_address_valid(thread_t thr_act
)
171 if (!force_act_lookup
&& db_lookup_act(thr_act
) < 0) {
172 db_printf("Bad thr_act address 0x%x\n", thr_act
);
180 * convert task_id(queue postion) to task address
183 db_lookup_task_id(register task_id
)
185 register task_t task
;
186 register processor_set_t pset
= &default_pset
;
187 register int npset
= 0;
189 if (task_id
> DB_MAX_TASKID
)
191 if (npset
++ >= DB_MAX_PSETS
)
193 if (queue_first(&pset
->tasks
) == 0)
195 queue_iterate(&pset
->tasks
, task
, task_t
, pset_tasks
) {
203 * convert (task_id, act_id) pair to thr_act address
210 register thread_t thr_act
;
213 if (act_id
> DB_MAX_THREADID
)
215 if (queue_first(&task
->threads
) == 0)
217 queue_iterate(&task
->threads
, thr_act
, thread_t
, task_threads
) {
225 * get next parameter from a command line, and check it as a valid
237 if (db_expression(&value
)) {
238 thr_act
= (thread_t
) value
;
239 if (!db_check_act_address_valid(thr_act
)) {
243 } else if (position
<= 0) {
244 thr_act
= db_default_act
;
252 * check the default thread is still valid
253 * ( it is called in entering DDB session )
256 db_init_default_act(void)
258 if (db_lookup_act(db_default_act
) < 0) {
259 db_default_act
= THREAD_NULL
;
260 db_default_task
= TASK_NULL
;
262 db_default_task
= db_default_act
->task
;
266 * set or get default thread which is used when /t or :t option is specified
267 * in the command line
271 struct db_variable
*vp
,
274 db_var_aux_param_t ap
) /* unused */
280 if (flag
== DB_VAR_SHOW
) {
281 db_printf("%#n", db_default_act
);
282 task_id
= db_lookup_task(db_default_task
);
284 act_id
= db_lookup_act(db_default_act
);
286 db_printf(" (task%d.%d)", task_id
, act_id
);
292 if (flag
!= DB_VAR_SET
) {
293 *valuep
= (db_expr_t
) db_default_act
;
296 thr_act
= (thread_t
) *valuep
;
297 if (thr_act
!= THREAD_NULL
&& !db_check_act_address_valid(thr_act
))
300 db_default_act
= thr_act
;
302 db_default_task
= thr_act
->task
;
307 * convert $taskXXX[.YYY] type DDB variable to task or thread address
311 struct db_variable
*vp
,
314 db_var_aux_param_t ap
)
320 if (flag
== DB_VAR_SHOW
) {
321 db_printf("%#n", db_default_task
);
322 task_id
= db_lookup_task(db_default_task
);
324 db_printf(" (task%d)", task_id
);
328 if (flag
!= DB_VAR_GET
) {
329 db_error("Cannot set to $task variable\n");
332 if ((task
= db_lookup_task_id(ap
->suffix
[0])) == TASK_NULL
) {
333 db_printf("no such task($task%d)\n", ap
->suffix
[0]);
337 if (ap
->level
<= 1) {
338 *valuep
= (db_expr_t
) task
;
341 if ((thr_act
= db_lookup_act_id(task
, ap
->suffix
[1])) == THREAD_NULL
){
342 db_printf("no such thr_act($task%d.%d)\n",
343 ap
->suffix
[0], ap
->suffix
[1]);
347 *valuep
= (db_expr_t
) thr_act
;