Created
May 18, 2017 12:50
-
-
Save gregoryyoung/a6f69f20e888fffaa90181cf3cd8392b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#endif | |
/* Time counting */ | |
#define MONO_PROFILER_GET_CURRENT_TIME(t) {\ | |
struct timeval current_time;\ | |
gettimeofday (¤t_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