X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/ff6e181ae92fc6f1e89841290f461d1f2f9badd9..593a1d5fd87cdf5b46dd5fcb84467b432cea0f91:/osfmk/kern/bsd_kern.c diff --git a/osfmk/kern/bsd_kern.c b/osfmk/kern/bsd_kern.c index 13620cd60..c13e40826 100644 --- a/osfmk/kern/bsd_kern.c +++ b/osfmk/kern/bsd_kern.c @@ -1,14 +1,19 @@ /* - * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2007 Apple, Inc. All rights reserved. * - * @APPLE_LICENSE_HEADER_START@ + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER @@ -18,7 +23,7 @@ * Please see the License for the specific language governing rights and * limitations under the License. * - * @APPLE_LICENSE_HEADER_END@ + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ #include @@ -32,6 +37,7 @@ #include #include #include +#include #include #include /* last */ @@ -51,9 +57,10 @@ boolean_t thread_should_abort(thread_t); boolean_t current_thread_aborted(void); void task_act_iterate_wth_args(task_t, void(*)(thread_t, void *), void *); void ipc_port_release(ipc_port_t); -boolean_t is_thread_active(thread_t); kern_return_t get_signalact(task_t , thread_t *, int); int get_vmsubmap_entries(vm_map_t, vm_object_offset_t, vm_object_offset_t); +void syscall_exit_funnelcheck(void); + /* * @@ -63,6 +70,14 @@ void *get_bsdtask_info(task_t t) return(t->bsd_info); } +/* + * + */ +void *get_bsdthreadtask_info(thread_t th) +{ + return(th->task != TASK_NULL ? th->task->bsd_info : NULL); +} + /* * */ @@ -117,15 +132,15 @@ get_signalact( for (inc = (thread_t)queue_first(&task->threads); !queue_end(&task->threads, (queue_entry_t)inc); ) { - thread_mtx_lock(inc); - if (inc->active && - (inc->state & (TH_ABORT|TH_ABORT_SAFELY)) != TH_ABORT) { - thread = inc; - break; - } - thread_mtx_unlock(inc); - - inc = (thread_t)queue_next(&inc->task_threads); + thread_mtx_lock(inc); + if (inc->active && + (inc->sched_mode & TH_MODE_ISABORTED) != TH_MODE_ABORT) { + thread = inc; + break; + } + thread_mtx_unlock(inc); + + inc = (thread_t)queue_next(&inc->task_threads); } if (result_out) @@ -169,7 +184,7 @@ check_actforsig( thread_mtx_lock(inc); if (inc->active && - (inc->state & (TH_ABORT|TH_ABORT_SAFELY)) != TH_ABORT) { + (inc->sched_mode & TH_MODE_ISABORTED) != TH_MODE_ABORT) { result = KERN_SUCCESS; break; } @@ -230,6 +245,22 @@ ipc_space_t get_task_ipcspace(task_t t) return(t->itk_space); } +int get_task_numactivethreads(task_t task) +{ + thread_t inc; + int num_active_thr=0; + task_lock(task); + + for (inc = (thread_t)queue_first(&task->threads); + !queue_end(&task->threads, (queue_entry_t)inc); inc = (thread_t)queue_next(&inc->task_threads)) + { + if(inc->active) + num_active_thr++; + } + task_unlock(task); + return num_active_thr; +} + int get_task_numacts(task_t t) { return(t->thread_count); @@ -261,6 +292,9 @@ swap_task_map(task_t task,vm_map_t map) old_map = task->map; thread->map = task->map = map; task_unlock(task); + + inval_copy_windows(thread); + return old_map; } @@ -287,43 +321,6 @@ task_t get_threadtask(thread_t th) return(th->task); } - -/* - * - */ -boolean_t is_thread_idle(thread_t th) -{ - return((th->state & TH_IDLE) == TH_IDLE); -} - -/* - * - */ -boolean_t is_thread_running(thread_t th) -{ - return((th->state & TH_RUN) == TH_RUN); -} - -/* - * - */ -thread_t -getshuttle_thread( - thread_t th) -{ - return(th); -} - -/* - * - */ -thread_t -getact_thread( - thread_t th) -{ - return(th); -} - /* * */ @@ -441,7 +438,7 @@ boolean_t thread_should_abort( thread_t th) { - return ((th->state & (TH_ABORT|TH_ABORT_SAFELY)) == TH_ABORT); + return ((th->sched_mode & TH_MODE_ISABORTED) == TH_MODE_ABORT); } /* @@ -459,14 +456,14 @@ current_thread_aborted ( thread_t th = current_thread(); spl_t s; - if ((th->state & (TH_ABORT|TH_ABORT_SAFELY)) == TH_ABORT && + if ((th->sched_mode & TH_MODE_ISABORTED) == TH_MODE_ABORT && (th->options & TH_OPT_INTMASK) != THREAD_UNINT) return (TRUE); - if (th->state & TH_ABORT_SAFELY) { + if (th->sched_mode & TH_MODE_ABORTSAFELY) { s = splsched(); thread_lock(th); - if (th->state & TH_ABORT_SAFELY) - th->state &= ~(TH_ABORT|TH_ABORT_SAFELY); + if (th->sched_mode & TH_MODE_ABORTSAFELY) + th->sched_mode &= ~TH_MODE_ISABORTED; thread_unlock(th); splx(s); } @@ -502,13 +499,6 @@ ipc_port_release( ipc_object_release(&(port)->ip_object); } -boolean_t -is_thread_active( - thread_t th) -{ - return(th->active); -} - void astbsd_on(void) { @@ -518,3 +508,174 @@ astbsd_on(void) ast_on_fast(AST_BSD); (void)ml_set_interrupts_enabled(reenable); } + + +#include + +void +fill_taskprocinfo(task_t task, struct proc_taskinfo_internal * ptinfo) +{ + vm_map_t map; + task_absolutetime_info_data_t tinfo; + thread_t thread; + int cswitch = 0, numrunning = 0; + + map = (task == kernel_task)? kernel_map: task->map; + + ptinfo->pti_virtual_size = map->size; + ptinfo->pti_resident_size = + (mach_vm_size_t)(pmap_resident_count(map->pmap)) + * PAGE_SIZE_64; + + task_lock(task); + + ptinfo->pti_policy = ((task != kernel_task)? + POLICY_TIMESHARE: POLICY_RR); + + tinfo.threads_user = tinfo.threads_system = 0; + tinfo.total_user = task->total_user_time; + tinfo.total_system = task->total_system_time; + + queue_iterate(&task->threads, thread, thread_t, task_threads) { + uint64_t tval; + + if ((thread->state & TH_RUN) == TH_RUN) + numrunning++; + cswitch += thread->c_switch; + tval = timer_grab(&thread->user_timer); + tinfo.threads_user += tval; + tinfo.total_user += tval; + + tval = timer_grab(&thread->system_timer); + tinfo.threads_system += tval; + tinfo.total_system += tval; + } + + ptinfo->pti_total_system = tinfo.total_system; + ptinfo->pti_total_user = tinfo.total_user; + ptinfo->pti_threads_system = tinfo.threads_system; + ptinfo->pti_threads_user = tinfo.threads_user; + + ptinfo->pti_faults = task->faults; + ptinfo->pti_pageins = task->pageins; + ptinfo->pti_cow_faults = task->cow_faults; + ptinfo->pti_messages_sent = task->messages_sent; + ptinfo->pti_messages_received = task->messages_received; + ptinfo->pti_syscalls_mach = task->syscalls_mach; + ptinfo->pti_syscalls_unix = task->syscalls_unix; + ptinfo->pti_csw = task->c_switch + cswitch; + ptinfo->pti_threadnum = task->thread_count; + ptinfo->pti_numrunning = numrunning; + ptinfo->pti_priority = task->priority; + + task_unlock(task); +} + +int +fill_taskthreadinfo(task_t task, uint64_t thaddr, struct proc_threadinfo_internal * ptinfo, void * vpp, int *vidp) +{ + thread_t thact; + int err=0; + mach_msg_type_number_t count; + thread_basic_info_data_t basic_info; + kern_return_t kret; + + task_lock(task); + + for (thact = (thread_t)queue_first(&task->threads); + !queue_end(&task->threads, (queue_entry_t)thact); ) { +#if defined(__ppc__) || defined(__arm__) + if (thact->machine.cthread_self == thaddr) +#elif defined (__i386__) + if (thact->machine.pcb->cthread_self == thaddr) +#else +#error architecture not supported +#endif + { + + count = THREAD_BASIC_INFO_COUNT; + if ((kret = thread_info_internal(thact, THREAD_BASIC_INFO, (thread_info_t)&basic_info, &count)) != KERN_SUCCESS) { + err = 1; + goto out; + } +#if 0 + ptinfo->pth_user_time = timer_grab(&basic_info.user_time); + ptinfo->pth_system_time = timer_grab(&basic_info.system_time); +#else + ptinfo->pth_user_time = ((basic_info.user_time.seconds * NSEC_PER_SEC) + (basic_info.user_time.microseconds * NSEC_PER_USEC)); + ptinfo->pth_system_time = ((basic_info.system_time.seconds * NSEC_PER_SEC) + (basic_info.system_time.microseconds * NSEC_PER_USEC)); + +#endif + ptinfo->pth_cpu_usage = basic_info.cpu_usage; + ptinfo->pth_policy = basic_info.policy; + ptinfo->pth_run_state = basic_info.run_state; + ptinfo->pth_flags = basic_info.flags; + ptinfo->pth_sleep_time = basic_info.sleep_time; + ptinfo->pth_curpri = thact->sched_pri; + ptinfo->pth_priority = thact->priority; + ptinfo->pth_maxpriority = thact->max_priority; + + if ((vpp != NULL) && (thact->uthread != NULL)) + bsd_threadcdir(thact->uthread, vpp, vidp); + err = 0; + goto out; + } + thact = (thread_t)queue_next(&thact->task_threads); + } + err = 1; + +out: + task_unlock(task); + return(err); +} + +int +fill_taskthreadlist(task_t task, void * buffer, int thcount) +{ + int numthr=0; + thread_t thact; + uint64_t * uptr; + uint64_t thaddr; + + uptr = (uint64_t *)buffer; + + task_lock(task); + + for (thact = (thread_t)queue_first(&task->threads); + !queue_end(&task->threads, (queue_entry_t)thact); ) { +#if defined(__ppc__) || defined(__arm__) + thaddr = thact->machine.cthread_self; +#elif defined (__i386__) + thaddr = thact->machine.pcb->cthread_self; +#else +#error architecture not supported +#endif + *uptr++ = thaddr; + numthr++; + if (numthr >= thcount) + goto out; + thact = (thread_t)queue_next(&thact->task_threads); + } + +out: + task_unlock(task); + return(numthr * sizeof(uint64_t)); + +} + +int +get_numthreads(task_t task) +{ + return(task->thread_count); +} + +void +syscall_exit_funnelcheck(void) +{ + thread_t thread; + + thread = current_thread(); + + if (thread->funnel_lock) + panic("syscall exit with funnel held\n"); +}