3

I need to measure the cpu usage of individual threads on darwin. On linux I use getrusage(RUSAGE_THREAD, ...) but it's not available on darwin.

craig65535
  • 3,439
  • 1
  • 23
  • 49
melisgl
  • 308
  • 2
  • 13

2 Answers2

2

Use thread_info and pass in mach_thread_self() to get CPU usage times for the current thread. The following will convert these into a struct rusage.

#include <mach/mach.h>
#include <sys/resource.h>
#include <errno.h>

int getrusage_thread(struct rusage *rusage)
{
    int ret = -1;
    thread_basic_info_data_t info = { 0 };
    mach_msg_type_number_t info_count = THREAD_BASIC_INFO_COUNT;
    kern_return_t kern_err;

    mach_port_t port = mach_thread_self();
    kern_err = thread_info(port,
                           THREAD_BASIC_INFO,
                           (thread_info_t)&info,
                           &info_count);
    mach_port_deallocate(mach_task_self(), port);

    if (kern_err == KERN_SUCCESS) {
        memset(rusage, 0, sizeof(struct rusage));
        rusage->ru_utime.tv_sec = info.user_time.seconds;
        rusage->ru_utime.tv_usec = info.user_time.microseconds;
        rusage->ru_stime.tv_sec = info.system_time.seconds;
        rusage->ru_stime.tv_usec = info.system_time.microseconds;
        ret = 0;
    } else {
        errno = EINVAL;
    }

    return ret;
}

craig65535
  • 3,439
  • 1
  • 23
  • 49
2

RUSAGE_THREAD flag of getrusage is Linux-specific.

getrusage of xnu does output only per-process sum.

Information about usage times of each thread is maintained in task_basic_info struct of each thread.

Documentation is here http://www.gnu.org/software/hurd/gnumach-doc/Task-Information.html

Here is a simple example of how to get task_basic_info struct http://blog.kuriositaet.de/?p=257

 task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&t_info, &t_info_count)
osgx
  • 90,338
  • 53
  • 357
  • 513
  • 2
    when I tried this, the user_time and system_time fields were both 0 in the task_basic_info struct. However, it would work if I asked for the task_thread_times_info struct instead (TASK_THREAD_TIMES_INFO). The documentation mentions that the counters are for terminated threads and live threads respectively. – Arvid Oct 17 '11 at 17:00
  • task_info returns times for the entire task (all active threads), not the current thread. – craig65535 Apr 04 '19 at 00:00