Mat
Mat

Reputation: 1091

Get current pthread cpu usage Mac OS X

How can I get a thread's cpu time from the thread itself in Mac OS X ? For linux, what I do is getrusage(RUSAGE_THREAD, &ru) but this solution isn't available for Mac OS X.

I came across this question but I don't know how to adapt it for my purpose (I'm not familiar with Mac OS X's internals. I am not even sure pthread thread == mach thread).

Upvotes: 4

Views: 2938

Answers (3)

inopinatus
inopinatus

Reputation: 3779

You can portably use clock_gettime(3) with the CLOCK_THREAD_CPUTIME_ID clock. Minimally:

#include <stdio.h>
#include <time.h>

// ...

void print_thread_usage(void) {
    struct timespec cpu;
    clock_gettime(CLOCK_THREAD_CPUTIME_ID, &cpu);
    printf("used %.6f seconds\n", cpu.tv_sec + cpu.tv_nsec/1e9f);
}

Available since MacOS 10.12 (2016) and Linux 2.6.12 (2005).

Upvotes: 1

Lucas Cr&#228;mer
Lucas Cr&#228;mer

Reputation: 176

If you are using the pthread api anyway, his should do the job as well:

#include <unistd.h>
#include <pthread.h>
#include <libproc.h>
#include <stdio.h>

[...]

uint64_t tid;
pthread_threadid_np(NULL, &tid);
struct proc_threadinfo pth;
if (PROC_PIDTHREADINFO_SIZE ==
      proc_pidinfo(getpid(), PROC_PIDTHREADID64INFO, tid, &pth,
                   PROC_PIDTHREADINFO_SIZE)) {
  printf("user time in ns: %llu\nsystem time in ns: %llu\n",
         pth.pth_user_time, pth.pth_system_time);
}

Upvotes: 3

Mat
Mat

Reputation: 1091

This is what I ended up with:

#include <mach/mach_init.h>
#include <mach/thread_act.h>
#include <mach/mach_port.h>

[...]

mach_port_t thread;
kern_return_t kr;
mach_msg_type_number_t count;
thread_basic_info_data_t info;

thread = mach_thread_self();

count = THREAD_BASIC_INFO_COUNT;
kr = thread_info(thread, THREAD_BASIC_INFO, (thread_info_t) &info, &count);

if (kr == KERN_SUCCESS && (info.flags & TH_FLAGS_IDLE) == 0) {
    usage->utime.tv_sec  = info.user_time.seconds;
    usage->utime.tv_usec = info.user_time.microseconds;
    usage->stime.tv_sec  = info.system_time.seconds;
    usage->stime.tv_usec = info.system_time.microseconds;
}
else {
    // should not happen
    printf("Could not retreive thread info.");
    bzero(usage, sizeof(struct usage));
}

mach_port_deallocate(mach_task_self(), thread);

I get very different results that what i get with getrusage(RUSAGE_THREAD, &ru) under Linux. So I'm not sure this is the right way.

Upvotes: 6

Related Questions