changeset 12954:f9755d9c479a

Native darwin timer update. Patch by Dan Christiansen <danchr@daimi.au.dk>
author wight
date Wed, 04 Aug 2004 15:48:43 +0000
parents 27e983508347
children 82fb5c71f776
files mplayer.c osdep/timer-darwin.c osdep/timer-lx.c osdep/timer-win2.c osdep/timer.h
diffstat 5 files changed, 70 insertions(+), 113 deletions(-) [+]
line wrap: on
line diff
--- a/mplayer.c	Wed Aug 04 13:36:56 2004 +0000
+++ b/mplayer.c	Wed Aug 04 15:48:43 2004 +0000
@@ -1127,7 +1127,8 @@
 #endif
     if(rtc_fd<0)
 #endif
-    mp_msg(MSGT_CPLAYER, MSGL_INFO, "Using %s timing\n",softsleep?"software":"usleep()");
+      mp_msg(MSGT_CPLAYER, MSGL_INFO, "Using %s timing\n",
+	     softsleep?"software":timer_name);
 
 #ifdef USE_TERMCAP
   if ( !use_gui ) load_termcap(NULL); // load key-codes
@@ -2232,9 +2233,9 @@
     } else
 #endif
     {
-	// -------- USLEEP + SOFTSLEEP -----------
+	// -------- TIMER + SOFTSLEEP -----------
 	float min=softsleep?0.021:0.005;
-	current_module="sleep_usleep";
+	current_module="sleep_timer";
         while(time_frame>min){
           if(time_frame<=0.020)
              usec_sleep(0); // sleeps 1 clock tick (10ms)!
--- a/osdep/timer-darwin.c	Wed Aug 04 13:36:56 2004 +0000
+++ b/osdep/timer-darwin.c	Wed Aug 04 15:48:43 2004 +0000
@@ -1,170 +1,116 @@
 /*
- * Precise timer routines using Mach kernel-space timing.
+ * Precise timer routines using Mach timing
+ *
+ * Copyright (c) 2003-2004, Dan Villiom Podlaski Christiansen
  *
- * It reports to be accurate by ~20us, unless the task is preempted. 
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
  *
- * (C) 2003 Dan Christiansen
- *
- * Released into the public domain.
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
  */
 
 #include <unistd.h>
 #include <stdlib.h>
-#include <stdio.h>
-
+#include <time.h>
+#include <math.h>
+#include <sys/time.h>
 #include <mach/mach_time.h>
-#include <mach/mach.h>
-#include <mach/clock.h>
 
 #include "../config.h"
 #include "../mp_msg.h"
 #include "timer.h"
 
-/* Utility macros for mach_timespec_t - it uses nsec rather than usec */
-
-/* returns time from t1 to t2, in seconds (as float) */
-#define diff_time(t1, t2)						\
-  (((t2).tv_sec - (t1).tv_sec) +					\
-   ((t2).tv_nsec - (t1).tv_nsec) / 1e9)
-
-/* returns time from t1 to t2, in microseconds (as integer) */
-#define udiff_time(t1, t2)						\
-  (((t2).tv_sec - (t1).tv_sec) * 1000000 +				\
-   ((t2).tv_nsec - (t1).tv_nsec) / 1000)
-
-/* returns float value of t, in seconds */
-#define time_to_float(t)						\
-  ((t).tv_sec + (t).tv_nsec / 1e9)
-
-/* returns integer value of t, in microseconds */
-#define time_to_usec(t)							\
-  ((t).tv_sec * 1000000 + (t).tv_nsec / 1000)
-
-/* sets ts to the value of f, in seconds */
-#define float_to_time(f, ts)						\
-  do {									\
-    (ts).tv_sec = (unsigned int)(f);					\
-    (ts).tv_nsec = (int)(((f) - (ts).sec) / 1000000000.0);		\
-  } while (0)
-
-/* sets ts to the value of i, in microseconds */
-#define usec_to_time(i, ts)						\
-  do {									\
-    (ts).tv_sec = (i) / 1000000;					\
-    (ts).tv_nsec = (i) % 1000000 * 1000;				\
-  } while (0)
-
-#define time_uadd(i, ts)						\
-  do {									\
-    (ts).tv_sec += (i) / 1000000;					\
-    (ts).tv_nsec += (i) % 1000000 * 1000;				\
-    while ((ts).tv_nsec > 1000000000) {					\
-      (ts).tv_sec++;							\
-      (ts).tv_nsec -= 1000000000;					\
-    }									\
-  } while (0)
-
-
 /* global variables */
 static double relative_time, startup_time;
 static double timebase_ratio;
-static mach_port_t clock_port;
+
+const char *timer_name = "Darwin accurate";
 
+/* the core sleep function, uses floats and is used in MPlayer G2 */
+float sleep_accurate(float time_frame)
+{
+  uint64_t deadline = time_frame / timebase_ratio + mach_absolute_time();
 
-/* sleep usec_delay microseconds */
+  mach_wait_until(deadline);
+
+  return (mach_absolute_time() - deadline) * timebase_ratio;
+}
+
+/* wrapper for MPlayer G1 */
 int usec_sleep(int usec_delay)
 {
-#if 0
-  mach_timespec_t start_time, end_time;
-
-  clock_get_time(clock_port, &start_time);
-
-  end_time = start_time;
-  time_uadd(usec_delay, end_time);
-
-  clock_sleep(clock_port, TIME_ABSOLUTE, end_time, NULL);
-
-  clock_get_time(clock_port, &end_time);
-
-  return usec_delay - udiff_time(start_time, end_time);
-#else
-  usleep(usec_delay);
-#endif
+  return sleep_accurate(usec_delay / 1e6) * 1e6;
 }
 
 
-/* Returns current time in microseconds */
+/* current time in microseconds */
 unsigned int GetTimer()
 {
   return (unsigned int)((mach_absolute_time() * timebase_ratio - startup_time)
 			* 1e6);
-}  
+}
 
-/* Returns current time in milliseconds */
+/* current time in milliseconds */
 unsigned int GetTimerMS()
 {
   return (unsigned int)(GetTimer() / 1000);
 }
 
-/* Returns time spent between now and last call in seconds */
+/* time spent between now and last call in seconds */
 float GetRelativeTime()
 {
-  double last_time;
-
-  last_time = relative_time;
+  double last_time = relative_time;
+  
+  if (!relative_time)
+    InitTimer();
   
   relative_time = mach_absolute_time() * timebase_ratio;
 
   return (float)(relative_time-last_time);
 }
 
-/* Initialize timer, must be called at least once at start */
+/* initialize timer, must be called at least once at start */
 void InitTimer()
 {
   struct mach_timebase_info timebase;
 
-  /* get base for mach_absolute_time() */
   mach_timebase_info(&timebase);
   timebase_ratio = (double)timebase.numer / (double)timebase.denom 
     * (double)1e-9;
-  
-  /* get mach port for the clock */
-  host_get_clock_service(mach_host_self(), REALTIME_CLOCK, &clock_port);
-  
-  /* prepare for GetRelativeTime() */
+    
   relative_time = startup_time = 
     (double)(mach_absolute_time() * timebase_ratio);
 }
 
+#if 0
+#include <stdio.h>
 
-#if 0
-int main()
-{
-  const long delay = 0.001*1e6;
-  const unsigned short attempts = 100;
-  int i,j[attempts],t[attempts],r[attempts];
-  double sqtotal;
-  double total;
+int main() {
+  int i,j, r, c = 200;
+  long long t = 0;
   
   InitTimer();
 
-  for (i = 0; i < attempts; i++) {
-    t[i] = j[i] = GetTimer();
-    r[i] = usec_sleep(delay);
-      j[i] = delay-(GetTimer() - j[i]);
-      fflush(stdout);
+  for (i = 0; i < c; i++) {
+    const int delay = rand() / (RAND_MAX / 1e5);
+    j = GetTimer();
+#if 1
+    r = usec_sleep(delay);
+#else
+    r = sleep_accurate(delay / 1e6) * 1e6;
+#endif
+    j = (GetTimer() - j) - delay;
+    printf("sleep time:%8i %5i (%i)\n", delay, j, j - r);
+    t += j - r;
   }
+  fprintf(stderr, "average error:\t%lli\n", t / c);
 
-  for (i = 0; i < attempts; i++) {
-    sqtotal += j[i]*j[i];
-    total += j[i];
-    printf("%2i=%0.06g  \tr: %9i\tj: %9i\tr - j:%9i\n",
-	   i, t[i] / 1e6, r[i], j[i], r[i] - j[i]);
-  }
-  
-  printf("attempts: %i\ttotal=%g\trms=%g\tavg=%g\n", attempts, total, 
-	 sqrt(sqtotal/attempts),total/attempts);
-  
   return 0;
 }
 #endif
--- a/osdep/timer-lx.c	Wed Aug 04 13:36:56 2004 +0000
+++ b/osdep/timer-lx.c	Wed Aug 04 15:48:43 2004 +0000
@@ -6,6 +6,13 @@
 #include <sys/time.h>
 #include "../config.h"
 
+const char *timer_name() =
+#ifdef HAVE_NANOSLEEP
+  "nanosleep()";
+#else
+  "usleep()";
+#endif
+
 int usec_sleep(int usec_delay)
 {
 #ifdef HAVE_NANOSLEEP
@@ -18,7 +25,6 @@
 #endif
 }
 
-
 // Returns current time in microseconds
 unsigned int GetTimer(){
   struct timeval tv;
--- a/osdep/timer-win2.c	Wed Aug 04 13:36:56 2004 +0000
+++ b/osdep/timer-win2.c	Wed Aug 04 15:48:43 2004 +0000
@@ -4,6 +4,8 @@
 #include <mmsystem.h>
 #include "timer.h"
 
+const char *timer_name = "Windows native";
+
 // Returns current time in microseconds
 unsigned int GetTimer(){
   return timeGetTime() * 1000;
--- a/osdep/timer.h	Wed Aug 04 13:36:56 2004 +0000
+++ b/osdep/timer.h	Wed Aug 04 15:48:43 2004 +0000
@@ -1,6 +1,8 @@
 #ifndef __TIMER_H
 #define __TIMER_H
 
+extern const char *timer_name;
+
 void InitTimer();
 unsigned int GetTimer();
 unsigned int GetTimerMS();