Fix errors in the recently moved time calculations. (#395203, Chris
[platform/upstream/glib.git] / glib / gtimer.c
index 402bee5..be1dc26 100644 (file)
 #endif /* G_OS_WIN32 */
 
 #include "glib.h"
+#include "gthread.h"
 #include "galias.h"
 
+#define G_NSEC_PER_SEC 1000000000
+
+#define GETTIME(v) (v = G_THREAD_UF (gettime, ()))
 
 struct _GTimer
 {
-#ifdef G_OS_WIN32
   guint64 start;
   guint64 end;
-#else /* !G_OS_WIN32 */
-  struct timeval start;
-  struct timeval end;
-#endif /* !G_OS_WIN32 */
 
   guint active : 1;
 };
 
-#ifdef G_OS_WIN32
-#  define GETTIME(v) \
-     GetSystemTimeAsFileTime ((FILETIME *)&v)
-#else /* !G_OS_WIN32 */
-#  define GETTIME(v) \
-     gettimeofday (&v, NULL)
-#endif /* !G_OS_WIN32 */
 
 GTimer*
 g_timer_new (void)
@@ -110,7 +102,7 @@ g_timer_stop (GTimer *timer)
 
   timer->active = FALSE;
 
-  GETTIME(timer->end);
+  GETTIME (timer->end);
 }
 
 void
@@ -124,11 +116,7 @@ g_timer_reset (GTimer *timer)
 void
 g_timer_continue (GTimer *timer)
 {
-#ifdef G_OS_WIN32
   guint64 elapsed;
-#else
-  struct timeval elapsed;
-#endif /* G_OS_WIN32 */
 
   g_return_if_fail (timer != NULL);
   g_return_if_fail (timer->active == FALSE);
@@ -138,38 +126,12 @@ g_timer_continue (GTimer *timer)
    *  elapsed interval.
    */
 
-#ifdef G_OS_WIN32
-
   elapsed = timer->end - timer->start;
 
   GETTIME (timer->start);
 
   timer->start -= elapsed;
 
-#else /* !G_OS_WIN32 */
-
-  if (timer->start.tv_usec > timer->end.tv_usec)
-    {
-      timer->end.tv_usec += G_USEC_PER_SEC;
-      timer->end.tv_sec--;
-    }
-
-  elapsed.tv_usec = timer->end.tv_usec - timer->start.tv_usec;
-  elapsed.tv_sec = timer->end.tv_sec - timer->start.tv_sec;
-
-  GETTIME (timer->start);
-
-  if (timer->start.tv_usec < elapsed.tv_usec)
-    {
-      timer->start.tv_usec += G_USEC_PER_SEC;
-      timer->start.tv_sec--;
-    }
-
-  timer->start.tv_usec -= elapsed.tv_usec;
-  timer->start.tv_sec -= elapsed.tv_sec;
-
-#endif /* !G_OS_WIN32 */
-
   timer->active = TRUE;
 }
 
@@ -178,49 +140,19 @@ g_timer_elapsed (GTimer *timer,
                 gulong *microseconds)
 {
   gdouble total;
-#ifdef G_OS_WIN32
   gint64 elapsed;
-#else
-  struct timeval elapsed;
-#endif /* G_OS_WIN32 */
 
   g_return_val_if_fail (timer != NULL, 0);
 
-#ifdef G_OS_WIN32
   if (timer->active)
     GETTIME (timer->end);
 
   elapsed = timer->end - timer->start;
 
-  total = elapsed / 1e7;
+  total = elapsed / 1e9;
 
   if (microseconds)
-    *microseconds = (elapsed / 10) % 1000000;
-#else /* !G_OS_WIN32 */
-  if (timer->active)
-    gettimeofday (&timer->end, NULL);
-
-  if (timer->start.tv_usec > timer->end.tv_usec)
-    {
-      timer->end.tv_usec += G_USEC_PER_SEC;
-      timer->end.tv_sec--;
-    }
-
-  elapsed.tv_usec = timer->end.tv_usec - timer->start.tv_usec;
-  elapsed.tv_sec = timer->end.tv_sec - timer->start.tv_sec;
-
-  total = elapsed.tv_sec + ((gdouble) elapsed.tv_usec / 1e6);
-  if (total < 0)
-    {
-      total = 0;
-
-      if (microseconds)
-       *microseconds = 0;
-    }
-  else if (microseconds)
-    *microseconds = elapsed.tv_usec;
-
-#endif /* !G_OS_WIN32 */
+    *microseconds = (elapsed / 1000) % 1000000;
 
   return total;
 }
@@ -238,6 +170,14 @@ g_usleep (gulong microseconds)
   while (nanosleep (&request, &remaining) == -1 && errno == EINTR)
     request = remaining;
 # else /* !HAVE_NANOSLEEP */
+#  ifdef HAVE_NSLEEP
+  /* on AIX, nsleep is analogous to nanosleep */
+  struct timespec request, remaining;
+  request.tv_sec = microseconds / G_USEC_PER_SEC;
+  request.tv_nsec = 1000 * (microseconds % G_USEC_PER_SEC);
+  while (nsleep (&request, &remaining) == -1 && errno == EINTR)
+    request = remaining;
+#  else /* !HAVE_NSLEEP */
   if (g_thread_supported ())
     {
       static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
@@ -270,6 +210,7 @@ g_usleep (gulong microseconds)
       tv.tv_usec = microseconds % G_USEC_PER_SEC;
       select(0, NULL, NULL, NULL, &tv);
     }
+#  endif /* !HAVE_NSLEEP */
 # endif /* !HAVE_NANOSLEEP */
 #endif /* !G_OS_WIN32 */
 }
@@ -333,7 +274,7 @@ mktime_utc (struct tm *tm)
   retval += (tm->tm_year - 68) / 4;
   retval += days_before[tm->tm_mon] + tm->tm_mday - 1;
   
-  if (tm->tm_year % 4 == 2 && tm->tm_mon < 2)
+  if (tm->tm_year % 4 == 0 && tm->tm_mon < 2)
     retval -= 1;
   
   retval = ((((retval * 24) + tm->tm_hour) * 60) + tm->tm_min) * 60 + tm->tm_sec;