minor optimization.
[platform/upstream/glib.git] / gtimer.c
index 47946b3..d613a50 100644 (file)
--- a/gtimer.c
+++ b/gtimer.c
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  */
-#include <sys/time.h>
-#include <unistd.h>
+
+/*
+ * Modified by the GLib Team and others 1997-1999.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
+/* 
+ * MT safe
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include "glib.h"
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#ifndef G_OS_WIN32
+#include <sys/time.h>
+#endif /* G_OS_WIN32 */
 
+#ifdef G_OS_WIN32
+#include <windows.h>
+#endif /* G_OS_WIN32 */
 
 typedef struct _GRealTimer GRealTimer;
 
 struct _GRealTimer
 {
+#ifdef G_OS_WIN32
+  DWORD start;
+  DWORD end;
+#else /* !G_OS_WIN32 */
   struct timeval start;
   struct timeval end;
-  gint active;
-};
+#endif /* !G_OS_WIN32 */
 
+  guint active : 1;
+};
 
 GTimer*
 g_timer_new (void)
@@ -39,7 +67,11 @@ g_timer_new (void)
   timer = g_new (GRealTimer, 1);
   timer->active = TRUE;
 
+#ifdef G_OS_WIN32
+  timer->start = GetTickCount ();
+#else /* !G_OS_WIN32 */
   gettimeofday (&timer->start, NULL);
+#endif /* !G_OS_WIN32 */
 
   return ((GTimer*) timer);
 }
@@ -47,7 +79,7 @@ g_timer_new (void)
 void
 g_timer_destroy (GTimer *timer)
 {
-  g_assert (timer != NULL);
+  g_return_if_fail (timer != NULL);
 
   g_free (timer);
 }
@@ -57,11 +89,16 @@ g_timer_start (GTimer *timer)
 {
   GRealTimer *rtimer;
 
-  g_assert (timer != NULL);
+  g_return_if_fail (timer != NULL);
 
   rtimer = (GRealTimer*) timer;
+  rtimer->active = TRUE;
+
+#ifdef G_OS_WIN32
+  rtimer->start = GetTickCount ();
+#else /* !G_OS_WIN32 */
   gettimeofday (&rtimer->start, NULL);
-  rtimer->active = 1;
+#endif /* !G_OS_WIN32 */
 }
 
 void
@@ -69,11 +106,16 @@ g_timer_stop (GTimer *timer)
 {
   GRealTimer *rtimer;
 
-  g_assert (timer != NULL);
+  g_return_if_fail (timer != NULL);
 
   rtimer = (GRealTimer*) timer;
+  rtimer->active = FALSE;
+
+#ifdef G_OS_WIN32
+  rtimer->end = GetTickCount ();
+#else /* !G_OS_WIN32 */
   gettimeofday (&rtimer->end, NULL);
-  rtimer->active = 0;
+#endif /* !G_OS_WIN32 */
 }
 
 void
@@ -81,10 +123,15 @@ g_timer_reset (GTimer *timer)
 {
   GRealTimer *rtimer;
 
-  g_assert (timer != NULL);
+  g_return_if_fail (timer != NULL);
 
   rtimer = (GRealTimer*) timer;
+
+#ifdef G_OS_WIN32
+   rtimer->start = GetTickCount ();
+#else /* !G_OS_WIN32 */
   gettimeofday (&rtimer->start, NULL);
+#endif /* !G_OS_WIN32 */
 }
 
 gdouble
@@ -92,19 +139,44 @@ g_timer_elapsed (GTimer *timer,
                 gulong *microseconds)
 {
   GRealTimer *rtimer;
-  struct timeval elapsed;
   gdouble total;
+#ifndef G_OS_WIN32
+  struct timeval elapsed;
+#endif /* G_OS_WIN32 */
 
-  g_assert (timer != NULL);
+  g_return_val_if_fail (timer != NULL, 0);
 
   rtimer = (GRealTimer*) timer;
 
+#ifdef G_OS_WIN32
+  if (rtimer->active)
+    rtimer->end = GetTickCount ();
+
+  /* Check for wraparound, which happens every 49.7 days.
+   * No, Win95 machines probably are never running for that long,
+   * but NT machines are.
+   */
+  if (rtimer->end < rtimer->start)
+    total = (UINT_MAX - (rtimer->start - rtimer->end)) / 1000.0;
+  else
+    total = (rtimer->end - rtimer->start) / 1000.0;
+
+  if (microseconds)
+    {
+      if (rtimer->end < rtimer->start)
+       *microseconds =
+         ((UINT_MAX - (rtimer->start - rtimer->end)) % 1000) * 1000;
+      else
+       *microseconds =
+         ((rtimer->end - rtimer->start) % 1000) * 1000;
+    }
+#else /* !G_OS_WIN32 */
   if (rtimer->active)
     gettimeofday (&rtimer->end, NULL);
 
   if (rtimer->start.tv_usec > rtimer->end.tv_usec)
     {
-      rtimer->end.tv_usec += 1000000;
+      rtimer->end.tv_usec += G_MICROSEC;
       rtimer->end.tv_sec--;
     }
 
@@ -112,9 +184,31 @@ g_timer_elapsed (GTimer *timer,
   elapsed.tv_sec = rtimer->end.tv_sec - rtimer->start.tv_sec;
 
   total = elapsed.tv_sec + ((gdouble) elapsed.tv_usec / 1e6);
+  if (total < 0)
+    {
+      total = 0;
 
-  if (microseconds)
+      if (microseconds)
+       *microseconds = 0;
+    }
+  else if (microseconds)
     *microseconds = elapsed.tv_usec;
 
+#endif /* !G_OS_WIN32 */
+
   return total;
 }
+
+void
+g_usleep (gulong microseconds)
+{
+#ifdef G_OS_WIN32
+  Sleep (microseconds / 1000);
+#else
+  struct timeval tv;
+  tv.tv_sec = microseconds / G_MICROSEC;
+  tv.tv_usec = microseconds % G_MICROSEC;
+  select(0, NULL, NULL, NULL, &tv);
+#endif
+}
+