--- a/configure.in	
+++ a/configure.in	
@@ -957,7 +957,6 @@ AC_CHECK_FUNCS(lstat strerror strsignal memmove vsnprintf stpcpy strcasecmp strn
 AC_CHECK_FUNCS(chown lchmod lchown fchmod fchown link statvfs statfs utimes getgrgid getpwuid)
 AC_CHECK_FUNCS(getmntent_r setmntent endmntent hasmntopt getmntinfo)
 # Check for high-resolution sleep functions
-AC_CHECK_FUNCS(nanosleep nsleep)
 
 AC_CHECK_HEADERS(crt_externs.h)
 AC_CHECK_FUNCS(_NSGetEnviron)
@@ -2376,23 +2375,10 @@ AC_CHECK_FUNCS(clock_gettime, [], [
     AC_DEFINE(HAVE_CLOCK_GETTIME, 1)
     G_THREAD_LIBS="$G_THREAD_LIBS -lrt"
     G_THREAD_LIBS_FOR_GTHREAD="$G_THREAD_LIBS_FOR_GTHREAD -lrt"
+    GLIB_RT_LIBS="-lrt"
   ])
 ])
-
-AC_CACHE_CHECK(for monotonic clocks,
-    glib_cv_monotonic_clock,AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
-#include <time.h>
-#include <unistd.h>
-int main() {
-#if !(defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0 && defined(CLOCK_MONOTONIC))
-        #error No monotonic clock
-#endif
-	return 0;
-}
-]])],glib_cv_monotonic_clock=yes,glib_cv_monotonic_clock=no))
-if test "$glib_cv_monotonic_clock" = "yes"; then
-  AC_DEFINE(HAVE_MONOTONIC_CLOCK,1,[Have a monotonic clock])
-fi
+AC_SUBST(GLIB_RT_LIBS)
 
 
 dnl ********************************
--- a/docs/reference/glib/glib-sections.txt	
+++ a/docs/reference/glib/glib-sections.txt	
@@ -516,6 +516,7 @@ GSourceFunc
 g_source_set_callback_indirect
 g_source_add_poll
 g_source_remove_poll
+g_source_get_time
 g_source_get_current_time
 g_source_remove
 g_source_remove_by_funcs_user_data
@@ -1275,6 +1276,9 @@ g_time_val_from_iso8601
 g_time_val_to_iso8601
 
 <SUBSECTION>
+g_get_monotonic_time
+
+<SUBSECTION>
 GDate
 GTime
 GDateDMY
--- a/docs/reference/glib/tmpl/date.sgml	
+++ a/docs/reference/glib/tmpl/date.sgml	
@@ -131,6 +131,14 @@ length of the sleep.
 @Returns: 
 
 
+<!-- ##### STRUCT GTimeSpec ##### -->
+<para>
+
+</para>
+
+@tv_sec: 
+@tv_nsec: 
+
 <!-- ##### STRUCT GDate ##### -->
 <para>
 Represents a day between January 1, Year 1 and a few thousand years in
--- a/gio/glocalfileinfo.c	
+++ a/gio/glocalfileinfo.c	
@@ -125,18 +125,18 @@ static GHashTable *gid_cache = NULL;
 char *
 _g_local_file_info_create_etag (GLocalFileStat *statbuf)
 {
-  GTimeVal tv;
-  
-  tv.tv_sec = statbuf->st_mtime;
+  glong sec, usec;
+
+  sec = statbuf->st_mtime;
 #if defined (HAVE_STRUCT_STAT_ST_MTIMENSEC)
-  tv.tv_usec = statbuf->st_mtimensec / 1000;
+  usec = statbuf->st_mtimensec / 1000;
 #elif defined (HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
-  tv.tv_usec = statbuf->st_mtim.tv_nsec / 1000;
+  usec = statbuf->st_mtim.tv_nsec / 1000;
 #else
-  tv.tv_usec = 0;
+  usec = 0;
 #endif
 
-  return g_strdup_printf ("%lu:%lu", tv.tv_sec, tv.tv_usec);
+  return g_strdup_printf ("%lu:%lu", sec, usec);
 }
 
 static char *
