Added high resolution timing API: SDL_GetPerformanceCounter(), SDL_GetPerformanceFrequency()
authorSam Lantinga <slouken@libsdl.org>
Fri, 25 Mar 2011 14:45:04 -0700
changeset 5514 6bd701987ba9
parent 5513 0a72c9c29099
child 5515 0fcf231a6e74
Added high resolution timing API: SDL_GetPerformanceCounter(), SDL_GetPerformanceFrequency()
include/SDL_timer.h
src/timer/beos/SDL_systimer.c
src/timer/dummy/SDL_systimer.c
src/timer/nds/SDL_systimer.c
src/timer/unix/SDL_systimer.c
src/timer/wince/SDL_systimer.c
src/timer/windows/SDL_systimer.c
test/testtimer.c
--- a/include/SDL_timer.h	Fri Mar 25 13:48:48 2011 -0700
+++ b/include/SDL_timer.h	Fri Mar 25 14:45:04 2011 -0700
@@ -48,6 +48,16 @@
 extern DECLSPEC Uint32 SDLCALL SDL_GetTicks(void);
 
 /**
+ * \brief Get the current value of the high resolution counter
+ */
+extern DECLSPEC Uint64 SDLCALL SDL_GetPerformanceCounter(void);
+
+/**
+ * \brief Get the count per second of the high resolution counter
+ */
+extern DECLSPEC Uint64 SDLCALL SDL_GetPerformanceFrequency(void);
+
+/**
  * \brief Wait a specified number of milliseconds before returning.
  */
 extern DECLSPEC void SDLCALL SDL_Delay(Uint32 ms);
--- a/src/timer/beos/SDL_systimer.c	Fri Mar 25 13:48:48 2011 -0700
+++ b/src/timer/beos/SDL_systimer.c	Fri Mar 25 14:45:04 2011 -0700
@@ -42,6 +42,18 @@
     return ((system_time() - start) / 1000);
 }
 
+Uint64
+SDL_GetPerformanceCounter(void)
+{
+    return system_time();
+}
+
+Uint64
+SDL_GetPerformanceFrequency(void)
+{
+    return 1000000;
+}
+
 void
 SDL_Delay(Uint32 ms)
 {
--- a/src/timer/dummy/SDL_systimer.c	Fri Mar 25 13:48:48 2011 -0700
+++ b/src/timer/dummy/SDL_systimer.c	Fri Mar 25 14:45:04 2011 -0700
@@ -37,6 +37,18 @@
     return 0;
 }
 
+Uint64
+SDL_GetPerformanceCounter(void)
+{
+    return SDL_GetTicks();
+}
+
+Uint64
+SDL_GetPerformanceFrequency(void)
+{
+    return 1000;
+}
+
 void
 SDL_Delay(Uint32 ms)
 {
--- a/src/timer/nds/SDL_systimer.c	Fri Mar 25 13:48:48 2011 -0700
+++ b/src/timer/nds/SDL_systimer.c	Fri Mar 25 14:45:04 2011 -0700
@@ -52,6 +52,18 @@
     return timer_ticks;
 }
 
