X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fmisc%2Fmtime.c;h=80ed1169ee3f3eb39967d1be350f1ee592cd8484;hb=55b7b5bdb7e65e94465d4ff5660cfc2964d7a18f;hp=454e99fb27a5ac3b415d92ab98d2f39245dbea2b;hpb=562d58660f9b5efdcc9189fa1f4e3d7dfca9b146;p=vlc diff --git a/src/misc/mtime.c b/src/misc/mtime.c index 454e99fb27..80ed1169ee 100644 --- a/src/misc/mtime.c +++ b/src/misc/mtime.c @@ -125,25 +125,28 @@ char *mstrtime( char *psz_buffer, mtime_t date ) * \param psz_buffer should be a buffer at least MSTRTIME_MAX_SIZE characters * \return psz_buffer is returned so this can be used as printf parameter. */ -char *secstotimestr( char *psz_buffer, int i_seconds ) +char *secstotimestr( char *psz_buffer, int32_t i_seconds ) { - int i_hours, i_mins; - i_mins = i_seconds / 60; - i_hours = i_mins / 60 ; - if( i_hours ) + if( unlikely(i_seconds < 0) ) { - snprintf( psz_buffer, MSTRTIME_MAX_SIZE, "%d:%2.2d:%2.2d", - (int) i_hours, - (int) (i_mins % 60), - (int) (i_seconds % 60) ); + secstotimestr( psz_buffer + 1, -i_seconds ); + *psz_buffer = '-'; + return psz_buffer; } + + div_t d; + + d = div( i_seconds, 60 ); + i_seconds = d.rem; + d = div( d.quot, 60 ); + + if( d.quot ) + snprintf( psz_buffer, MSTRTIME_MAX_SIZE, "%u:%02u:%02u", + d.quot, d.rem, i_seconds ); else - { - snprintf( psz_buffer, MSTRTIME_MAX_SIZE, "%2.2d:%2.2d", - (int) i_mins , - (int) (i_seconds % 60) ); - } - return( psz_buffer ); + snprintf( psz_buffer, MSTRTIME_MAX_SIZE, "%02u:%02u", + d.rem, i_seconds ); + return psz_buffer; } #if defined (HAVE_CLOCK_NANOSLEEP) @@ -211,124 +214,26 @@ mtime_t mdate( void ) #elif defined( USE_APPLE_MACH ) pthread_once(&mtime_timebase_info_once, mtime_init_timebase); uint64_t date = mach_absolute_time(); + mach_timebase_info_data_t tb = mtime_timebase_info; - /* Convert to nanoseconds */ - date *= mtime_timebase_info.numer; - date /= mtime_timebase_info.denom; - + /* Get the ssystem dependent factor. Switch to double to prevent overflow */ + double factor = (double) tb.numer / (double) tb.denom; /* Convert to microseconds */ - res = date / 1000; + double d = (double) date * factor / 1000; + res = d; + #elif defined( WIN32 ) || defined( UNDER_CE ) /* We don't need the real date, just the value of a high precision timer */ - static mtime_t freq = INT64_C(-1); - - if( freq == INT64_C(-1) ) - { - /* Extract from the Tcl source code: - * (http://www.cs.man.ac.uk/fellowsd-bin/TIP/7.html) - * - * Some hardware abstraction layers use the CPU clock - * in place of the real-time clock as a performance counter - * reference. This results in: - * - inconsistent results among the processors on - * multi-processor systems. - * - unpredictable changes in performance counter frequency - * on "gearshift" processors such as Transmeta and - * SpeedStep. - * There seems to be no way to test whether the performance - * counter is reliable, but a useful heuristic is that - * if its frequency is 1.193182 MHz or 3.579545 MHz, it's - * derived from a colorburst crystal and is therefore - * the RTC rather than the TSC. If it's anything else, we - * presume that the performance counter is unreliable. - */ - LARGE_INTEGER buf; - - freq = ( QueryPerformanceFrequency( &buf ) && - (buf.QuadPart == INT64_C(1193182) || buf.QuadPart == INT64_C(3579545) ) ) - ? buf.QuadPart : 0; - -#if defined( WIN32 ) - /* on windows 2000, XP and Vista detect if there are two - cores there - that makes QueryPerformanceFrequency in - any case not trustable? - (may also be true, for single cores with adaptive - CPU frequency and active power management?) - */ - HINSTANCE h_Kernel32 = LoadLibrary(_T("kernel32.dll")); - if(h_Kernel32) - { - void WINAPI (*pf_GetSystemInfo)(LPSYSTEM_INFO); - pf_GetSystemInfo = (void WINAPI (*)(LPSYSTEM_INFO)) - GetProcAddress(h_Kernel32, _T("GetSystemInfo")); - if(pf_GetSystemInfo) - { - SYSTEM_INFO system_info; - pf_GetSystemInfo(&system_info); - if(system_info.dwNumberOfProcessors > 1) - freq = 0; - } - FreeLibrary(h_Kernel32); - } -#endif - } + LARGE_INTEGER counter, freq; + if (!QueryPerformanceCounter (&counter) + || !QueryPerformanceFrequency (&freq)) + abort(); - if( freq != 0 ) - { - LARGE_INTEGER counter; - QueryPerformanceCounter (&counter); - - /* Convert to from (1/freq) to microsecond resolution */ - /* We need to split the division to avoid 63-bits overflow */ - lldiv_t d = lldiv (counter.QuadPart, freq); + /* Convert to from (1/freq) to microsecond resolution */ + /* We need to split the division to avoid 63-bits overflow */ + lldiv_t d = lldiv (counter.QuadPart, freq.QuadPart); - res = (d.quot * 1000000) + ((d.rem * 1000000) / freq); - } - else - { - /* Fallback on timeGetTime() which has a millisecond resolution - * (actually, best case is about 5 ms resolution) - * timeGetTime() only returns a DWORD thus will wrap after - * about 49.7 days so we try to detect the wrapping. */ - - static CRITICAL_SECTION date_lock; - static mtime_t i_previous_time = INT64_C(-1); - static int i_wrap_counts = -1; - - if( i_wrap_counts == -1 ) - { - /* Initialization */ -#if defined( WIN32 ) - i_previous_time = INT64_C(1000) * timeGetTime(); -#else - i_previous_time = INT64_C(1000) * GetTickCount(); -#endif - InitializeCriticalSection( &date_lock ); - i_wrap_counts = 0; - } - - EnterCriticalSection( &date_lock ); -#if defined( WIN32 ) - res = INT64_C(1000) * - (i_wrap_counts * INT64_C(0x100000000) + timeGetTime()); -#else - res = INT64_C(1000) * - (i_wrap_counts * INT64_C(0x100000000) + GetTickCount()); -#endif - if( i_previous_time > res ) - { - /* Counter wrapped */ - i_wrap_counts++; - res += INT64_C(0x100000000) * 1000; - } - i_previous_time = res; - LeaveCriticalSection( &date_lock ); - } -#elif defined(USE_APPLE_MACH) - /* The version that should be used, if it was cancelable */ - pthread_once(&mtime_timebase_info_once, mtime_init_timebase); - uint64_t mach_time = date * 1000 * mtime_timebase_info.denom / mtime_timebase_info.numer; - mach_wait_until(mach_time); + res = (d.quot * 1000000) + ((d.rem * 1000000) / freq.QuadPart); #else struct timeval tv_date;