--- a/glib-2.0.pc.in	
+++ a/glib-2.0.pc.in	
@@ -10,6 +10,7 @@ glib_mkenums=glib-mkenums
 Name: GLib
 Description: C Utility Library
 Version: @VERSION@
+Requires.private: @PCRE_REQUIRES@
 Libs: -L${libdir} -lglib-2.0 @INTLLIBS@
-Libs.private: @ICONV_LIBS@
+Libs.private: @G_THREAD_LIBS@ @G_LIBS_EXTRA@ @PCRE_LIBS@ @INTLLIBS@ @ICONV_LIBS@
 Cflags: -I${includedir}/glib-2.0 -I${libdir}/glib-2.0/include @GLIB_EXTRA_CFLAGS@
--- a/glib/Makefile.am	
+++ a/glib/Makefile.am	
@@ -291,7 +291,7 @@ pcre_lib =
 pcre_inc =
 endif
 
-libglib_2_0_la_LIBADD = libcharset/libcharset.la $(printf_la) @GIO@ @GSPAWN@ @PLATFORMDEP@ @ICONV_LIBS@ @G_LIBS_EXTRA@ $(pcre_lib)
+libglib_2_0_la_LIBADD = libcharset/libcharset.la $(printf_la) @GIO@ @GSPAWN@ @PLATFORMDEP@ @ICONV_LIBS@ @G_LIBS_EXTRA@ $(pcre_lib) $(GLIB_RT_LIBS)
 libglib_2_0_la_DEPENDENCIES = libcharset/libcharset.la $(printf_la) @GIO@ @GSPAWN@ @PLATFORMDEP@ $(glib_win32_res) $(glib_def)
 
 libglib_2_0_la_LDFLAGS = \
--- a/glib/glib.symbols	
+++ a/glib/glib.symbols	
@@ -614,6 +614,7 @@ g_child_watch_add
 g_child_watch_add_full
 g_child_watch_source_new
 g_get_current_time
+g_get_monotonic_time
 g_main_context_acquire
 g_main_context_add_poll
 g_main_context_check
@@ -653,6 +654,7 @@ g_source_attach
 g_source_destroy
 g_source_get_can_recurse
 g_source_get_context
+g_source_get_time
 g_source_get_current_time
 g_source_get_id
 g_source_get_priority
--- a/glib/gmain.c	
+++ a/glib/gmain.c	
@@ -159,8 +159,8 @@ struct _GMainContext
 
   GPollFunc poll_func;
 
-  GTimeVal current_time;
-  gboolean time_is_current;
+  gint64   time;
+  gboolean time_is_fresh;
 };
 
 struct _GSourceCallback
@@ -181,9 +181,9 @@ struct _GMainLoop
 struct _GTimeoutSource
 {
   GSource     source;
-  GTimeVal    expiration;
+  gint64      expiration;
   guint       interval;
-  guint	      granularity;
+  gboolean    seconds;
 };
 
 struct _GChildWatchSource
@@ -286,8 +286,6 @@ static gint child_watch_wake_up_pipe[2] = {0, 0};
 G_LOCK_DEFINE_STATIC (main_context_list);
 static GSList *main_context_list = NULL;
 
-static gint timer_perturb = -1;
-
 GSourceFuncs g_timeout_funcs =
 {
   g_timeout_prepare,
@@ -503,7 +501,7 @@ g_main_context_new (void)
   
   context->pending_dispatches = g_ptr_array_new ();
   
-  context->time_is_current = FALSE;
+  context->time_is_fresh = FALSE;
   
 #ifdef G_THREADS_ENABLED
   if (g_thread_supported ())
@@ -1622,6 +1620,213 @@ g_get_current_time (GTimeVal *result)
 #endif
 }
 
