summaryrefslogtreecommitdiff
path: root/src/common/timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/timer.c')
-rw-r--r--src/common/timer.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/src/common/timer.c b/src/common/timer.c
index 143d2ddce..190e41eaf 100644
--- a/src/common/timer.c
+++ b/src/common/timer.c
@@ -100,11 +100,52 @@ char* search_timer_func_list(TimerFunc func)
* Get tick time
*----------------------------*/
+#if defined(ENABLE_RDTSC)
+static uint64 RDTSC_BEGINTICK = 0, RDTSC_CLOCK = 0;
+
+static __inline uint64 _rdtsc(){
+ register union{
+ uint64 qw;
+ uint32 dw[2];
+ } t;
+
+ asm volatile("rdtsc":"=a"(t.dw[0]), "=d"(t.dw[1]) );
+
+ return t.qw;
+}
+
+static void rdtsc_calibrate(){
+ uint64 t1, t2;
+ int32 i;
+
+ ShowStatus("Calibrating Timer Source, please wait... ");
+
+ RDTSC_CLOCK = 0;
+
+ for(i = 0; i < 5; i++){
+ t1 = _rdtsc();
+ usleep(1000000); //1000 MS
+ t2 = _rdtsc();
+ RDTSC_CLOCK += (t2 - t1) / 1000;
+ }
+ RDTSC_CLOCK /= 5;
+
+ RDTSC_BEGINTICK = _rdtsc();
+
+ ShowMessage(" done. (Frequency: %u Mhz)\n", (uint32)(RDTSC_CLOCK/1000) );
+}
+
+#endif
+
/// platform-abstracted tick retrieval
static unsigned int tick(void)
{
#if defined(WIN32)
return GetTickCount();
+#elif defined(ENABLE_RDTSC)
+ //
+ return (unsigned int)((_rdtsc() - RDTSC_BEGINTICK) / RDTSC_CLOCK);
+ //
#elif (defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0 && defined(_POSIX_MONOTONIC_CLOCK) /* posix compliant */) || (defined(__FreeBSD_cc_version) && __FreeBSD_cc_version >= 500005 /* FreeBSD >= 5.1.0 */)
struct timespec tval;
clock_gettime(CLOCK_MONOTONIC, &tval);
@@ -368,6 +409,10 @@ unsigned long get_uptime(void)
void timer_init(void)
{
+#if defined(ENABLE_RDTSC)
+ rdtsc_calibrate();
+#endif
+
time(&start_time);
}