]> git.sesse.net Git - vlc/blobdiff - src/misc/mtime.c
Ahem: (v)asprintf requires stdio.h; strndup requires string.h
[vlc] / src / misc / mtime.c
index cc3911548ea714d22f0c2662b475e9fe977fd522..a925e45256d940a6a6fc0d1c8532f2a422831515 100644 (file)
 /*****************************************************************************
  * Preamble
  *****************************************************************************/
+
+#include <vlc/vlc.h>
+
 #include <stdio.h>                                              /* sprintf() */
 #include <time.h>                      /* clock_gettime(), clock_nanosleep() */
-#include <stdlib.h>                                                /* ldiv() */
+#include <stdlib.h>                                               /* lldiv() */
 
-#include <vlc/vlc.h>
 
 #if defined( PTH_INIT_IN_PTH_H )                                  /* GNU Pth */
 #   include <pth.h>
@@ -187,17 +189,18 @@ mtime_t mdate( void )
         return usec_time;
     }
 
-#elif defined (HAVE_CLOCK_GETTIME)
+#elif defined (HAVE_CLOCK_NANOSLEEP)
     struct timespec ts;
 
-# if (_POSIX_MONOTONIC_CLOCK >= 0)
+# if (_POSIX_MONOTONIC_CLOCK - 0 >= 0)
     /* Try to use POSIX monotonic clock if available */
     if( clock_gettime( CLOCK_MONOTONIC, &ts ) )
 # endif
         /* Run-time fallback to real-time clock (always available) */
         (void)clock_gettime( CLOCK_REALTIME, &ts );
 
-    return (ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
+    return ((mtime_t)ts.tv_sec * (mtime_t)1000000)
+           + (mtime_t)(ts.tv_nsec / 1000);
 #else
     struct timeval tv_date;
 
@@ -238,29 +241,21 @@ void mwait( mtime_t date )
     }
     msleep( delay );
 
-#elif defined (HAVE_CLOCK_GETTIME)
-    struct timespec ts;
-    ldiv_t d;
-
-# if 1
-    /*
-     * Ideally, we'd use absolute time (TIMER_ABSTIME), instead of
-     * computing the time difference... but VLC mtime_t type seems to
-     * overflow way too quickly for this to work properly, or maybe it's a
-     * signedness problem (??).
-     */
-    date -= mdate();
-    if( date <= 0 )
+#elif defined (HAVE_CLOCK_NANOSLEEP)
+# if defined (HAVE_TIMER_ABSTIME_THAT_ACTUALLY_WORKS_WELL)
+    lldiv_t d = lldiv( date, 1000000 );
+    struct timespec ts = { d.quot, d.rem };
+
+#  if (_POSIX_MONOTONIC_CLOCK - 0 >= 0)
+    if( clock_nanosleep( CLOCK_MONOTONIC, TIMER_ABSTIME, &ts, NULL ) )
+#  endif
+        clock_nanosleep( CLOCK_REALTIME, TIMER_ABSTIME, &ts, NULL );
+# else
+    date -= mdate ();
+    if( date <= 0)
         return;
+    msleep( date );
 # endif
-    d = ldiv( date, 1000000 );
-    ts.tv_sec = d.quot;
-    ts.tv_nsec = d.rem * 1000;
-
-# if (_POSIX_MONOTONIC_CLOCK >= 0)
-    if( clock_nanosleep( CLOCK_MONOTONIC, 0 /*TIMER_ABSTIME*/, &ts, NULL ) )
-# endif
-        (void)clock_nanosleep( CLOCK_REALTIME, 0, &ts, NULL );
 #else
 
     struct timeval tv_date;
@@ -330,6 +325,15 @@ void msleep( mtime_t delay )
 #elif defined( WIN32 ) || defined( UNDER_CE )
     Sleep( (int) (delay / 1000) );
 
+#elif defined( HAVE_CLOCK_NANOSLEEP ) 
+    lldiv_t d = lldiv( delay, 1000000 );
+    struct timespec ts = { d.quot, d.rem * 1000 };
+
+# if (_POSIX_CLOCK_MONOTONIC - 0 >= 0)
+    if( clock_nanosleep( CLOCK_MONOTONIC, 0, &ts, NULL ) )
+# endif
+        clock_nanosleep( CLOCK_REALTIME, 0, &ts, NULL );
+
 #elif defined( HAVE_NANOSLEEP )
     struct timespec ts_delay;