]>
git.saurik.com Git - apple/xnu.git/blob - osfmk/kern/bsd_kern.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@
22 #include <mach/mach_types.h>
23 #include <kern/queue.h>
25 #include <kern/thread.h>
26 #include <kern/thread_act.h>
27 #include <kern/task.h>
29 #include <kern/lock.h>
30 #include <vm/vm_map.h>
32 #include <ipc/ipc_port.h>
33 #include <ipc/ipc_object.h>
35 #undef thread_should_halt
36 #undef ipc_port_release
38 /* BSD KERN COMPONENT INTERFACE */
40 task_t bsd_init_task
= TASK_NULL
;
41 char init_task_failure_data
[1024];
42 extern unsigned int not_in_kdp
; /* Skip acquiring locks if we're in kdp */
44 thread_act_t
get_firstthread(task_t
);
45 vm_map_t
get_task_map(task_t
);
46 ipc_space_t
get_task_ipcspace(task_t
);
47 boolean_t
is_kerneltask(task_t
);
48 boolean_t
is_thread_idle(thread_t
);
49 vm_offset_t
get_map_min( vm_map_t
);
50 vm_offset_t
get_map_max( vm_map_t
);
51 int get_task_userstop(task_t
);
52 int get_thread_userstop(thread_act_t
);
53 boolean_t
thread_should_abort(thread_t
);
54 boolean_t
current_thread_aborted(void);
55 void task_act_iterate_wth_args(task_t
, void(*)(thread_act_t
, void *), void *);
56 void ipc_port_release(ipc_port_t
);
57 boolean_t
is_thread_active(thread_t
);
58 kern_return_t
get_thread_waitresult(thread_t
);
59 vm_size_t
get_vmmap_size(vm_map_t
);
60 int get_vmmap_entries(vm_map_t
);
61 int get_task_numacts(task_t
);
62 thread_act_t
get_firstthread(task_t task
);
63 kern_return_t
get_signalact(task_t
, thread_act_t
*, int);
69 void *get_bsdtask_info(task_t t
)
77 void set_bsdtask_info(task_t t
,void * v
)
85 void *get_bsdthread_info(thread_act_t th
)
91 * XXX: wait for BSD to fix signal code
92 * Until then, we cannot block here. We know the task
93 * can't go away, so we make sure it is still active after
94 * retrieving the first thread for extra safety.
96 thread_act_t
get_firstthread(task_t task
)
100 thr_act
= (thread_act_t
)queue_first(&task
->threads
);
101 if (queue_end(&task
->threads
, (queue_entry_t
)thr_act
))
102 thr_act
= THR_ACT_NULL
;
104 return(THR_ACT_NULL
);
108 kern_return_t
get_signalact(task_t task
,thread_act_t
* thact
, int setast
)
113 thread_act_t thr_act
;
119 return(KERN_FAILURE
);
122 thr_act
= THR_ACT_NULL
;
123 for (inc
= (thread_act_t
)queue_first(&task
->threads
);
124 !queue_end(&task
->threads
, (queue_entry_t
)inc
);
126 th
= act_lock_thread(inc
);
128 ((th
->state
& (TH_ABORT
|TH_ABORT_SAFELY
)) != TH_ABORT
)) {
132 act_unlock_thread(inc
);
133 ninc
= (thread_act_t
)queue_next(&inc
->task_threads
);
140 act_set_astbsd(thr_act
);
142 act_unlock_thread(thr_act
);
147 return(KERN_SUCCESS
);
149 return(KERN_FAILURE
);
153 kern_return_t
check_actforsig(task_t task
, thread_act_t thact
, int setast
)
158 thread_act_t thr_act
;
165 return(KERN_FAILURE
);
168 thr_act
= THR_ACT_NULL
;
169 for (inc
= (thread_act_t
)queue_first(&task
->threads
);
170 !queue_end(&task
->threads
, (queue_entry_t
)inc
);
174 ninc
= (thread_act_t
)queue_next(&inc
->task_threads
);
177 th
= act_lock_thread(inc
);
179 ((th
->state
& (TH_ABORT
|TH_ABORT_SAFELY
)) != TH_ABORT
)) {
184 act_unlock_thread(inc
);
185 /* ninc = (thread_act_t)queue_next(&inc->thr_acts); */
191 act_set_astbsd(thr_act
);
193 act_unlock_thread(thr_act
);
198 return(KERN_SUCCESS
);
200 return(KERN_FAILURE
);
206 vm_map_t
get_task_map(task_t t
)
214 ipc_space_t
get_task_ipcspace(task_t t
)
216 return(t
->itk_space
);
219 int get_task_numacts(task_t t
)
221 return(t
->thread_count
);
224 /* does this machine need 64bit register set for signal handler */
225 int is_64signalregset(void)
227 task_t t
= current_task();
228 if(t
->taskFeatures
[0] & tf64BitData
)
235 * The old map reference is returned.
238 swap_task_map(task_t task
,vm_map_t map
)
240 thread_act_t act
= current_act();
243 if (task
!= act
->task
)
244 panic("swap_task_map");
248 act
->map
= task
->map
= map
;
254 swap_act_map(thread_act_t thr_act
,vm_map_t map
)
256 panic("swap_act_map");
262 pmap_t
get_task_pmap(task_t t
)
264 return(t
->map
->pmap
);
270 pmap_t
get_map_pmap(vm_map_t map
)
277 task_t
get_threadtask(thread_act_t th
)
286 boolean_t
is_thread_idle(thread_t th
)
288 return((th
->state
& TH_IDLE
) == TH_IDLE
);
294 boolean_t
is_thread_running(thread_t th
)
296 return((th
->state
& TH_RUN
) == TH_RUN
);
326 return(vm_map_min(map
));
336 return(vm_map_max(map
));
346 get_vmsubmap_entries(
348 vm_object_offset_t start
,
349 vm_object_offset_t end
)
351 int total_entries
= 0;
352 vm_map_entry_t entry
;
356 entry
= vm_map_first_entry(map
);
357 while((entry
!= vm_map_to_entry(map
)) && (entry
->vme_start
< start
)) {
358 entry
= entry
->vme_next
;
361 while((entry
!= vm_map_to_entry(map
)) && (entry
->vme_start
< end
)) {
362 if(entry
->is_sub_map
) {
364 get_vmsubmap_entries(entry
->object
.sub_map
,
367 (entry
->vme_end
- entry
->vme_start
));
371 entry
= entry
->vme_next
;
375 return(total_entries
);
382 int total_entries
= 0;
383 vm_map_entry_t entry
;
387 entry
= vm_map_first_entry(map
);
389 while(entry
!= vm_map_to_entry(map
)) {
390 if(entry
->is_sub_map
) {
392 get_vmsubmap_entries(entry
->object
.sub_map
,
395 (entry
->vme_end
- entry
->vme_start
));
399 entry
= entry
->vme_next
;
403 return(total_entries
);
416 return(task
->user_stop_count
);
426 return(th
->user_stop_count
);
436 return(!th
->top_act
||
437 (th
->state
& (TH_ABORT
|TH_ABORT_SAFELY
)) == TH_ABORT
);
441 * This routine is like thread_should_abort() above. It checks to
442 * see if the current thread is aborted. But unlike above, it also
443 * checks to see if thread is safely aborted. If so, it returns
444 * that fact, and clears the condition (safe aborts only should
445 * have a single effect, and a poll of the abort status
449 current_thread_aborted (
452 thread_t th
= current_thread();
456 ((th
->state
& (TH_ABORT
|TH_ABORT_SAFELY
)) == TH_ABORT
&&
457 th
->interrupt_level
!= THREAD_UNINT
))
459 if (th
->state
& TH_ABORT_SAFELY
) {
462 if (th
->state
& TH_ABORT_SAFELY
)
463 th
->state
&= ~(TH_ABORT
|TH_ABORT_SAFELY
);
474 task_act_iterate_wth_args(
476 void (*func_callback
)(thread_act_t
, void *),
479 thread_act_t inc
, ninc
;
482 for (inc
= (thread_act_t
)queue_first(&task
->threads
);
483 !queue_end(&task
->threads
, (queue_entry_t
)inc
);
485 ninc
= (thread_act_t
)queue_next(&inc
->task_threads
);
486 (void) (*func_callback
)(inc
, func_arg
);
495 ipc_object_release(&(port
)->ip_object
);
506 get_thread_waitresult(
509 return(th
->wait_result
);
517 reenable
= ml_set_interrupts_enabled(FALSE
);
518 ast_on_fast(AST_BSD
);
519 (void)ml_set_interrupts_enabled(reenable
);