Beispiel #1
0
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 */
}
Beispiel #2
0
/*
 * 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);
}
Beispiel #3
0
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);
}