mirror of
https://github.com/VSadov/Satori.git
synced 2025-06-10 18:11:04 +09:00
Refactor get_time_stamp_ns (#34536)
* Refactor get_time_stamp_ns * Add place holder function for pc to make pc build pass * Add missing header file * Move all time functions to mono-time.c * Make sampling_thread_running a global variable * Pass void* to init, clean_up and get_time function to accormodate different clock ID types for different os, and move back profiler specific function * Add static keyword for local helper function and fix a typo * Change to platform-specific typedef approach * Add missing header file for macOS * Add missing header file for linux * Change header file name * Change header file name one more time * Fix failures on macOS * Update src/mono/mono/utils/mono-time.h Co-Authored-By: Ryan Lucia <ryan@luciaonline.net> Co-authored-by: Ryan Lucia <ryan@luciaonline.net>
This commit is contained in:
commit
ede936d155
4 changed files with 131 additions and 78 deletions
|
@ -70,6 +70,7 @@
|
|||
#include <mono/utils/mono-threads.h>
|
||||
#include <mono/utils/os-event.h>
|
||||
#include <mono/utils/mono-state.h>
|
||||
#include <mono/utils/mono-time.h>
|
||||
#include <mono/mini/debugger-state-machine.h>
|
||||
|
||||
#include "mini.h"
|
||||
|
@ -517,48 +518,11 @@ static volatile gint32 sampling_thread_running;
|
|||
|
||||
#ifdef HOST_DARWIN
|
||||
|
||||
static clock_serv_t sampling_clock_service;
|
||||
static clock_serv_t sampling_clock;
|
||||
|
||||
static void
|
||||
clock_init (MonoProfilerSampleMode mode)
|
||||
clock_init_for_profiler (MonoProfilerSampleMode mode)
|
||||
{
|
||||
kern_return_t ret;
|
||||
|
||||
do {
|
||||
ret = host_get_clock_service (mach_host_self (), SYSTEM_CLOCK, &sampling_clock_service);
|
||||
} while (ret == KERN_ABORTED);
|
||||
|
||||
if (ret != KERN_SUCCESS)
|
||||
g_error ("%s: host_get_clock_service () returned %d", __func__, ret);
|
||||
}
|
||||
|
||||
static void
|
||||
clock_cleanup (void)
|
||||
{
|
||||
kern_return_t ret;
|
||||
|
||||
do {
|
||||
ret = mach_port_deallocate (mach_task_self (), sampling_clock_service);
|
||||
} while (ret == KERN_ABORTED);
|
||||
|
||||
if (ret != KERN_SUCCESS)
|
||||
g_error ("%s: mach_port_deallocate () returned %d", __func__, ret);
|
||||
}
|
||||
|
||||
static guint64
|
||||
clock_get_time_ns (void)
|
||||
{
|
||||
kern_return_t ret;
|
||||
mach_timespec_t mach_ts;
|
||||
|
||||
do {
|
||||
ret = clock_get_time (sampling_clock_service, &mach_ts);
|
||||
} while (ret == KERN_ABORTED);
|
||||
|
||||
if (ret != KERN_SUCCESS)
|
||||
g_error ("%s: clock_get_time () returned %d", __func__, ret);
|
||||
|
||||
return ((guint64) mach_ts.tv_sec * 1000000000) + (guint64) mach_ts.tv_nsec;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -571,7 +535,7 @@ clock_sleep_ns_abs (guint64 ns_abs)
|
|||
then.tv_nsec = ns_abs % 1000000000;
|
||||
|
||||
do {
|
||||
ret = clock_sleep (sampling_clock_service, TIME_ABSOLUTE, then, &remain_unused);
|
||||
ret = clock_sleep (sampling_clock, TIME_ABSOLUTE, then, &remain_unused);
|
||||
|
||||
if (ret != KERN_SUCCESS && ret != KERN_ABORTED)
|
||||
g_error ("%s: clock_sleep () returned %d", __func__, ret);
|
||||
|
@ -580,10 +544,10 @@ clock_sleep_ns_abs (guint64 ns_abs)
|
|||
|
||||
#else
|
||||
|
||||
static clockid_t sampling_posix_clock;
|
||||
static clockid_t sampling_clock;
|
||||
|
||||
static void
|
||||
clock_init (MonoProfilerSampleMode mode)
|
||||
clock_init_for_profiler (MonoProfilerSampleMode mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case MONO_PROFILER_SAMPLE_MODE_PROCESS: {
|
||||
|
@ -601,34 +565,18 @@ clock_init (MonoProfilerSampleMode mode)
|
|||
* those systems, we fall back to CLOCK_MONOTONIC if we get EINVAL.
|
||||
*/
|
||||
if (clock_nanosleep (CLOCK_PROCESS_CPUTIME_ID, TIMER_ABSTIME, &ts, NULL) != EINVAL) {
|
||||
sampling_posix_clock = CLOCK_PROCESS_CPUTIME_ID;
|
||||
sampling_clock = CLOCK_PROCESS_CPUTIME_ID;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
// fallthrough
|
||||
}
|
||||
case MONO_PROFILER_SAMPLE_MODE_REAL: sampling_posix_clock = CLOCK_MONOTONIC; break;
|
||||
case MONO_PROFILER_SAMPLE_MODE_REAL: sampling_clock = CLOCK_MONOTONIC; break;
|
||||
default: g_assert_not_reached (); break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clock_cleanup (void)
|
||||
{
|
||||
}
|
||||
|
||||
static guint64
|
||||
clock_get_time_ns (void)
|
||||
{
|
||||
struct timespec ts;
|
||||
|
||||
if (clock_gettime (sampling_posix_clock, &ts) == -1)
|
||||
g_error ("%s: clock_gettime () returned -1, errno = %d", __func__, errno);
|
||||
|
||||
return ((guint64) ts.tv_sec * 1000000000) + (guint64) ts.tv_nsec;
|
||||
}
|
||||
|
||||
static void
|
||||
clock_sleep_ns_abs (guint64 ns_abs)
|
||||
{
|
||||
|
@ -640,7 +588,7 @@ clock_sleep_ns_abs (guint64 ns_abs)
|
|||
then.tv_nsec = ns_abs % 1000000000;
|
||||
|
||||
do {
|
||||
ret = clock_nanosleep (sampling_posix_clock, TIMER_ABSTIME, &then, NULL);
|
||||
ret = clock_nanosleep (sampling_clock, TIMER_ABSTIME, &then, NULL);
|
||||
|
||||
if (ret != 0 && ret != EINTR)
|
||||
g_error ("%s: clock_nanosleep () returned %d", __func__, ret);
|
||||
|
@ -675,7 +623,7 @@ clock_sleep_ns_abs (guint64 ns_abs)
|
|||
* nanoseconds).
|
||||
*/
|
||||
do {
|
||||
diff = (gint64) ns_abs - (gint64) clock_get_time_ns ();
|
||||
diff = (gint64) ns_abs - (gint64) mono_clock_get_time_ns (sampling_clock);
|
||||
|
||||
if (diff <= 0)
|
||||
break;
|
||||
|
@ -743,16 +691,17 @@ init:
|
|||
goto init;
|
||||
}
|
||||
|
||||
clock_init (mode);
|
||||
mono_clock_init (&sampling_clock);
|
||||
clock_init_for_profiler (mode);
|
||||
|
||||
for (guint64 sleep = clock_get_time_ns (); mono_atomic_load_i32 (&sampling_thread_running); clock_sleep_ns_abs (sleep)) {
|
||||
for (guint64 sleep = mono_clock_get_time_ns (sampling_clock); mono_atomic_load_i32 (&sampling_thread_running); clock_sleep_ns_abs (sleep)) {
|
||||
uint32_t freq;
|
||||
MonoProfilerSampleMode new_mode;
|
||||
|
||||
mono_profiler_get_sample_mode (NULL, &new_mode, &freq);
|
||||
|
||||
if (new_mode != mode) {
|
||||
clock_cleanup ();
|
||||
mono_clock_cleanup (sampling_clock);
|
||||
goto init;
|
||||
}
|
||||
|
||||
|
@ -774,7 +723,7 @@ init:
|
|||
} FOREACH_THREAD_SAFE_END
|
||||
}
|
||||
|
||||
clock_cleanup ();
|
||||
mono_clock_cleanup (sampling_clock);
|
||||
|
||||
done:
|
||||
mono_atomic_store_i32 (&sampling_thread_exiting, 1);
|
||||
|
|
|
@ -70,6 +70,7 @@
|
|||
#include <mono/utils/mono-compiler.h>
|
||||
#include <mono/utils/mono-proclib.h>
|
||||
#include <mono/utils/mono-state.h>
|
||||
#include <mono/utils/mono-time.h>
|
||||
#include <mono/metadata/w32handle.h>
|
||||
#include <mono/metadata/threadpool.h>
|
||||
|
||||
|
@ -1934,6 +1935,7 @@ static FILE *perf_dump_file;
|
|||
static mono_mutex_t perf_dump_mutex;
|
||||
static void *perf_dump_mmap_addr = MAP_FAILED;
|
||||
static guint32 perf_dump_pid;
|
||||
static clockid_t clock_id = CLOCK_MONOTONIC;
|
||||
|
||||
enum {
|
||||
JIT_DUMP_MAGIC = 0x4A695444,
|
||||
|
@ -1984,7 +1986,6 @@ typedef struct
|
|||
} JitCodeLoadRecord;
|
||||
|
||||
static void add_file_header_info (FileHeader *header);
|
||||
static guint64 get_time_stamp_ns (void);
|
||||
static void add_basic_JitCodeLoadRecord_info (JitCodeLoadRecord *record);
|
||||
|
||||
void
|
||||
|
@ -2025,18 +2026,10 @@ add_file_header_info (FileHeader *header)
|
|||
header->elf_mach = ELF_MACHINE;
|
||||
header->pad1 = 0;
|
||||
header->pid = perf_dump_pid;
|
||||
header->timestamp = get_time_stamp_ns ();
|
||||
header->timestamp = mono_clock_get_time_ns (clock_id);
|
||||
header->flags = 0;
|
||||
}
|
||||
|
||||
static guint64
|
||||
get_time_stamp_ns (void)
|
||||
{
|
||||
struct timespec ts;
|
||||
int result = clock_gettime (CLOCK_MONOTONIC, &ts);
|
||||
return ts.tv_sec * 1000000000ULL + ts.tv_nsec;
|
||||
}
|
||||
|
||||
void
|
||||
mono_emit_jit_dump (MonoJitInfo *jinfo, gpointer code)
|
||||
{
|
||||
|
@ -2059,7 +2052,7 @@ mono_emit_jit_dump (MonoJitInfo *jinfo, gpointer code)
|
|||
|
||||
// TODO: write debugInfo and unwindInfo immediately before the JitCodeLoadRecord (while lock is held).
|
||||
|
||||
record.header.timestamp = get_time_stamp_ns ();
|
||||
record.header.timestamp = mono_clock_get_time_ns (clock_id);
|
||||
|
||||
fwrite (&record, sizeof (record), 1, perf_dump_file);
|
||||
fwrite (jinfo->d.method->name, nameLen + 1, 1, perf_dump_file);
|
||||
|
@ -2073,7 +2066,7 @@ static void
|
|||
add_basic_JitCodeLoadRecord_info (JitCodeLoadRecord *record)
|
||||
{
|
||||
record->header.id = JIT_CODE_LOAD;
|
||||
record->header.timestamp = get_time_stamp_ns ();
|
||||
record->header.timestamp = mono_clock_get_time_ns (clock_id);
|
||||
record->pid = perf_dump_pid;
|
||||
record->tid = syscall (SYS_gettid);
|
||||
}
|
||||
|
|
|
@ -15,6 +15,12 @@
|
|||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#ifdef HOST_DARWIN
|
||||
#include <mach/clock.h>
|
||||
#include <mach/mach.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include <mono/utils/mono-time.h>
|
||||
#include <mono/utils/atomic.h>
|
||||
|
||||
|
@ -229,3 +235,94 @@ mono_100ns_datetime_from_timeval (struct timeval tv)
|
|||
|
||||
#endif
|
||||
|
||||
#if defined(HOST_DARWIN)
|
||||
|
||||
void
|
||||
mono_clock_init (mono_clock_id_t *clk_id)
|
||||
{
|
||||
kern_return_t ret;
|
||||
|
||||
do {
|
||||
ret = host_get_clock_service (mach_host_self (), SYSTEM_CLOCK, clk_id);
|
||||
} while (ret == KERN_ABORTED);
|
||||
|
||||
if (ret != KERN_SUCCESS)
|
||||
g_error ("%s: host_get_clock_service () returned %d", __func__, ret);
|
||||
}
|
||||
|
||||
void
|
||||
mono_clock_cleanup (mono_clock_id_t clk_id)
|
||||
{
|
||||
kern_return_t ret;
|
||||
|
||||
do {
|
||||
ret = mach_port_deallocate (mach_task_self (), clk_id);
|
||||
} while (ret == KERN_ABORTED);
|
||||
|
||||
if (ret != KERN_SUCCESS)
|
||||
g_error ("%s: mach_port_deallocate () returned %d", __func__, ret);
|
||||
}
|
||||
|
||||
guint64
|
||||
mono_clock_get_time_ns (mono_clock_id_t clk_id)
|
||||
{
|
||||
kern_return_t ret;
|
||||
mach_timespec_t mach_ts;
|
||||
|
||||
do {
|
||||
ret = clock_get_time (clk_id, &mach_ts);
|
||||
} while (ret == KERN_ABORTED);
|
||||
|
||||
if (ret != KERN_SUCCESS)
|
||||
g_error ("%s: clock_get_time () returned %d", __func__, ret);
|
||||
|
||||
return ((guint64) mach_ts.tv_sec * 1000000000) + (guint64) mach_ts.tv_nsec;
|
||||
}
|
||||
|
||||
#elif defined(__linux__)
|
||||
|
||||
void
|
||||
mono_clock_init (mono_clock_id_t *clk_id)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
mono_clock_cleanup (mono_clock_id_t clk_id)
|
||||
{
|
||||
}
|
||||
|
||||
guint64
|
||||
mono_clock_get_time_ns (mono_clock_id_t clk_id)
|
||||
{
|
||||
struct timespec ts;
|
||||
|
||||
if (clock_gettime (clk_id, &ts) == -1)
|
||||
g_error ("%s: clock_gettime () returned -1, errno = %d", __func__, errno);
|
||||
|
||||
return ((guint64) ts.tv_sec * 1000000000) + (guint64) ts.tv_nsec;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void
|
||||
mono_clock_init (mono_clock_id_t *clk_id)
|
||||
{
|
||||
// TODO: need to implement this function for PC
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
void
|
||||
mono_clock_cleanup (mono_clock_id_t clk_id)
|
||||
{
|
||||
// TODO: need to implement this function for PC
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
guint64
|
||||
mono_clock_get_time_ns (mono_clock_id_t clk_id)
|
||||
{
|
||||
// TODO: need to implement time stamp function for PC
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -29,6 +29,20 @@ gint64 mono_100ns_datetime (void);
|
|||
gint64 mono_100ns_datetime_from_timeval (struct timeval tv);
|
||||
#endif
|
||||
|
||||
#if defined(HOST_DARWIN)
|
||||
#include <mach/clock.h>
|
||||
typedef clock_serv_t mono_clock_id_t;
|
||||
#elif defined(__linux__)
|
||||
#include <sys/types.h>
|
||||
typedef clockid_t mono_clock_id_t;
|
||||
#else
|
||||
typedef void *mono_clock_id_t;
|
||||
#endif
|
||||
|
||||
void mono_clock_init (mono_clock_id_t *clk_id);
|
||||
void mono_clock_cleanup (mono_clock_id_t clk_id);
|
||||
guint64 mono_clock_get_time_ns (mono_clock_id_t clk_id);
|
||||
|
||||
/* Stopwatch class for internal runtime use */
|
||||
typedef struct {
|
||||
gint64 start, stop;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue