Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
#endif
/* Time counting */
#define MONO_PROFILER_GET_CURRENT_TIME(t) {\
struct timeval current_time;\
gettimeofday (&current_time, NULL);\
(t) = (((guint64)current_time.tv_sec) * 1000000) + current_time.tv_usec;\
} while (0)
static gboolean use_fast_timer = FALSE;
#if (defined(__i386__) || defined(__x86_64__)) && ! defined(HOST_WIN32)
#if defined(__i386__)
static const guchar cpuid_impl [] = {
0x55, /* push %ebp */
0x89, 0xe5, /* mov %esp,%ebp */
0x53 /* push %ebx */
0x8b, 0x45, 0x08, /* mov 0x8(%ebp),%eax */
0x0f, 0xa2, /* cpuid */
0x50, /* push %eax */
0x8b, 0x45, 0x10, /* mov 0x10(%ebp),%eax */
0x89, 0x18, /* mov %ebx,(%eax) */
0x8b, 0x45, 0x14, /* mov 0x14(%ebp),%eax */
0x89, 0x08, /* mov %ecx,(%eax) */
0x8b, 0x45, 0x18, /* mov 0x18(%ebp),%eax */
0x89, 0x10, /* mov %edx,(%eax) */
0x58, /* pop %eax */
0x8b, 0x55, 0x0c, /* mov 0xc(%ebp),%edx */
0x89, 0x02, /* mov %eax,(%edx) */
0x5b, /* pop %ebx */
0xc9, /* leave */
0xc3, /* ret */
};
typedef void (*CpuidFunc) (int id, int* p_eax, int* p_ebx, int* p_ecx, int* p_edx);
static int
cpuid (int id, int* p_eax, int* p_ebx, int* p_ecx, int* p_edx) {
int have_cpuid = 0;
#ifndef _MSC_VER
__asm__ __volatile__ (
"pushfl\n"
"popl %%eax\n"
"movl %%eax, %%edx\n"
"xorl $0x200000, %%eax\n"
"pushl %%eax\n"
"popfl\n"
"pushfl\n"
"popl %%eax\n"
"xorl %%edx, %%eax\n"
"andl $0x200000, %%eax\n"
"movl %%eax, %0"
: "=r" (have_cpuid)
:
: "%eax", "%edx"
);
#else
__asm {
pushfd
pop eax
mov edx, eax
xor eax, 0x200000
push eax
popfd
pushfd
pop eax
xor eax, edx
and eax, 0x200000
mov have_cpuid, eax
}
#endif
if (have_cpuid) {
CpuidFunc func = (CpuidFunc) cpuid_impl;
func (id, p_eax, p_ebx, p_ecx, p_edx);
/*
* * We use this approach because of issues with gcc and pic code, see:
* * http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=7329
* __asm__ __volatile__ ("cpuid"
* : "=a" (*p_eax), "=b" (*p_ebx), "=c" (*p_ecx), "=d" (*p_edx)
* : "a" (id));
**/
return 1;
}
return 0;
}
#ifdef __MACH__
#include <sys/time.h>
//clock_gettime is not implemented on OSX
int clock_gettime(int /*clk_id*/, struct timespec* t) {
struct timeval now;
int rv = gettimeofday(&now, NULL);
if (rv) return rv;
t->tv_sec = now.tv_sec;
t->tv_nsec = now.tv_usec * 1000;
return 0;
}
#endif
static void detect_fast_timer (void) {
int p_eax, p_ebx, p_ecx, p_edx;
if (cpuid (0x1, &p_eax, &p_ebx, &p_ecx, &p_edx)) {
if (p_edx & 0x10) {
use_fast_timer = TRUE;
} else {
use_fast_timer = FALSE;
}
} else {
use_fast_timer = FALSE;
}
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.