/* * Semi-precise timer routines using CoreFoundation * * (C) 2003 Dan Christiansen * * Released into the public domain. * * Changelog: * 07/05/2003 sleep_accurate() merged from timer-lx.c * updated to mplayer-g2 * 11/05/2003 simplification, description & cleanup * */ /* About CFRunLoop: * * - Minimum sleep interval seems to be 0.000025s * - The common accuracy is in the order 0.0003s * - Sometimes, maybe 1 in 10 runs, it is 0.001s-0.015s late. * * Being a run loop, it can be up to several seconds (or more) late if * another task runs. It appears to never be too early. * * CFRunLoop offers interruptable sleep, but does not deploy busy waiting; * it uses the system even manager. */ #include #include #include "../config.h" #include "timer.h" static CFAbsoluteTime relative_time; int usec_sleep(int usec_delay) { float start, end; start = CFAbsoluteTimeGetCurrent(); CFRunLoopRunInMode(kCFRunLoopDefaultMode, usec_delay/1000000.0, false); end = CFAbsoluteTimeGetCurrent(); return (usec_delay-(end-start))*1000000; } /* timing without rounding errors */ float sleep_accurate(float time_frame) { const float min=0.01; float start, end; if (time_frame > min) { start = CFAbsoluteTimeGetCurrent(); CFRunLoopRunInMode(kCFRunLoopDefaultMode, time_frame-min, false); end = CFAbsoluteTimeGetCurrent(); time_frame -= end-start; end = start = 0; } if (time_frame > 0) { struct timespec ts; ts.tv_sec = (long)time_frame; ts.tv_nsec = (long)(time_frame * 1000000000.0); start = CFAbsoluteTimeGetCurrent(); nanosleep(&ts, NULL); end = CFAbsoluteTimeGetCurrent(); } return time_frame-(end-start); } /* Returns current time in microseconds */ unsigned int GetTimer() { return (unsigned int)(CFAbsoluteTimeGetCurrent() * 1000000); } /* Returns current time in milliseconds */ unsigned int GetTimerMS() { return (unsigned int)(CFAbsoluteTimeGetCurrent() * 1000); } /* Returns time spent between now and last call in seconds */ float GetRelativeTime() { CFAbsoluteTime last_time = relative_time; relative_time = CFAbsoluteTimeGetCurrent(); return (float)(relative_time - last_time); } /* Initialize timer, must be called at least once at start */ void InitTimer() { GetRelativeTime(); }