Bug 1142457 - Compute stopwatch durations per thread on MacOS X. r=jandem, r=areinald

--HG--
extra : rebase_source : c7abb31b57fa865e120942f731438ba9df9697fd
This commit is contained in:
David Rajchenbach-Teller 2015-04-03 11:19:58 +02:00
Родитель ef19488c6f
Коммит e1ec28cb96
1 изменённых файлов: 38 добавлений и 15 удалений

Просмотреть файл

@ -53,12 +53,14 @@
#include "vm/ScopeObject-inl.h" #include "vm/ScopeObject-inl.h"
#include "vm/Stack-inl.h" #include "vm/Stack-inl.h"
#if defined(XP_UNIX) #if defined(XP_MACOSX)
#include <mach/mach.h>
#elif defined(XP_UNIX)
#include <sys/resource.h> #include <sys/resource.h>
#elif defined(XP_WIN) #elif defined(XP_WIN)
#include <processthreadsapi.h> #include <processthreadsapi.h>
#include <windows.h> #include <windows.h>
#endif // defined(XP_UNIX) || defined(XP_WIN) #endif // defined(XP_MACOSX) || defined(XP_UNIX) || defined(XP_WIN)
using namespace js; using namespace js;
using namespace js::gc; using namespace js::gc;
@ -522,31 +524,52 @@ struct AutoStopwatch final
} }
} }
// Get the OS-reported time spent in userland/systemland, // Get the OS-reported time spent in userland/systemland, in
// in microseconds. // microseconds. On most platforms, this data is per-thread,
bool getTimes(uint64_t *userTime, uint64_t *systemTime) const { // but on some platforms we need to fall back to per-process.
bool getTimes(uint64_t* userTime, uint64_t* systemTime) const {
MOZ_ASSERT(userTime); MOZ_ASSERT(userTime);
MOZ_ASSERT(systemTime); MOZ_ASSERT(systemTime);
#if defined(XP_UNIX) #if defined(XP_MACOSX)
// On MacOS X, to get we per-thread data, we need to
// reach into the kernel.
mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT;
thread_basic_info_data_t info;
mach_port_t port = mach_thread_self();
kern_return_t err =
thread_info(/* [in] targeted thread*/ port,
/* [in] nature of information*/ THREAD_BASIC_INFO,
/* [out] thread information */ (thread_info_t)&info,
/* [inout] number of items */ &count);
// We do not need ability to communicate with the thread, so
// let's release the port.
mach_port_deallocate(mach_task_self(), port);
if (err != KERN_SUCCESS)
return false;
*userTime = info.user_time.microseconds + info.user_time.seconds * 1000000;
*systemTime = info.system_time.microseconds + info.system_time.seconds * 1000000;
#elif defined(XP_UNIX)
struct rusage rusage; struct rusage rusage;
#if defined(RUSAGE_THREAD) #if defined(RUSAGE_THREAD)
// Under Linux, we can obtain per-thread statistics // Under Linux, we can obtain per-thread statistics
int err = getrusage(RUSAGE_THREAD, &rusage); int err = getrusage(RUSAGE_THREAD, &rusage);
#else #else
// Under other Unices, including MacOS X, we need to // Under other Unices, we need to do with more noisy
// do with more noisy per-process statistics. // per-process statistics.
int err = getrusage(RUSAGE_SELF, &rusage); int err = getrusage(RUSAGE_SELF, &rusage);
#endif // defined(RUSAGE_THREAD) #endif // defined(RUSAGE_THREAD)
MOZ_ASSERT(!err);
if (err) if (err)
return false; return false;
*userTime = rusage.ru_utime.tv_usec *userTime = rusage.ru_utime.tv_usec + rusage.ru_utime.tv_sec * 1000000;
+ rusage.ru_utime.tv_sec * 1000000; *systemTime = rusage.ru_stime.tv_usec + rusage.ru_stime.tv_sec * 1000000;
*systemTime = rusage.ru_stime.tv_usec
+ rusage.ru_stime.tv_sec * 1000000;
#elif defined(XP_WIN) #elif defined(XP_WIN)
// Under Windows, we can obtain per-thread statistics, // Under Windows, we can obtain per-thread statistics,
@ -559,7 +582,7 @@ struct AutoStopwatch final
BOOL success = GetThreadTimes(GetCurrentThread(), BOOL success = GetThreadTimes(GetCurrentThread(),
&creationFileTime, &exitFileTime, &creationFileTime, &exitFileTime,
&kernelFileTime, &userFileTime); &kernelFileTime, &userFileTime);
MOZ_ASSERT(success);
if (!success) if (!success)
return false; return false;
@ -575,7 +598,7 @@ struct AutoStopwatch final
// Convert 100 ns to 1 us, make sure that the result is monotonic // Convert 100 ns to 1 us, make sure that the result is monotonic
*userTime = runtime_-> stopwatch.userTimeFix.monotonize(userTimeInt.QuadPart / 10); *userTime = runtime_-> stopwatch.userTimeFix.monotonize(userTimeInt.QuadPart / 10);
#endif // defined(XP_UNIX) || defined(XP_WIN) #endif // defined(XP_MACOSX) || defined(XP_UNIX) || defined(XP_WIN)
return true; return true;
} }