summaryrefslogtreecommitdiffstats
path: root/osdep
diff options
context:
space:
mode:
authorwight <wight@b3059339-0415-0410-9bf9-f77b7e298cf2>2004-08-04 15:48:43 +0000
committerwight <wight@b3059339-0415-0410-9bf9-f77b7e298cf2>2004-08-04 15:48:43 +0000
commite68d7f68588a02bacba0b0cbdb72719c2101a40b (patch)
tree7d9c2827dd588f35b349a011633353819c948acd /osdep
parent37e68033df4a76d098b18b06f1ca87cdcdf1c978 (diff)
downloadmpv-e68d7f68588a02bacba0b0cbdb72719c2101a40b.tar.bz2
mpv-e68d7f68588a02bacba0b0cbdb72719c2101a40b.tar.xz
Native darwin timer update.
Patch by Dan Christiansen <danchr@daimi.au.dk> git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@12955 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'osdep')
-rw-r--r--osdep/timer-darwin.c158
-rw-r--r--osdep/timer-lx.c8
-rw-r--r--osdep/timer-win2.c2
-rw-r--r--osdep/timer.h2
4 files changed, 63 insertions, 107 deletions
diff --git a/osdep/timer-darwin.c b/osdep/timer-darwin.c
index e9a8e7d291..eba0bc2891 100644
--- a/osdep/timer-darwin.c
+++ b/osdep/timer-darwin.c
@@ -1,170 +1,116 @@
/*
- * Precise timer routines using Mach kernel-space timing.
+ * Precise timer routines using Mach timing
*
- * It reports to be accurate by ~20us, unless the task is preempted.
+ * Copyright (c) 2003-2004, Dan Villiom Podlaski Christiansen
*
- * (C) 2003 Dan Christiansen
+ * 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:
*
- * 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";
-/* sleep usec_delay microseconds */
-int usec_sleep(int usec_delay)
+/* the core sleep function, uses floats and is used in MPlayer G2 */
+float sleep_accurate(float time_frame)
{
-#if 0
- mach_timespec_t start_time, end_time;
-
- clock_get_time(clock_port, &start_time);
+ uint64_t deadline = time_frame / timebase_ratio + mach_absolute_time();
- end_time = start_time;
- time_uadd(usec_delay, end_time);
+ mach_wait_until(deadline);
- clock_sleep(clock_port, TIME_ABSOLUTE, end_time, NULL);
-
- clock_get_time(clock_port, &end_time);
+ return (mach_absolute_time() - deadline) * timebase_ratio;
+}
- return usec_delay - udiff_time(start_time, end_time);
-#else
- usleep(usec_delay);
-#endif
+/* wrapper for MPlayer G1 */
+int usec_sleep(int usec_delay)
+{
+ 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
-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;
+#include <stdio.h>
+
+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
diff --git a/osdep/timer-lx.c b/osdep/timer-lx.c
index 4321e46bfa..4bf2b0bf96 100644
--- a/osdep/timer-lx.c
+++ b/osdep/timer-lx.c
@@ -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 @@ int usec_sleep(int usec_delay)
#endif
}
-
// Returns current time in microseconds
unsigned int GetTimer(){
struct timeval tv;
diff --git a/osdep/timer-win2.c b/osdep/timer-win2.c
index 7f31126790..2f0b5c3075 100644
--- a/osdep/timer-win2.c
+++ b/osdep/timer-win2.c
@@ -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;
diff --git a/osdep/timer.h b/osdep/timer.h
index efda23ad6c..1e181650c1 100644
--- a/osdep/timer.h
+++ b/osdep/timer.h
@@ -1,6 +1,8 @@
#ifndef __TIMER_H
#define __TIMER_H
+extern const char *timer_name;
+
void InitTimer();
unsigned int GetTimer();
unsigned int GetTimerMS();