2 * Precise timer routines using Mach timing
4 * Copyright (c) 2003-2004, Dan Villiom Podlaski Christiansen
6 * Permission is hereby granted, free of charge, to any person
7 * obtaining a copy of this software and associated documentation
8 * files (the "Software"), to deal in the Software without
9 * restriction, including without limitation the rights to use, copy,
10 * modify, merge, publish, distribute, sublicense, and/or sell copies
11 * of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be
15 * included in all copies or substantial portions of the Software.
23 #include <mach/mach_time.h>
29 /* global variables */
30 static double relative_time
;
31 static double timebase_ratio
;
33 const char *timer_name
= "Darwin accurate";
37 /* the core sleep function, uses floats and is used in MPlayer G2 */
38 float sleep_accurate(float time_frame
)
40 uint64_t deadline
= time_frame
/ timebase_ratio
+ mach_absolute_time();
42 mach_wait_until(deadline
);
44 return (mach_absolute_time() - deadline
) * timebase_ratio
;
47 /* wrapper for MPlayer G1 */
48 int usec_sleep(int usec_delay
)
50 return sleep_accurate(usec_delay
/ 1e6
) * 1e6
;
54 /* current time in microseconds */
55 unsigned int GetTimer(void)
57 return (unsigned int)(uint64_t)(mach_absolute_time() * timebase_ratio
* 1e6
);
60 /* current time in milliseconds */
61 unsigned int GetTimerMS(void)
63 return (unsigned int)(uint64_t)(mach_absolute_time() * timebase_ratio
* 1e3
);
66 /* time spent between now and last call in seconds */
67 float GetRelativeTime(void)
69 double last_time
= relative_time
;
74 relative_time
= mach_absolute_time() * timebase_ratio
;
76 return (float)(relative_time
-last_time
);
79 /* initialize timer, must be called at least once at start */
82 struct mach_timebase_info timebase
;
84 mach_timebase_info(&timebase
);
85 timebase_ratio
= (double)timebase
.numer
/ (double)timebase
.denom
88 relative_time
= (double)(mach_absolute_time() * timebase_ratio
);
100 for (i
= 0; i
< c
; i
++) {
101 const int delay
= rand() / (RAND_MAX
/ 1e5
);
104 r
= usec_sleep(delay
);
106 r
= sleep_accurate(delay
/ 1e6
) * 1e6
;
108 j
= (GetTimer() - j
) - delay
;
109 printf("sleep time:%8i %5i (%i)\n", delay
, j
, j
- r
);
112 fprintf(stderr
, "average error:\t%lli\n", t
/ c
);