+/**
+ * g_get_monotonic_time:
+ *
+ * Queries the system monotonic time.
+ *
+ * The monotonic clock will always increase and doesn't suffer
+ * discontinuities when the user (or NTP) changes the system time.  It
+ * may or may not continue to tick during times where the machine is
+ * suspended.
+ *
+ * We try to use the clock that corresponds as closely as possible to
+ * the passage of time as measured by system calls such as poll() but it
+ * may not always be possible to do this.
+ *
+ * Returns: the monotonic time, in microseconds
+ *
+ * Since: 2.28
+ **/
+#if defined (G_OS_WIN32)
+static ULONGLONG (*g_GetTickCount64) (void) = NULL;
+static guint32 g_win32_tick_epoch = 0;
+
+void
+g_clock_win32_init (void)
+{
+  HMODULE kernel32;
+
+  g_GetTickCount64 = NULL;
+  kernel32 = GetModuleHandle ("KERNEL32.DLL");
+  if (kernel32 != NULL)
+    g_GetTickCount64 = (void *) GetProcAddress (kernel32, "GetTickCount64");
+  g_win32_tick_epoch = ((guint32)GetTickCount()) >> 31;
+}
+
+gint64
+g_get_monotonic_time (void)
+{
+  guint64 ticks;
+  guint32 ticks32;
+
+  /* There are four sources for the monotonic time on Windows:
+   *
+   * Three are based on a (1 msec accuracy, but only read periodically) clock chip:
+   * - GetTickCount (GTC)
+   *    32bit msec counter, updated each ~15msec, wraps in ~50 days
+   * - GetTickCount64 (GTC64)
+   *    Same as GetTickCount, but extended to 64bit, so no wrap
+   *    Only available in Vista or later
+   * - timeGetTime (TGT)
+   *    similar to GetTickCount by default: 15msec, 50 day wrap.
+   *    available in winmm.dll (thus known as the multimedia timers)
+   *    However apps can raise the system timer clock frequency using timeBeginPeriod()
+   *    increasing the accuracy up to 1 msec, at a cost in general system performance
+   *    and battery use.
+   *
+   * One is based on high precision clocks:
+   * - QueryPrecisionCounter (QPC)
+   *    This has much higher accuracy, but is not guaranteed monotonic, and
+   *    has lots of complications like clock jumps and different times on different
+   *    CPUs. It also has lower long term accuracy (i.e. it will drift compared to
+   *    the low precision clocks.
+   *
+   * Additionally, the precision available in the timer-based wakeup such as
+   * MsgWaitForMultipleObjectsEx (which is what the mainloop is based on) is based
+   * on the TGT resolution, so by default it is ~15msec, but can be increased by apps.
+   *
+   * The QPC timer has too many issues to be used as is. The only way it could be used
+   * is to use it to interpolate the lower precision clocks. Firefox does something like
+   * this:
+   *   https://bugzilla.mozilla.org/show_bug.cgi?id=363258
+   *
+   * However this seems quite complicated, so we're not doing this right now.
+   *
+   * The approach we take instead is to use the TGT timer, extending it to 64bit
+   * either by using the GTC64 value, or if that is not available, a process local
+   * time epoch that we increment when we detect a timer wrap (assumes that we read
+   * the time at least once every 50 days).
+   *
+   * This means that:
+   *  - We have a globally consistent monotonic clock on Vista and later
+   *  - We have a locally monotonic clock on XP
+   *  - Apps that need higher precision in timeouts and clock reads can call
+   *    timeBeginPeriod() to increase it as much as they want
+   */
+
+  if (g_GetTickCount64 != NULL)
+    {
+      guint32 ticks_as_32bit;
+
+      ticks = g_GetTickCount64 ();
+      ticks32 = timeGetTime();
+
+      /* GTC64 and TGT are sampled at different times, however they
+       * have the same base and source (msecs since system boot).
+       * They can differ by as much as -16 to +16 msecs.
+       * We can't just inject the low bits into the 64bit counter
+       * as one of the counters can have wrapped in 32bit space and
+       * the other not. Instead we calculate the signed difference
+       * in 32bit space and apply that difference to the 64bit counter.
+       */
+      ticks_as_32bit = (guint32)ticks;
+
+      /* We could do some 2's complement hack, but we play it safe */
+      if (ticks32 - ticks_as_32bit <= G_MAXINT32)
+        ticks += ticks32 - ticks_as_32bit;
+      else
+        ticks -= ticks_as_32bit - ticks32;
+    }
+  else
+    {
+      guint32 epoch;
+
+      epoch = g_atomic_int_get (&g_win32_tick_epoch);
+
+      /* Must read ticks after the epoch. Then we're guaranteed
+       * that the ticks value we read is higher or equal to any
+       * previous ones that lead to the writing of the epoch.
+       */
+      ticks32 = timeGetTime();
+
+      /* We store the MSB of the current time as the LSB
+       * of the epoch. Comparing these bits lets us detect when
+       * the 32bit counter has wrapped so we can increase the
+       * epoch.
+       *
+       * This will work as long as this function is called at
+       * least once every ~24 days, which is half the wrap time
+       * of a 32bit msec counter. I think this is pretty likely.
+       *
+       * Note that g_win32_tick_epoch is a process local state,
+       * so the monotonic clock will not be the same between
+       * processes.
+       */
+      if ((ticks32 >> 31) != (epoch & 1))
+        {
+          epoch++;
+          g_atomic_int_set (&g_win32_tick_epoch, epoch);
+        }
+
+
+      ticks = (guint64)ticks32 | ((guint64)epoch) << 31;
+    }
+
+  return ticks * 1000;
+}
+#elif defined(HAVE_MACH_MACH_TIME_H) /* Mac OS */
+gint64
+g_get_monotonic_time (void)
+{
+  static mach_timebase_info_data_t timebase_info;
+
+  if (timebase_info.denom == 0)
+    {
+      /* This is a fraction that we must use to scale
+       * mach_absolute_time() by in order to reach nanoseconds.
+       *
+       * We've only ever observed this to be 1/1, but maybe it could be
+       * 1000/1 if mach time is microseconds already, or 1/1000 if
+       * picoseconds.  Try to deal nicely with that.
+       */
+      mach_timebase_info (&timebase_info);
+
+      /* We actually want microseconds... */
+      if (timebase_info.numer % 1000 == 0)
+        timebase_info.numer /= 1000;
+      else
+        timebase_info.denom *= 1000;
+
+      /* We want to make the numer 1 to avoid having to multiply... */
+      if (timebase_info.denom % timebase_info.numer == 0)
+        {
+          timebase_info.denom /= timebase_info.numer;
+          timebase_info.numer = 1;
+        }
+      else
+        {
+          /* We could just multiply by timebase_info.numer below, but why
+           * bother for a case that may never actually exist...
+           *
+           * Plus -- performing the multiplication would risk integer
+           * overflow.  If we ever actually end up in this situation, we
+           * should more carefully evaluate the correct course of action.
+           */
+          mach_timebase_info (&timebase_info); /* Get a fresh copy for a better message */
+          g_error ("Got weird mach timebase info of %d/%d.  Please file a bug against GLib.",
+                   timebase_info.numer, timebase_info.denom);
+        }
+    }
+
+  return mach_absolute_time () / timebase_info.denom;
+}
+#else
+gint64
+g_get_monotonic_time (void)
+{
+  struct timespec ts;
+  gint result;
+
+  result = clock_gettime (CLOCK_MONOTONIC, &ts);
+
+  if G_UNLIKELY (result != 0)
+    g_error ("GLib requires working CLOCK_MONOTONIC");
+
+  return (((gint64) ts.tv_sec) * 1000000) + (ts.tv_nsec / 1000);
+}
+#endif
+
 static void
 g_main_dispatch_free (gpointer dispatch)
 {
@@ -2208,7 +2413,7 @@ g_main_context_prepare (GMainContext *context,
   
   LOCK_CONTEXT (context);
 
-  context->time_is_current = FALSE;
+  context->time_is_fresh = FALSE;
 
   if (context->in_check_or_prepare)
     {
@@ -2372,7 +2577,7 @@ g_main_context_query (GMainContext *context,
     {
       *timeout = context->timeout;
       if (*timeout != 0)
-	context->time_is_current = FALSE;
+        context->time_is_fresh = FALSE;
     }
   
   UNLOCK_CONTEXT (context);
@@ -3090,33 +3295,56 @@ g_main_context_remove_poll_unlocked (GMainContext *context,
  * @source:  a #GSource
  * @timeval: #GTimeVal structure in which to store current time.
  * 
- * Gets the "current time" to be used when checking 
- * this source. The advantage of calling this function over
- * calling g_get_current_time() directly is that when 
- * checking multiple sources, GLib can cache a single value
- * instead of having to repeatedly get the system time.
+ *
+ * This function ignores @source and is otherwise the same as
+ * g_get_current_time().
  **/
 void
 g_source_get_current_time (GSource  *source,
 			   GTimeVal *timeval)
 {
+  g_get_current_time (timeval);
+}
+
+/**
+ * g_source_get_time:
+ * @source: a #GSource
+ *
+ * Gets the time to be used when checking this source. The advantage of
+ * calling this function over calling g_get_monotonic_time() directly is
+ * that when checking multiple sources, GLib can cache a single value
+ * instead of having to repeatedly get the system monotonic time.
+ *
+ * The time here is the system monotonic time, if available, or some
+ * other reasonable alternative otherwise.  See g_get_monotonic_time().
+ *
+ * Returns: the monotonic time in microseconds
+ *
+ * Since: 2.28
+ **/
+gint64
+g_source_get_time (GSource *source)
+{
   GMainContext *context;
-  
-  g_return_if_fail (source->context != NULL);
- 
+  gint64 result;
+
+  g_return_val_if_fail (source->context != NULL, 0);
+
   context = source->context;
 
   LOCK_CONTEXT (context);
 
-  if (!context->time_is_current)
+  if (!context->time_is_fresh)
     {
-      g_get_current_time (&context->current_time);
-      context->time_is_current = TRUE;
+      context->time = g_get_monotonic_time ();
+      context->time_is_fresh = TRUE;
     }
-  
-  *timeval = context->current_time;
-  
+
+  result = context->time;
+
   UNLOCK_CONTEXT (context);
+
+  return result;
 }
 
 /**
@@ -3250,160 +3478,97 @@ g_main_context_is_owner (GMainContext *context)
 
 static void
 g_timeout_set_expiration (GTimeoutSource *timeout_source,
-			  GTimeVal       *current_time)
+                          gint64          current_time)
 {
-  guint seconds = timeout_source->interval / 1000;
-  guint msecs = timeout_source->interval - seconds * 1000;
+  timeout_source->expiration = current_time +
+                               (guint64) timeout_source->interval * 1000;
 
-  timeout_source->expiration.tv_sec = current_time->tv_sec + seconds;
-  timeout_source->expiration.tv_usec = current_time->tv_usec + msecs * 1000;
-  if (timeout_source->expiration.tv_usec >= 1000000)
-    {
-      timeout_source->expiration.tv_usec -= 1000000;
-      timeout_source->expiration.tv_sec++;
-    }
-  if (timer_perturb==-1)
-    {
-      /*
-       * we want a per machine/session unique 'random' value; try the dbus
-       * address first, that has a UUID in it. If there is no dbus, use the
-       * hostname for hashing.
-       */
-      const char *session_bus_address = g_getenv ("DBUS_SESSION_BUS_ADDRESS");
-      if (!session_bus_address)
-        session_bus_address = g_getenv ("HOSTNAME");
-      if (session_bus_address)
-        timer_perturb = ABS ((gint) g_str_hash (session_bus_address));
-      else
-        timer_perturb = 0;
-    }
-  if (timeout_source->granularity)
+  if (timeout_source->seconds)
     {
-      gint remainder;
-      gint gran; /* in usecs */
-      gint perturb;
+      gint64 remainder;
+      static gint timer_perturb = -1;
 
-      gran = timeout_source->granularity * 1000;
-      perturb = timer_perturb % gran;
-      /*
-       * We want to give each machine a per machine pertubation;
-       * shift time back first, and forward later after the rounding
-       */
-
-      timeout_source->expiration.tv_usec -= perturb;
-      if (timeout_source->expiration.tv_usec < 0)
+      if (timer_perturb == -1)
         {
-          timeout_source->expiration.tv_usec += 1000000;
-          timeout_source->expiration.tv_sec--;
+          /*
+           * we want a per machine/session unique 'random' value; try the dbus
+           * address first, that has a UUID in it. If there is no dbus, use the
+           * hostname for hashing.
+           */
+          const char *session_bus_address = g_getenv ("DBUS_SESSION_BUS_ADDRESS");
+          if (!session_bus_address)
+            session_bus_address = g_getenv ("HOSTNAME");
+          if (session_bus_address)
+            timer_perturb = ABS ((gint) g_str_hash (session_bus_address)) % 1000000;
+          else
+            timer_perturb = 0;
         }
 
-      remainder = timeout_source->expiration.tv_usec % gran;
-      if (remainder >= gran/4) /* round up */
-        timeout_source->expiration.tv_usec += gran;
-      timeout_source->expiration.tv_usec -= remainder;
-      /* shift back */
-      timeout_source->expiration.tv_usec += perturb;
+      /* We want the microseconds part of the timeout to land on the
+       * 'timer_perturb' mark, but we need to make sure we don't try to
+       * set the timeout in the past.  We do this by ensuring that we
+       * always only *increase* the expiration time by adding a full
+       * second in the case that the microsecond portion decreases.
+       */
+      timeout_source->expiration -= timer_perturb;
 
-      /* the rounding may have overflown tv_usec */
-      while (timeout_source->expiration.tv_usec > 1000000)
-        {
-          timeout_source->expiration.tv_usec -= 1000000;
-          timeout_source->expiration.tv_sec++;
-        }
+      remainder = timeout_source->expiration % 1000000;
+      if (remainder >= 1000000/4)
+        timeout_source->expiration += 1000000;
+
+      timeout_source->expiration -= remainder;
+      timeout_source->expiration += timer_perturb;
     }
 }
 
 static gboolean
 g_timeout_prepare (GSource *source,
-		   gint    *timeout)
+                   gint    *timeout)
 {
-  glong sec;
-  glong msec;
-  GTimeVal current_time;
-  
-  GTimeoutSource *timeout_source = (GTimeoutSource *)source;
-
-  g_source_get_current_time (source, &current_time);
-
-  sec = timeout_source->expiration.tv_sec - current_time.tv_sec;
-  msec = (timeout_source->expiration.tv_usec - current_time.tv_usec) / 1000;
+  GTimeoutSource *timeout_source = (GTimeoutSource *) source;
+  gint64 now = g_source_get_time (source);
 
-  /* We do the following in a rather convoluted fashion to deal with
-   * the fact that we don't have an integral type big enough to hold
-   * the difference of two timevals in millseconds.
-   */
-  if (sec < 0 || (sec == 0 && msec < 0))
-    msec = 0;
-  else
+  if (now < timeout_source->expiration)
     {
-      glong interval_sec = timeout_source->interval / 1000;
-      glong interval_msec = timeout_source->interval % 1000;
-
-      if (msec < 0)
-	{
-	  msec += 1000;
-	  sec -= 1;
-	}
-      
-      if (sec > interval_sec ||
-	  (sec == interval_sec && msec > interval_msec))
-	{
-	  /* The system time has been set backwards, so we
-	   * reset the expiration time to now + timeout_source->interval;
-	   * this at least avoids hanging for long periods of time.
-	   */
-	  g_timeout_set_expiration (timeout_source, &current_time);
-	  msec = MIN (G_MAXINT, timeout_source->interval);
-	}
-      else
-	{
-	  msec = MIN (G_MAXINT, (guint)msec + 1000 * (guint)sec);
-	}
+      /* Round up to ensure that we don't try again too early */
+      *timeout = (timeout_source->expiration - now + 999) / 1000;
+      return FALSE;
     }
 
-  *timeout = (gint)msec;
-  
-  return msec == 0;
+  *timeout = 0;
+  return TRUE;
 }
 
 static gboolean 
 g_timeout_check (GSource *source)
 {
-  GTimeVal current_time;
-  GTimeoutSource *timeout_source = (GTimeoutSource *)source;
+  GTimeoutSource *timeout_source = (GTimeoutSource *) source;
+  gint64 now = g_source_get_time (source);
 
-  g_source_get_current_time (source, &current_time);
-  
-  return ((timeout_source->expiration.tv_sec < current_time.tv_sec) ||
-	  ((timeout_source->expiration.tv_sec == current_time.tv_sec) &&
-	   (timeout_source->expiration.tv_usec <= current_time.tv_usec)));
+  return timeout_source->expiration <= now;
 }
 
 static gboolean
 g_timeout_dispatch (GSource     *source,
-		    GSourceFunc  callback,
-		    gpointer     user_data)
+                    GSourceFunc  callback,
+                    gpointer     user_data)
 {
   GTimeoutSource *timeout_source = (GTimeoutSource *)source;
+  gboolean again;
 
   if (!callback)
     {
       g_warning ("Timeout source dispatched without callback\n"
-		 "You must call g_source_set_callback().");
+                 "You must call g_source_set_callback().");
       return FALSE;
     }
- 
-  if (callback (user_data))
-    {
-      GTimeVal current_time;
 
-      g_source_get_current_time (source, &current_time);
-      g_timeout_set_expiration (timeout_source, &current_time);
+  again = callback (user_data);
 
-      return TRUE;
-    }
-  else
-    return FALSE;
+  if (again)
+    g_timeout_set_expiration (timeout_source, g_source_get_time (source));
+
+  return again;
 }
 
 /**
@@ -3423,13 +3588,10 @@ g_timeout_source_new (guint interval)
 {
   GSource *source = g_source_new (&g_timeout_funcs, sizeof (GTimeoutSource));
   GTimeoutSource *timeout_source = (GTimeoutSource *)source;
-  GTimeVal current_time;
 
   timeout_source->interval = interval;
+  g_timeout_set_expiration (timeout_source, g_get_monotonic_time ());
 
-  g_get_current_time (&current_time);
-  g_timeout_set_expiration (timeout_source, &current_time);
-  
   return source;
 }
 
@@ -3455,13 +3617,11 @@ g_timeout_source_new_seconds (guint interval)
 {
   GSource *source = g_source_new (&g_timeout_funcs, sizeof (GTimeoutSource));
   GTimeoutSource *timeout_source = (GTimeoutSource *)source;
-  GTimeVal current_time;
 
-  timeout_source->interval = 1000*interval;
-  timeout_source->granularity = 1000;
+  timeout_source->interval = 1000 * interval;
+  timeout_source->seconds = TRUE;
 
-  g_get_current_time (&current_time);
-  g_timeout_set_expiration (timeout_source, &current_time);
+  g_timeout_set_expiration (timeout_source, g_get_monotonic_time ());
 
   return source;
 }
--- a/glib/gmain.h	
+++ a/glib/gmain.h	
@@ -217,6 +217,7 @@ void     g_source_remove_poll      (GSource        *source,
 
 void     g_source_get_current_time (GSource        *source,
 				    GTimeVal       *timeval);
+gint64   g_source_get_time         (GSource        *source);
 
  /* void g_source_connect_closure (GSource        *source,
                                   GClosure       *closure);
@@ -231,7 +232,8 @@ GSource *g_timeout_source_new_seconds (guint interval);
 
 /* Miscellaneous functions
  */
