void sample_rusage (struct proc *p) { struct task_basic_info bi; struct task_events_info ei; struct task_thread_times_info tti; mach_msg_type_number_t count; error_t err; count = TASK_BASIC_INFO_COUNT; err = task_info (p->p_task, TASK_BASIC_INFO, (task_info_t) &bi, &count); if (err) memset (&bi, 0, sizeof bi); count = TASK_EVENTS_INFO_COUNT; err = task_info (p->p_task, TASK_EVENTS_INFO, (task_info_t) &ei, &count); if (err) memset (&ei, 0, sizeof ei); count = TASK_THREAD_TIMES_INFO_COUNT; err = task_info (p->p_task, TASK_THREAD_TIMES_INFO, (task_info_t) &tti, &count); if (err) memset (&tti, 0, sizeof tti); time_value_add (&bi.user_time, &tti.user_time); time_value_add (&bi.system_time, &tti.system_time); memset (&p->p_rusage, 0, sizeof (struct rusage)); p->p_rusage.ru_utime.tv_sec = bi.user_time.seconds; p->p_rusage.ru_utime.tv_usec = bi.user_time.microseconds; p->p_rusage.ru_stime.tv_sec = bi.system_time.seconds; p->p_rusage.ru_stime.tv_usec = bi.system_time.microseconds; /* These statistics map only approximately. */ p->p_rusage.ru_majflt = ei.pageins; p->p_rusage.ru_minflt = ei.faults - ei.pageins; p->p_rusage.ru_msgsnd = ei.messages_sent; /* Mach IPC, not SysV IPC */ p->p_rusage.ru_msgrcv = ei.messages_received; /* ditto */ }
/* * Return a Python tuple (user_time, kernel_time) */ static PyObject* get_cpu_times(PyObject* self, PyObject* args) { long pid; int err; unsigned int info_count = TASK_BASIC_INFO_COUNT; task_port_t task; // = (task_port_t)NULL; time_value_t user_time, system_time; struct task_basic_info tasks_info; struct task_thread_times_info task_times; if (! PyArg_ParseTuple(args, "l", &pid)) { return NULL; } /* task_for_pid() requires special privileges * "This function can be called only if the process is owned by the * procmod group or if the caller is root." * - http://developer.apple.com/documentation/MacOSX/Conceptual/universal_binary/universal_binary_tips/chapter_5_section_19.html */ err = task_for_pid(mach_task_self(), pid, &task); if ( err == KERN_SUCCESS) { info_count = TASK_BASIC_INFO_COUNT; err = task_info(task, TASK_BASIC_INFO, (task_info_t)&tasks_info, &info_count); if (err != KERN_SUCCESS) { // errcode 4 is "invalid argument" (access denied) if (err == 4) { return AccessDenied(); } // otherwise throw a runtime error with appropriate error code return PyErr_Format(PyExc_RuntimeError, "task_info(TASK_BASIC_INFO) failed"); } info_count = TASK_THREAD_TIMES_INFO_COUNT; err = task_info(task, TASK_THREAD_TIMES_INFO, (task_info_t)&task_times, &info_count); if (err != KERN_SUCCESS) { // errcode 4 is "invalid argument" (access denied) if (err == 4) { return AccessDenied(); } return PyErr_Format(PyExc_RuntimeError, "task_info(TASK_BASIC_INFO) failed"); } } else { // task_for_pid failed if (! pid_exists(pid) ) { return NoSuchProcess(); } // pid exists, so return AccessDenied error since task_for_pid() failed return AccessDenied(); } float user_t = -1.0; float sys_t = -1.0; user_time = tasks_info.user_time; system_time = tasks_info.system_time; time_value_add(&user_time, &task_times.user_time); time_value_add(&system_time, &task_times.system_time); user_t = (float)user_time.seconds + ((float)user_time.microseconds / 1000000.0); sys_t = (float)system_time.seconds + ((float)system_time.microseconds / 1000000.0); return Py_BuildValue("(dd)", user_t, sys_t); }
void act_deallocate( thread_act_t act) { task_t task; thread_t thread; void *task_proc; if (act == NULL) return; act_lock(act); if (--act->act_ref_count > 0) { act_unlock(act); return; } assert(!act->active); thread = act->thread; assert(thread != NULL); thread->top_act = NULL; act_unlock(act); task = act->task; task_lock(task); task_proc = task->bsd_info; { time_value_t user_time, system_time; thread_read_times(thread, &user_time, &system_time); time_value_add(&task->total_user_time, &user_time); time_value_add(&task->total_system_time, &system_time); queue_remove(&task->threads, act, thread_act_t, task_threads); act->task_threads.next = NULL; task->thread_count--; task->res_thread_count--; } task_unlock(task); act_prof_deallocate(act); ipc_thr_act_terminate(act); #ifdef MACH_BSD { extern void uthread_free(task_t, void *, void *, void *); void *ut = act->uthread; uthread_free(task, act, ut, task_proc); act->uthread = NULL; } #endif /* MACH_BSD */ task_deallocate(task); thread_deallocate(thread); }