annotate osdep/timer-darwin.c @ 11371:9cd1546f26ea

patch by Vladimir Mosgalin <mosgalin@VM10124.spb.edu> Following patch adds ID of Radeon 9800 (non pro) (R350) to mplayer pci database, thus enabling vidix for it. Vidix works great on it... Well, not exactly great, just the same way it works on other radeons.
author attila
date Mon, 03 Nov 2003 10:30:20 +0000
parents 56b59bcdee80
children d12758db79aa
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
10148
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
1 /*
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
2 * Precise timer routines using Mach kernel-space timing.
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
3 *
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
4 * It reports to be accurate by ~20us, unless the task is preempted.
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
5 *
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
6 * (C) 2003 Dan Christiansen
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
7 *
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
8 * Released into the public domain.
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
9 */
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
10
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
11 #include <unistd.h>
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
12 #include <stdlib.h>
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
13 #include <stdio.h>
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
14
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
15 #include <mach/mach_time.h>
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
16 #include <mach/mach.h>
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
17 #include <mach/clock.h>
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
18
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
19 #include "../config.h"
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
20 #include "../mp_msg.h"
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
21 #include "timer.h"
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
22
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
23 /* Utility macros for mach_timespec_t - it uses nsec rather than usec */
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
24
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
25 /* returns time from t1 to t2, in seconds (as float) */
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
26 #define diff_time(t1, t2) \
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
27 (((t2).tv_sec - (t1).tv_sec) + \
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
28 ((t2).tv_nsec - (t1).tv_nsec) / 1e9)
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
29
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
30 /* returns time from t1 to t2, in microseconds (as integer) */
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
31 #define udiff_time(t1, t2) \
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
32 (((t2).tv_sec - (t1).tv_sec) * 1000000 + \
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
33 ((t2).tv_nsec - (t1).tv_nsec) / 1000)
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
34
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
35 /* returns float value of t, in seconds */
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
36 #define time_to_float(t) \
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
37 ((t).tv_sec + (t).tv_nsec / 1e9)
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
38
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
39 /* returns integer value of t, in microseconds */
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
40 #define time_to_usec(t) \
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
41 ((t).tv_sec * 1000000 + (t).tv_nsec / 1000)
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
42
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
43 /* sets ts to the value of f, in seconds */
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
44 #define float_to_time(f, ts) \
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
45 do { \
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
46 (ts).tv_sec = (unsigned int)(f); \
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
47 (ts).tv_nsec = (int)(((f) - (ts).sec) / 1000000000.0); \
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
48 } while (0)
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
49
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
50 /* sets ts to the value of i, in microseconds */
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
51 #define usec_to_time(i, ts) \
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
52 do { \
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
53 (ts).tv_sec = (i) / 1000000; \
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
54 (ts).tv_nsec = (i) % 1000000 * 1000; \
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
55 } while (0)
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
56
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
57 #define time_uadd(i, ts) \
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
58 do { \
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
59 (ts).tv_sec += (i) / 1000000; \
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
60 (ts).tv_nsec += (i) % 1000000 * 1000; \
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
61 while ((ts).tv_nsec > 1000000000) { \
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
62 (ts).tv_sec++; \
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
63 (ts).tv_nsec -= 1000000000; \
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
64 } \
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
65 } while (0)
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
66
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
67
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
68 /* global variables */
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
69 static double relative_time, startup_time;
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
70 static double timebase_ratio;
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
71 static mach_port_t clock_port;
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
72
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
73
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
74 /* sleep usec_delay microseconds */
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
75 int usec_sleep(int usec_delay)
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
76 {
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
77 mach_timespec_t start_time, end_time;
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
78
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
79 clock_get_time(clock_port, &start_time);
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
80
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
81 end_time = start_time;
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
82 time_uadd(usec_delay, end_time);
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
83
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
84 clock_sleep(clock_port, TIME_ABSOLUTE, end_time, NULL);
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
85
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
86 clock_get_time(clock_port, &end_time);
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
87
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
88 return usec_delay - udiff_time(start_time, end_time);
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
89 }
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
90
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
91
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
92 /* Returns current time in microseconds */
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
93 unsigned int GetTimer()
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
94 {
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
95 return (unsigned int)((mach_absolute_time() * timebase_ratio - startup_time)
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
96 * 1e6);
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
97 }
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
98
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
99 /* Returns current time in milliseconds */
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
100 unsigned int GetTimerMS()
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
101 {
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
102 return (unsigned int)(GetTimer() / 1000);
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
103 }
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
104
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
105 /* Returns time spent between now and last call in seconds */
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
106 float GetRelativeTime()
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
107 {
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
108 double last_time;
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
109
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
110 last_time = relative_time;
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
111
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
112 relative_time = mach_absolute_time() * timebase_ratio;
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
113
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
114 return (float)(relative_time-last_time);
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
115 }
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
116
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
117 /* Initialize timer, must be called at least once at start */
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
118 void InitTimer()
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
119 {
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
120 struct mach_timebase_info timebase;
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
121
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
122 /* get base for mach_absolute_time() */
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
123 mach_timebase_info(&timebase);
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
124 timebase_ratio = (double)timebase.numer / (double)timebase.denom
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
125 * (double)1e-9;
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
126
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
127 /* get mach port for the clock */
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
128 host_get_clock_service(mach_host_self(), REALTIME_CLOCK, &clock_port);
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
129
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
130 /* prepare for GetRelativeTime() */
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
131 relative_time = startup_time =
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
132 (double)(mach_absolute_time() * timebase_ratio);
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
133 }
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
134
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
135
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
136 #if 0
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
137 int main()
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
138 {
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
139 const long delay = 0.001*1e6;
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
140 const unsigned short attempts = 100;
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
141 int i,j[attempts],t[attempts],r[attempts];
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
142 double sqtotal;
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
143 double total;
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
144
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
145 InitTimer();
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
146
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
147 for (i = 0; i < attempts; i++) {
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
148 t[i] = j[i] = GetTimer();
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
149 r[i] = usec_sleep(delay);
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
150 j[i] = delay-(GetTimer() - j[i]);
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
151 fflush(stdout);
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
152 }
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
153
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
154 for (i = 0; i < attempts; i++) {
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
155 sqtotal += j[i]*j[i];
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
156 total += j[i];
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
157 printf("%2i=%0.06g \tr: %9i\tj: %9i\tr - j:%9i\n",
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
158 i, t[i] / 1e6, r[i], j[i], r[i] - j[i]);
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
159 }
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
160
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
161 printf("attempts: %i\ttotal=%g\trms=%g\tavg=%g\n", attempts, total,
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
162 sqrt(sqtotal/attempts),total/attempts);
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
163
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
164 return 0;
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
165 }
139b44930abc Precise timer for Darwin (it's more accurate than timer-macosx.c)
alex
parents:
diff changeset
166 #endif