-void g_get_current_time		        (GTimeVal	*result);
+void   g_get_current_time                 (GTimeVal       *result);
+gint64 g_get_monotonic_time               (void);
 
 /* ============== Compat main loop stuff ================== */
 
--- a/glib/gtimer.c	
+++ a/glib/gtimer.c	
@@ -48,12 +48,9 @@ 
 #endif /* G_OS_WIN32 */
 
 #include "glib.h"
-#include "gthread.h"
+#include "gmain.h"
 #include "galias.h"
 
-#define G_NSEC_PER_SEC 1000000000
-
-#define GETTIME(v) (v = g_thread_gettime ())
 
 struct _GTimer
 {
@@ -72,7 +69,7 @@ g_timer_new (void)
   timer = g_new (GTimer, 1);
   timer->active = TRUE;
 
-  GETTIME (timer->start);
+  timer->start = g_get_monotonic_time ();
 
   return timer;
 }
@@ -92,7 +89,7 @@ g_timer_start (GTimer *timer)
 
   timer->active = TRUE;
 
-  GETTIME (timer->start);
+  timer->start = g_get_monotonic_time ();
 }
 
 void
@@ -102,7 +99,7 @@ g_timer_stop (GTimer *timer)
 
   timer->active = FALSE;
 
-  GETTIME (timer->end);
+  timer->end = g_get_monotonic_time ();
 }
 
 void