+Uint64
+SDL_GetPerformanceCounter(void)
+{
+    return SDL_GetTicks();
+}
+
+Uint64
+SDL_GetPerformanceFrequency(void)
+{
+    return 1000;
+}
+
 void
 SDL_Delay(Uint32 ms)
 {
--- a/src/timer/unix/SDL_systimer.c	Fri Mar 25 13:48:48 2011 -0700
+++ b/src/timer/unix/SDL_systimer.c	Fri Mar 25 14:45:04 2011 -0700
@@ -64,6 +64,7 @@
 #if HAVE_CLOCK_GETTIME
     Uint32 ticks;
     struct timespec now;
+
     clock_gettime(CLOCK_MONOTONIC, &now);
     ticks =
         (now.tv_sec - start.tv_sec) * 1000 + (now.tv_nsec -
@@ -72,6 +73,7 @@
 #else
     Uint32 ticks;
     struct timeval now;
+
     gettimeofday(&now, NULL);
     ticks =
         (now.tv_sec - start.tv_sec) * 1000 + (now.tv_usec -
@@ -80,6 +82,40 @@
 #endif
 }
 
+Uint64
+SDL_GetPerformanceCounter(void)
+{
+#if HAVE_CLOCK_GETTIME
+    Uint64 ticks;
+    struct timespec now;
+
+    clock_gettime(CLOCK_MONOTONIC, &now);
+    ticks = now.tv_sec;
+    ticks *= 1000000000;
+    ticks += now.tv_nsec;
+    return (ticks);
+#else
+    Uint64 ticks;
+    struct timeval now;
+
+    gettimeofday(&now, NULL);
+    ticks = now.tv_sec;
+    ticks *= 1000000;
+    ticks += now.tv_usec;
+    return (ticks);
+#endif
+}
+
+Uint64
+SDL_GetPerformanceFrequency(void)
+{
+#if HAVE_CLOCK_GETTIME
+    return 1000000000;
+#else
+    return 1000000;
+#endif
+}
+
 void
 SDL_Delay(Uint32 ms)
 {
--- a/src/timer/wince/SDL_systimer.c	Fri Mar 25 13:48:48 2011 -0700
+++ b/src/timer/wince/SDL_systimer.c	Fri Mar 25 14:45:04 2011 -0700
@@ -87,6 +87,18 @@
     return ((Uint32) wce_rel_ticks());
 }
 
+Uint64
+SDL_GetPerformanceCounter(void)
+{
+    return SDL_GetTicks();
+}
+
+Uint64
+SDL_GetPerformanceFrequency(void)
+{
+    return 1000;
+}
+
 /* Give up approx. givem milliseconds to the OS. */
 void
 SDL_Delay(Uint32 ms)
--- a/src/timer/windows/SDL_systimer.c	Fri Mar 25 13:48:48 2011 -0700
+++ b/src/timer/windows/SDL_systimer.c	Fri Mar 25 14:45:04 2011 -0700
@@ -99,6 +99,28 @@
     return (ticks);
 }
 
+Uint64
+SDL_GetPerformanceCounter(void)
+{
+    LARGE_INTEGER counter;
+
+    if (!QueryPerformanceCounter(&counter)) {
+        return SDL_GetTicks();
+    }
+    return counter.QuadPart;
+}
+
+Uint64
+SDL_GetPerformanceFrequency(void)
+{
+    LARGE_INTEGER frequency;
+
+    if (!QueryPerformanceFrequency(&frequency)) {
+        return 1000;
+    }
+    return frequency.QuadPart;
+}
+
 void
 SDL_Delay(Uint32 ms)
 {
--- a/test/testtimer.c	Fri Mar 25 13:48:48 2011 -0700
+++ b/test/testtimer.c	Fri Mar 25 14:45:04 2011 -0700
@@ -29,8 +29,9 @@
 int
 main(int argc, char *argv[])
 {
-    int desired;
+    int i, desired;
     SDL_TimerID t1, t2, t3;
+    Uint64 start, now;
 
     if (SDL_Init(SDL_INIT_TIMER) < 0) {
         fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
@@ -85,6 +86,15 @@
     SDL_RemoveTimer(t2);
     SDL_RemoveTimer(t3);
 
+    start = SDL_GetPerformanceCounter();
+    for (i = 0; i < 1000000; ++i) {
+        ticktock(0);
+    }
+    now = SDL_GetPerformanceCounter();
+    printf("1 million iterations of ticktock took %f ms\n", (double)((now - start)*1000) / SDL_GetPerformanceFrequency());
+
     SDL_Quit();
     return (0);
 }
+
+/* vi: set ts=4 sw=4 expandtab: */