+/*
+ * utils.c: log profiler and reporter utils
+ *
+ * We have here the minimal needed portability functions: we can't depend
+ * on the ones provided by the runtime, since they are internal and,
+ * especially mprof-report is an external program.
+ * Note also that we don't take a glib/eglib dependency here for mostly
+ * the same reason (but also because we need tight control in the profiler
+ * over memory allocation, which needs to work with the world stopped).
+ *
+ * Author:
+ * Paolo Molaro (lupus@ximian.com)
+ *
+ * Copyright 2010 Novell, Inc (http://www.novell.com)
+ */
+#include "utils.h"
#include <stdlib.h>
-#include <inttypes.h>
#include <time.h>
#include <stdio.h>
#include <string.h>
+#include <unistd.h>
#ifdef HOST_WIN32
#include <windows.h>
#else
#include <sched.h>
#endif
-#include "utils.h"
-//#ifdef HAVE_SYS_TIME_H
+#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
-//#endif
-//#if HAVE_SYS_MMAN_H
+#endif
+#if HAVE_SYS_MMAN_H
#include <sys/mman.h>
-//#endif
+#endif
#if defined(__APPLE__)
#include <mach/mach_time.h>
static mach_timebase_info_data_t timebase_info;
#endif
-#ifndef MAP_ANON
+#ifndef MAP_ANONYMOUS
#define MAP_ANONYMOUS MAP_ANON
#endif
#define TICKS_PER_SEC 1000000000LL
-#if (defined(TARGET_X86) || defined(TARGET_AMD64)) && defined(__linux__)
+#if (defined(TARGET_X86) || defined(TARGET_AMD64)) && defined(__linux__) && defined(HAVE_SCHED_GETCPU)
#define HAVE_RDTSC 1
#endif
#ifdef HOST_WIN32
static CRITICAL_SECTION log_lock;
+static LARGE_INTEGER pcounter_freq;
#else
static pthread_mutex_t log_lock = PTHREAD_MUTEX_INITIALIZER;
#endif
+static int timer_overhead = 0;
static uint64_t time_inc = 0;
typedef uint64_t (*TimeFunc)(void);
#if defined(__APPLE__)
uint64_t time = mach_absolute_time ();
- time *= info.numer;
- time /= info.denom;
+ time *= timebase_info.numer;
+ time /= timebase_info.denom;
return time;
-#else
+#elif defined(HOST_WIN32)
+ LARGE_INTEGER value;
+ QueryPerformanceCounter (&value);
+ return value.QuadPart * TICKS_PER_SEC / pcounter_freq.QuadPart;
+#elif defined(CLOCK_MONOTONIC)
struct timespec tspec;
clock_gettime (CLOCK_MONOTONIC, &tspec);
return ((uint64_t)tspec.tv_sec * TICKS_PER_SEC + tspec.tv_nsec);
+#else
+ struct timeval tv;
+ gettimeofday (&tv, NULL);
+ return ((uint64_t)tv.tv_sec * TICKS_PER_SEC + tv.tv_usec * 1000);
#endif
}
void
utils_init (int fast_time)
{
+ int i;
+ uint64_t time_start, time_end;
TLS_INIT (tls_data);
#ifdef HOST_WIN32
InitializeCriticalSection (&log_lock);
+ QueryPerformanceFrequency (&pcounter_freq);
#endif
#if defined (__APPLE__)
mach_timebase_info (&timebase_info);
} else {
time_func = clock_time;
}
+ time_start = time_func ();
+ for (i = 0; i < 256; ++i)
+ time_func ();
+ time_end = time_func ();
+ timer_overhead = (time_end - time_start) / 256;
+}
+
+int
+get_timer_overhead (void)
+{
+ return timer_overhead;
}
uint64_t
#endif
}
+uintptr_t
+process_id (void)
+{
+#ifdef HOST_WIN32
+ return 0; /* FIXME */
+#else
+ return (uintptr_t)getpid ();
+#endif
+}
+