@@ -110,7 +107,7 @@ g_timer_reset (GTimer *timer)
 {
   g_return_if_fail (timer != NULL);
 
-  GETTIME (timer->start);
+  timer->start = g_get_monotonic_time ();
 }
 
 void
@@ -128,7 +125,7 @@ g_timer_continue (GTimer *timer)
 
   elapsed = timer->end - timer->start;
 
-  GETTIME (timer->start);
+  timer->start = g_get_monotonic_time ();
 
   timer->start -= elapsed;
 
@@ -145,14 +142,14 @@ g_timer_elapsed (GTimer *timer,
   g_return_val_if_fail (timer != NULL, 0);
 
   if (timer->active)
-    GETTIME (timer->end);
+    timer->end = g_get_monotonic_time ();
 
   elapsed = timer->end - timer->start;
 
-  total = elapsed / 1e9;
+  total = elapsed / 1e6;
 
   if (microseconds)
-    *microseconds = (elapsed / 1000) % 1000000;
+    *microseconds = elapsed % 1000000;
 
   return total;
 }
@@ -162,57 +159,13 @@ g_usleep (gulong microseconds)
 {
 #ifdef G_OS_WIN32
   Sleep (microseconds / 1000);
-#else /* !G_OS_WIN32 */
-# ifdef HAVE_NANOSLEEP
+#else
   struct timespec request, remaining;
   request.tv_sec = microseconds / G_USEC_PER_SEC;
   request.tv_nsec = 1000 * (microseconds % G_USEC_PER_SEC);
   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;
-      static GCond* cond = NULL;
-      GTimeVal end_time;
-      
-      g_get_current_time (&end_time);
-      if (microseconds > G_MAXLONG)
-	{
-	  microseconds -= G_MAXLONG;
-	  g_time_val_add (&end_time, G_MAXLONG);
-	}
-      g_time_val_add (&end_time, microseconds);
-
-      g_static_mutex_lock (&mutex);
-      
-      if (!cond)
-	cond = g_cond_new ();
-      
-      while (g_cond_timed_wait (cond, g_static_mutex_get_mutex (&mutex), 
-				&end_time))
-	/* do nothing */;
-      
-      g_static_mutex_unlock (&mutex);
-    }
-  else
-    {
-      struct timeval tv;
-      tv.tv_sec = microseconds / G_USEC_PER_SEC;
-      tv.tv_usec = microseconds % G_USEC_PER_SEC;
-      select(0, NULL, NULL, NULL, &tv);
-    }
-#  endif /* !HAVE_NSLEEP */
-# endif /* !HAVE_NANOSLEEP */
-#endif /* !G_OS_WIN32 */
+#endif
 }
 
 /**
--- a/glib/gtypes.h	
+++ a/glib/gtypes.h	
@@ -33,6 +33,7 @@ 
 
 #include <glibconfig.h>
 #include <glib/gmacros.h>
+#include <time.h>
 
 G_BEGIN_DECLS
 
