Subject: bug#11875: EMACS_TIME simplification

From: Paul Eggert <[email-masked]>
Date: Sat, 07 Jul 2012 13:41:42 -0700

Tags: patch

Attached is a patch to the Emacs trunk bzr 108944 that simplifies
EMACS_TIME calculation.  It replaces macros (which typically
do not work with GDB) with functions, typedefs, and enums, making
time-related code easier to debug.  The functional style also
makes the source code easier to read and maintain.  I would
have appreciated having this in my recent round of changes
to the time code.

I plan to install this after a bit more testing but thought I'd
post it for review first.
=== modified file 'lib-src/ChangeLog'
--- lib-src/ChangeLog	2012-07-07 00:20:56 +0000
+++ lib-src/ChangeLog	2012-07-07 04:53:38 +0000
@@ -1,3 +1,8 @@
+2012-07-07  Paul Eggert  <[email-masked]>
+
+	EMACS_TIME simplification.
+	* profile.c (TV2): Remove no-longer-needed static var.
+
 2012-07-07  Juanma Barranquero  <[email-masked]>
 
 	* makefile.w32-in ($(BLD)/ctags.$(O), $(BLD)/etags.$(O)):

=== modified file 'lib-src/profile.c'
--- lib-src/profile.c	2012-06-30 15:32:51 +0000
+++ lib-src/profile.c	2012-07-07 04:53:38 +0000
@@ -36,7 +36,7 @@
 #include <intprops.h>
 #include <systime.h>
 
-static EMACS_TIME TV1, TV2;
+static EMACS_TIME TV1;
 static int watch_not_started = 1; /* flag */
 static char time_string[INT_STRLEN_BOUND (uintmax_t) + sizeof "."
 			+ LOG10_EMACS_TIME_RESOLUTION];
@@ -46,7 +46,7 @@
 static void
 reset_watch (void)
 {
-  EMACS_GET_TIME (TV1);
+  TV1 = current_emacs_time ();
   watch_not_started = 0;
 }
 
@@ -57,14 +57,11 @@
 static char *
 get_time (void)
 {
-  uintmax_t s;
-  int ns;
+  EMACS_TIME TV2 = sub_emacs_time (current_emacs_time (), TV1);
+  uintmax_t s = EMACS_SECS (TV2);
+  int ns = EMACS_NSECS (TV2);
   if (watch_not_started)
     exit (EXIT_FAILURE);  /* call reset_watch first ! */
-  EMACS_GET_TIME (TV2);
-  EMACS_SUB_TIME (TV2, TV2, TV1);
-  s = EMACS_SECS (TV2);
-  ns = EMACS_NSECS (TV2);
   sprintf (time_string, "%"PRIuMAX".%0*d", s, LOG10_EMACS_TIME_RESOLUTION, ns);
   return time_string;
 }

=== modified file 'src/ChangeLog'
--- src/ChangeLog	2012-07-07 19:33:28 +0000
+++ src/ChangeLog	2012-07-07 20:04:02 +0000
@@ -1,5 +1,31 @@
 2012-07-07  Paul Eggert  <[email-masked]>
 
+	EMACS_TIME simplification.
+	This replaces macros (which typically do not work in GDB)
+	with functions, typedefs and enums, making the code easier to debug.
+	The functional style also makes code easier to read and maintain.
+	* systime.h: Include <sys/time.h> on all hosts, not just if
+	WINDOWSNT, since 'struct timeval' is needed in general.
+	(EMACS_TIME): Now a typedef, not a macro.
+	(EMACS_TIME_RESOLUTION, LOG10_EMACS_TIME_RESOLUTION): Now constants,
+	not macros.
+	(EMACS_SECS, EMACS_NSECS, EMACS_TIME_SIGN, EMACS_TIME_VALID_P)
+	(EMACS_TIME_FROM_DOUBLE, EMACS_TIME_TO_DOUBLE, EMACS_TIME_EQ)
+	(EMACS_TIME_NE, EMACS_TIME_GT, EMACS_TIME_GE, EMACS_TIME_LT)
+	(EMACS_TIME_LE): Now functions, not macros.
+	(EMACS_SET_SECS, EMACS_SET_NSECS, EMACS_SET_SECS_NSECS)
+	(EMACS_SET_USECS, EMACS_SET_SECS_USECS): Remove these macros,
+	which are not functions.  All uses rewritten to use:
+	(make_emacs_time): New function.
+	(EMACS_SECS_ADDR, EMACS_SET_INVALID_TIME, EMACS_GET_TIME)
+	(EMACS_ADD_TIME, EMACS_SUB_TIME): Remove these macros, which are
+	not functions.  All uses rewritten to use the following, respectively:
+	(emacs_secs_addr, invalid_emacs_time, get_emacs_time)
+	(add_emacs_time, sub_emacs_time): New functions.
+	* atimer.c: Don't include <sys/time.h>,	as "systime.h" does this.
+	* fileio.c (Fcopy_file):
+	* xterm.c (XTflash): Get the current time closer to when it's used.
+
 	* lread.c (load_path_check): Now static.
 
 	Fix some minor --with-ns problems found by static checking.

=== modified file 'src/alloc.c'
--- src/alloc.c	2012-07-06 05:07:44 +0000
+++ src/alloc.c	2012-07-07 04:53:38 +0000
@@ -5380,7 +5380,7 @@
   int message_p;
   Lisp_Object total[8];
   ptrdiff_t count = SPECPDL_INDEX ();
-  EMACS_TIME t1, t2, t3;
+  EMACS_TIME t1;
 
   if (abort_on_gc)
     abort ();
@@ -5429,7 +5429,7 @@
       }
   }
 
-  EMACS_GET_TIME (t1);
+  t1 = current_emacs_time ();
 
   /* In case user calls debug_print during GC,
      don't let that cause a recursive GC.  */
@@ -5683,8 +5683,8 @@
   /* Accumulate statistics.  */
   if (FLOATP (Vgc_elapsed))
     {
-      EMACS_GET_TIME (t2);
-      EMACS_SUB_TIME (t3, t2, t1);
+      EMACS_TIME t2 = current_emacs_time ();
+      EMACS_TIME t3 = sub_emacs_time (t2, t1);
       Vgc_elapsed = make_float (XFLOAT_DATA (Vgc_elapsed)
 				+ EMACS_TIME_TO_DOUBLE (t3));
     }

=== modified file 'src/atimer.c'
--- src/atimer.c	2012-07-05 06:32:41 +0000
+++ src/atimer.c	2012-07-07 04:53:38 +0000
@@ -26,7 +26,6 @@
 #include "blockinput.h"
 #include "atimer.h"
 #include <unistd.h>
-#include <sys/time.h>
 
 /* Free-list of atimer structures.  */
 
@@ -93,10 +92,7 @@
 #ifndef HAVE_SETITIMER
   if (EMACS_NSECS (timestamp) != 0
       && EMACS_SECS (timestamp) < TYPE_MAXIMUM (time_t))
-    {
-      EMACS_SET_USECS (timestamp, 0);
-      EMACS_SET_SECS (timestamp, EMACS_SECS (timestamp) + 1);
-    }
+    timestamp = make_emacs_time (EMACS_SECS (timestamp) + 1, 0);
 #endif /* not HAVE_SETITIMER */
 
   /* Get an atimer structure from the free-list, or allocate
@@ -125,13 +121,11 @@
       break;
 
     case ATIMER_RELATIVE:
-      EMACS_GET_TIME (t->expiration);
-      EMACS_ADD_TIME (t->expiration, t->expiration, timestamp);
+      t->expiration = add_emacs_time (current_emacs_time (), timestamp);
       break;
 
     case ATIMER_CONTINUOUS:
-      EMACS_GET_TIME (t->expiration);
-      EMACS_ADD_TIME (t->expiration, t->expiration, timestamp);
+      t->expiration = add_emacs_time (current_emacs_time (), timestamp);
       t->interval = timestamp;
       break;
     }
@@ -285,31 +279,25 @@
 {
   if (atimers)
     {
-      EMACS_TIME now, timestamp;
 #ifdef HAVE_SETITIMER
       struct itimerval it;
 #endif
 
       /* Determine s/us till the next timer is ripe.  */
-      EMACS_GET_TIME (now);
+      EMACS_TIME now = current_emacs_time ();
 
       /* Don't set the interval to 0; this disables the timer.  */
-      if (EMACS_TIME_LE (atimers->expiration, now))
-	{
-	  EMACS_SET_SECS (timestamp, 0);
-	  EMACS_SET_USECS (timestamp, 1000);
-	}
-      else
-	EMACS_SUB_TIME (timestamp, atimers->expiration, now);
-
+      EMACS_TIME interval = (EMACS_TIME_LE (atimers->expiration, now)
+			     ? make_emacs_time (0, 1000 * 1000)
+			     : sub_emacs_time (atimers->expiration, now));
 
 #ifdef HAVE_SETITIMER
 
       memset (&it, 0, sizeof it);
-      it.it_value = make_timeval (timestamp);
+      it.it_value = make_timeval (interval);
       setitimer (ITIMER_REAL, &it, 0);
 #else /* not HAVE_SETITIMER */
-      alarm (max (EMACS_SECS (timestamp), 1));
+      alarm (max (EMACS_SECS (interval), 1));
 #endif /* not HAVE_SETITIMER */
     }
 }
@@ -344,7 +332,7 @@
 
   while (atimers
 	 && (pending_atimers = interrupt_input_blocked) == 0
-	 && (EMACS_GET_TIME (now),
+	 && (now = current_emacs_time (),
 	     EMACS_TIME_LE (atimers->expiration, now)))
     {
       struct atimer *t;
@@ -355,7 +343,7 @@
 
       if (t->type == ATIMER_CONTINUOUS)
 	{
-	  EMACS_ADD_TIME (t->expiration, now, t->interval);
+	  t->expiration = add_emacs_time (now, t->interval);
 	  schedule_atimer (t);
 	}
       else

=== modified file 'src/buffer.c'
--- src/buffer.c	2012-07-06 07:34:37 +0000
+++ src/buffer.c	2012-07-07 04:53:38 +0000
@@ -705,7 +705,7 @@
   BVAR (b, filename) = Qnil;
   BVAR (b, file_truename) = Qnil;
   BVAR (b, directory) = (current_buffer) ? BVAR (current_buffer, directory) : Qnil;
-  EMACS_SET_SECS_NSECS (b->modtime, 0, UNKNOWN_MODTIME_NSECS);
+  b->modtime = make_emacs_time (0, UNKNOWN_MODTIME_NSECS);
   b->modtime_size = -1;
   XSETFASTINT (BVAR (b, save_length), 0);
   b->last_window_start = 1;

=== modified file 'src/dispnew.c'
--- src/dispnew.c	2012-07-05 18:35:48 +0000
+++ src/dispnew.c	2012-07-07 20:00:04 +0000
@@ -3190,7 +3190,6 @@
     force_p = 1;
   else if (!force_p && NUMBERP (Vredisplay_preemption_period))
     {
-      EMACS_TIME tm;
       double p = XFLOATINT (Vredisplay_preemption_period);
 
       if (detect_input_pending_ignore_squeezables ())
@@ -3199,9 +3198,9 @@
 	  goto do_pause;
 	}
 
-      EMACS_GET_TIME (tm);
       preemption_period = EMACS_TIME_FROM_DOUBLE (p);
-      EMACS_ADD_TIME (preemption_next_check, tm, preemption_period);
+      preemption_next_check = add_emacs_time (current_emacs_time (),
+					      preemption_period);
     }
 
   if (FRAME_WINDOW_P (f))
@@ -3343,12 +3342,10 @@
 	force_p = 1;
       else if (!force_p && NUMBERP (Vredisplay_preemption_period))
 	{
-	  EMACS_TIME tm;
 	  double p = XFLOATINT (Vredisplay_preemption_period);
-
-	  EMACS_GET_TIME (tm);
 	  preemption_period = EMACS_TIME_FROM_DOUBLE (p);
-	  EMACS_ADD_TIME (preemption_next_check, tm, preemption_period);
+	  preemption_next_check = add_emacs_time (current_emacs_time (),
+						  preemption_period);
 	}
 
       /* Update W.  */
@@ -3595,11 +3592,11 @@
 #if PERIODIC_PREEMPTION_CHECKING
 	    if (!force_p)
 	      {
-		EMACS_TIME tm;
-		EMACS_GET_TIME (tm);
+		EMACS_TIME tm = current_emacs_time ();
 		if (EMACS_TIME_LT (preemption_next_check, tm))
 		  {
-		    EMACS_ADD_TIME (preemption_next_check, tm, preemption_period);
+		    preemption_next_check = add_emacs_time (tm,
+							    preemption_period);
 		    if (detect_input_pending_ignore_squeezables ())
 		      break;
 		  }
@@ -4700,11 +4697,10 @@
 #if PERIODIC_PREEMPTION_CHECKING
 	  if (!force_p)
 	    {
-	      EMACS_TIME tm;
-	      EMACS_GET_TIME (tm);
+	      EMACS_TIME tm = current_emacs_time ();
 	      if (EMACS_TIME_LT (preemption_next_check, tm))
 		{
-		  EMACS_ADD_TIME (preemption_next_check, tm, preemption_period);
+		  preemption_next_check = add_emacs_time (tm, preemption_period);
 		  if (detect_input_pending_ignore_squeezables ())
 		    break;
 		}

=== modified file 'src/editfns.c'
--- src/editfns.c	2012-07-07 01:57:42 +0000
+++ src/editfns.c	2012-07-07 20:00:04 +0000
@@ -1408,10 +1408,7 @@
 picosecond counts.  */)
   (void)
 {
-  EMACS_TIME t;
-
-  EMACS_GET_TIME (t);
-  return make_lisp_time (t);
+  return make_lisp_time (current_emacs_time ());
 }
 
 DEFUN ("get-internal-run-time", Fget_internal_run_time, Sget_internal_run_time,
@@ -1428,7 +1425,6 @@
   struct rusage usage;
   time_t secs;
   int usecs;
-  EMACS_TIME t;
 
   if (getrusage (RUSAGE_SELF, &usage) < 0)
     /* This shouldn't happen.  What action is appropriate?  */
@@ -1442,8 +1438,7 @@
       usecs -= 1000000;
       secs++;
     }
-  EMACS_SET_SECS_USECS (t, secs, usecs);
-  return make_lisp_time (t);
+  return make_lisp_time (make_emacs_time (secs, usecs * 1000));
 #else /* ! HAVE_GETRUSAGE  */
 #ifdef WINDOWSNT
   return w32_get_internal_run_time ();
@@ -1560,8 +1555,7 @@
 	  /* Return the greatest representable time that is not greater
 	     than the requested time.  */
 	  time_t sec = hi;
-	  EMACS_SET_SECS_NSECS (*result, (sec << 16) + lo,
-				us * 1000 + ps / 1000);
+	  *result = make_emacs_time ((sec << 16) + lo, us * 1000 + ps / 1000);
 	}
       else
 	{
@@ -1587,7 +1581,7 @@
 {
   EMACS_TIME t;
   if (NILP (specified_time))
-    EMACS_GET_TIME (t);
+    t = current_emacs_time ();
   else
     {
       Lisp_Object high, low, usec, psec;
@@ -1635,8 +1629,7 @@
   double t;
   if (NILP (specified_time))
     {
-      EMACS_TIME now;
-      EMACS_GET_TIME (now);
+      EMACS_TIME now = current_emacs_time ();
       t = EMACS_SECS (now) + EMACS_NSECS (now) / 1e9;
     }
   else
@@ -1780,11 +1773,12 @@
 
   while (1)
     {
+      time_t *taddr = emacs_secs_addr (&t);
       BLOCK_INPUT;
 
       synchronize_system_time_locale ();
 
-      tm = ut ? gmtime (EMACS_SECS_ADDR (t)) : localtime (EMACS_SECS_ADDR (t));
+      tm = ut ? gmtime (taddr) : localtime (taddr);
       if (! tm)
 	{
 	  UNBLOCK_INPUT;
@@ -2065,10 +2059,10 @@
   Lisp_Object zone_offset, zone_name;
 
   zone_offset = Qnil;
-  EMACS_SET_SECS_NSECS (value, lisp_seconds_argument (specified_time), 0);
+  value = make_emacs_time (lisp_seconds_argument (specified_time), 0);
   zone_name = format_time_string ("%Z", sizeof "%Z" - 1, value, 0, &localtm);
   BLOCK_INPUT;
-  t = gmtime (EMACS_SECS_ADDR (value));
+  t = gmtime (emacs_secs_addr (&value));
   if (t)
     offset = tm_diff (&localtm, t);
   UNBLOCK_INPUT;

=== modified file 'src/fileio.c'
--- src/fileio.c	2012-07-07 01:57:42 +0000
+++ src/fileio.c	2012-07-07 04:53:38 +0000
@@ -1925,12 +1925,12 @@
       DWORD attributes;
       char * filename;
 
-      EMACS_GET_TIME (now);
       filename = SDATA (encoded_newname);
 
       /* Ensure file is writable while its modified time is set.  */
       attributes = GetFileAttributes (filename);
       SetFileAttributes (filename, attributes & ~FILE_ATTRIBUTE_READONLY);
+      now = current_emacs_time ();
       if (set_file_times (-1, filename, now, now))
 	{
 	  /* Restore original attributes.  */
@@ -3217,12 +3217,10 @@
 static EMACS_TIME
 time_error_value (int errnum)
 {
-  EMACS_TIME t;
   int ns = (errnum == ENOENT || errnum == EACCES || errnum == ENOTDIR
 	    ? NONEXISTENT_MODTIME_NSECS
 	    : UNKNOWN_MODTIME_NSECS);
-  EMACS_SET_SECS_NSECS (t, 0, ns);
-  return t;
+  return make_emacs_time (0, ns);
 }
 
 DEFUN ("insert-file-contents", Finsert_file_contents, Sinsert_file_contents,
@@ -5082,7 +5080,7 @@
   struct stat st;
   Lisp_Object handler;
   Lisp_Object filename;
-  EMACS_TIME mtime, diff, one_second;
+  EMACS_TIME mtime, diff;
 
   if (NILP (buf))
     b = current_buffer;
@@ -5110,11 +5108,10 @@
   if ((EMACS_TIME_EQ (mtime, b->modtime)
        /* If both exist, accept them if they are off by one second.  */
        || (EMACS_TIME_VALID_P (mtime) && EMACS_TIME_VALID_P (b->modtime)
-	   && ((EMACS_TIME_LT (mtime, b->modtime)
-		? EMACS_SUB_TIME (diff, b->modtime, mtime)
-		: EMACS_SUB_TIME (diff, mtime, b->modtime)),
-	       EMACS_SET_SECS_NSECS (one_second, 1, 0),
-	       EMACS_TIME_LE (diff, one_second))))
+	   && ((diff = (EMACS_TIME_LT (mtime, b->modtime)
+			? sub_emacs_time (b->modtime, mtime)
+			: sub_emacs_time (mtime, b->modtime))),
+	       EMACS_TIME_LE (diff, make_emacs_time (1, 0)))))
       && (st.st_size == b->modtime_size
           || b->modtime_size < 0))
     return Qt;
@@ -5127,7 +5124,7 @@
 Next attempt to save will certainly not complain of a discrepancy.  */)
   (void)
 {
-  EMACS_SET_SECS_NSECS (current_buffer->modtime, 0, UNKNOWN_MODTIME_NSECS);
+  current_buffer->modtime = make_emacs_time (0, UNKNOWN_MODTIME_NSECS);
   current_buffer->modtime_size = -1;
   return Qnil;
 }
@@ -5426,9 +5423,8 @@
 		|| NILP (Ffind_file_name_handler (BVAR (b, auto_save_file_name),
 						  Qwrite_region))))
 	  {
-	    EMACS_TIME before_time, after_time;
-
-	    EMACS_GET_TIME (before_time);
+	    EMACS_TIME before_time = current_emacs_time ();
+	    EMACS_TIME after_time;
 
 	    /* If we had a failure, don't try again for 20 minutes.  */
 	    if (b->auto_save_failure_time > 0
@@ -5465,7 +5461,7 @@
 	    XSETFASTINT (BVAR (current_buffer, save_length), Z - BEG);
 	    set_buffer_internal (old);
 
-	    EMACS_GET_TIME (after_time);
+	    after_time = current_emacs_time ();
 
 	    /* If auto-save took more than 60 seconds,
 	       assume it was an NFS failure that got a timeout.  */

=== modified file 'src/fns.c'
--- src/fns.c	2012-07-05 18:35:48 +0000
+++ src/fns.c	2012-07-07 04:53:38 +0000
@@ -78,8 +78,7 @@
 
   if (EQ (limit, Qt))
     {
-      EMACS_TIME t;
-      EMACS_GET_TIME (t);
+      EMACS_TIME t = current_emacs_time ();
       seed_random (getpid () ^ EMACS_SECS (t) ^ EMACS_NSECS (t));
     }

=== modified file 'src/image.c'
--- src/image.c	2012-07-07 19:23:41 +0000
+++ src/image.c	2012-07-07 20:04:02 +0000
@@ -1061,7 +1061,7 @@
 prepare_image_for_display (struct frame *f, struct image *img)
 {
   /* We're about to display IMG, so set its timestamp to `now'.  */
-  EMACS_GET_TIME (img->timestamp);
+  img->timestamp = current_emacs_time ();
 
   /* If IMG doesn't have a pixmap yet, load it now, using the image
      type dependent loader function.  */
@@ -1520,8 +1520,8 @@
 	    delay = 1600 * delay / nimages / nimages;
 	  delay = max (delay, 1);
 
-	  EMACS_GET_TIME (t);
-	  EMACS_SUB_TIME (old, t, EMACS_TIME_FROM_DOUBLE (delay));
+	  t = current_emacs_time ();
+	  old = sub_emacs_time (t, EMACS_TIME_FROM_DOUBLE (delay));
 
 	  for (i = 0; i < c->used; ++i)
 	    {
@@ -1792,7 +1792,7 @@
     }
 
   /* We're using IMG, so set its timestamp to `now'.  */
-  EMACS_GET_TIME (img->timestamp);
+  img->timestamp = current_emacs_time ();
 
   /* Value is the image id.  */
   return img->id;

=== modified file 'src/keyboard.c'
--- src/keyboard.c	2012-07-05 18:35:48 +0000
+++ src/keyboard.c	2012-07-07 20:31:07 +0000
@@ -2017,12 +2017,11 @@
 	  || EMACS_SECS (poll_timer->interval) != polling_period)
 	{
 	  time_t period = max (1, min (polling_period, TYPE_MAXIMUM (time_t)));
-	  EMACS_TIME interval;
+	  EMACS_TIME interval = make_emacs_time (period, 0);
 
 	  if (poll_timer)
 	    cancel_atimer (poll_timer);
 
-	  EMACS_SET_SECS_USECS (interval, period, 0);
 	  poll_timer = start_atimer (ATIMER_CONTINUOUS, interval,
 				     poll_for_input, NULL);
 	}
@@ -2786,13 +2785,8 @@
     {
       KBOARD *kb IF_LINT (= NULL);
 
-      if (end_time)
-	{
-	  EMACS_TIME now;
-	  EMACS_GET_TIME (now);
-	  if (EMACS_TIME_GE (now, *end_time))
-	    goto exit;
-	}
+      if (end_time && EMACS_TIME_LE (*end_time, current_emacs_time ()))
+	goto exit;
 
       /* Actually read a character, waiting if necessary.  */
       save_getcjmp (save_jump);
@@ -3847,13 +3841,12 @@
 #endif
       if (end_time)
 	{
-	  EMACS_TIME duration;
-	  EMACS_GET_TIME (duration);
-	  if (EMACS_TIME_GE (duration, *end_time))
+	  EMACS_TIME now = current_emacs_time ();
+	  if (EMACS_TIME_LE (*end_time, now))
 	    return Qnil;	/* Finished waiting.  */
 	  else
 	    {
-	      EMACS_SUB_TIME (duration, *end_time, duration);
+	      EMACS_TIME duration = sub_emacs_time (*end_time, now);
 	      wait_reading_process_output (min (EMACS_SECS (duration),
 						WAIT_READING_MAX),
 					   EMACS_NSECS (duration),
@@ -4256,8 +4249,7 @@
   if (EMACS_TIME_VALID_P (timer_idleness_start_time))
     return;
 
-  EMACS_GET_TIME (timer_idleness_start_time);
-
+  timer_idleness_start_time = current_emacs_time ();
   timer_last_idleness_start_time = timer_idleness_start_time;
 
   /* Mark all idle-time timers as once again candidates for running.  */
@@ -4278,7 +4270,7 @@
 static void
 timer_stop_idle (void)
 {
-  EMACS_SET_INVALID_TIME (timer_idleness_start_time);
+  timer_idleness_start_time = invalid_emacs_time ();
 }
 
 /* Resume idle timer from last idle start time.  */
@@ -4339,7 +4331,7 @@
   Lisp_Object timers, idle_timers, chosen_timer;
   struct gcpro gcpro1, gcpro2, gcpro3;
 
-  EMACS_SET_INVALID_TIME (nexttime);
+  nexttime = invalid_emacs_time ();
 
   /* Always consider the ordinary timers.  */
   timers = Vtimer_list;
@@ -4361,11 +4353,10 @@
 
   if (CONSP (timers) || CONSP (idle_timers))
     {
-      EMACS_GET_TIME (now);
-      if (EMACS_TIME_VALID_P (timer_idleness_start_time))
-	EMACS_SUB_TIME (idleness_now, now, timer_idleness_start_time);
-      else
-	EMACS_SET_SECS_NSECS (idleness_now, 0, 0);
+      now = current_emacs_time ();
+      idleness_now = (EMACS_TIME_VALID_P (timer_idleness_start_time)
+		      ? sub_emacs_time (now, timer_idleness_start_time)
+		      : make_emacs_time (0, 0));
     }
 
   while (CONSP (timers) || CONSP (idle_timers))
@@ -4374,12 +4365,10 @@
       Lisp_Object timer = Qnil, idle_timer = Qnil;
       EMACS_TIME timer_time, idle_timer_time;
       EMACS_TIME difference;
-      EMACS_TIME timer_difference, idle_timer_difference;
+      EMACS_TIME timer_difference = invalid_emacs_time ();
+      EMACS_TIME idle_timer_difference = invalid_emacs_time ();
       int ripe, timer_ripe = 0, idle_timer_ripe = 0;
 
-      EMACS_SET_INVALID_TIME (timer_difference);
-      EMACS_SET_INVALID_TIME (idle_timer_difference);
-
       /* Set TIMER and TIMER_DIFFERENCE
 	 based on the next ordinary timer.
 	 TIMER_DIFFERENCE is the distance in time from NOW to when
@@ -4395,10 +4384,9 @@
 	    }
 
 	  timer_ripe = EMACS_TIME_LE (timer_time, now);
-	  if (timer_ripe)
-	    EMACS_SUB_TIME (timer_difference, now, timer_time);
-	  else
-	    EMACS_SUB_TIME (timer_difference, timer_time, now);
+	  timer_difference = (timer_ripe
+			      ? sub_emacs_time (now, timer_time)
+			      : sub_emacs_time (timer_time, now));
 	}
 
       /* Likewise for IDLE_TIMER and IDLE_TIMER_DIFFERENCE
@@ -4413,12 +4401,10 @@
 	    }
 
 	  idle_timer_ripe = EMACS_TIME_LE (idle_timer_time, idleness_now);
-	  if (idle_timer_ripe)
-	    EMACS_SUB_TIME (idle_timer_difference,
-			    idleness_now, idle_timer_time);
-	  else
-	    EMACS_SUB_TIME (idle_timer_difference,
-			    idle_timer_time, idleness_now);
+	  idle_timer_difference =
+	    (idle_timer_ripe
+	     ? sub_emacs_time (idleness_now, idle_timer_time)
+	     : sub_emacs_time (idle_timer_time, idleness_now));
 	}
 
       /* Decide which timer is the next timer,
@@ -4474,8 +4460,7 @@
                  return 0 to indicate that.  */
 	    }
 
-          EMACS_SET_SECS (nexttime, 0);
-          EMACS_SET_USECS (nexttime, 0);
+	  nexttime = make_emacs_time (0, 0);
 	}
       else
 	/* When we encounter a timer that is still waiting,
@@ -4527,14 +4512,8 @@
   (void)
 {
   if (EMACS_TIME_VALID_P (timer_idleness_start_time))
-    {
-      EMACS_TIME now, idleness_now;
-
-      EMACS_GET_TIME (now);
-      EMACS_SUB_TIME (idleness_now, now, timer_idleness_start_time);
-
-      return make_lisp_time (idleness_now);
-    }
+    return make_lisp_time (sub_emacs_time (current_emacs_time (),
+					   timer_idleness_start_time));
 
   return Qnil;
 }
@@ -7224,7 +7203,7 @@
 #endif
 
   if (input_available_clear_time)
-    EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
+    *input_available_clear_time = make_emacs_time (0, 0);
 
 #ifndef SYNC_INPUT
   handle_async_input ();
@@ -7327,7 +7306,7 @@
 	    /* Tell wait_reading_process_output that it needs to wake
 	       up and look around.  */
 	    if (input_available_clear_time)
-	      EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
+	      *input_available_clear_time = make_emacs_time (0, 0);
 	  }
 	break;
       }
@@ -11344,7 +11323,7 @@
   quit_char = Ctl ('g');
   Vunread_command_events = Qnil;
   unread_command_char = -1;
-  EMACS_SET_INVALID_TIME (timer_idleness_start_time);
+  timer_idleness_start_time = invalid_emacs_time ();
   total_keys = 0;
   recent_keys_index = 0;
   kbd_fetch_ptr = kbd_buffer;

=== modified file 'src/lread.c'
--- src/lread.c	2012-07-07 19:33:28 +0000
+++ src/lread.c	2012-07-07 20:04:02 +0000
@@ -600,8 +600,7 @@
     {
       double duration = extract_float (seconds);
       EMACS_TIME wait_time = EMACS_TIME_FROM_DOUBLE (duration);
-      EMACS_GET_TIME (end_time);
-      EMACS_ADD_TIME (end_time, end_time, wait_time);
+      end_time = add_emacs_time (current_emacs_time (), wait_time);
     }
 
 /* Read until we get an acceptable event.  */

=== modified file 'src/msdos.c'
--- src/msdos.c	2012-07-05 06:32:41 +0000
+++ src/msdos.c	2012-07-07 20:00:04 +0000
@@ -4136,14 +4136,14 @@
       EMACS_TIME clnow, cllast, cldiff;
 
       gettime (&t);
-      EMACS_SET_SECS_NSECS (cllast, t.tv_sec, t.tv_nsec);
+      cllast = make_emacs_time (t.tv_sec, t.tv_nsec);
 
       while (!check_input || !detect_input_pending ())
 	{
 	  gettime (&t);
-	  EMACS_SET_SECS_NSECS (clnow, t.tv_sec, t.tv_nsec);
-	  EMACS_SUB_TIME (cldiff, clnow, cllast);
-	  EMACS_SUB_TIME (*timeout, *timeout, cldiff);
+	  clnow = make_emacs_time (t.tv_sec, t.tv_nsec);
+	  cldiff = sub_emacs_time (clnow, cllast);
+	  *timeout = sub_emacs_time (*timeout, cldiff);
 
 	  /* Stop when timeout value crosses zero.  */
 	  if (EMACS_TIME_SIGN (*timeout) <= 0)

=== modified file 'src/nsterm.m'
--- src/nsterm.m	2012-07-06 21:07:46 +0000
+++ src/nsterm.m	2012-07-07 04:53:38 +0000
@@ -389,21 +389,16 @@
      Blocking timer utility used by ns_ring_bell
    -------------------------------------------------------------------------- */
 {
-  EMACS_TIME wakeup, delay;
-
-  EMACS_GET_TIME (wakeup);
-  EMACS_SET_SECS_USECS (delay, 0, usecs);
-  EMACS_ADD_TIME (wakeup, wakeup, delay);
+  EMACS_TIME wakeup = add_emacs_time (current_emacs_time (),
+				      make_emacs_time (0, usecs * 1000));
 
   /* Keep waiting until past the time wakeup.  */
   while (1)
     {
-      EMACS_TIME timeout;
-
-      EMACS_GET_TIME (timeout);
-      if (EMACS_TIME_LE (wakeup, timeout))
+      EMACS_TIME now = current_emacs_time ();
+      if (EMACS_TIME_LE (wakeup, now))
 	break;
-      EMACS_SUB_TIME (timeout, wakeup, timeout);
+      timeout = sub_emacs_time (wakeup, now);
 
       /* Try to wait that long--but we might wake up sooner.  */
       pselect (0, NULL, NULL, NULL, &timeout, NULL);

=== modified file 'src/process.c'
--- src/process.c	2012-07-06 16:57:32 +0000
+++ src/process.c	2012-07-07 04:53:38 +0000
@@ -1852,10 +1852,9 @@
 	 So have an interrupt jar it loose.  */
       {
 	struct atimer *timer;
-	EMACS_TIME offset;
+	EMACS_TIME offset = make_emacs_time (1, 0);
 
 	stop_polling ();
-	EMACS_SET_SECS_USECS (offset, 1, 0);
 	timer = start_atimer (ATIMER_RELATIVE, offset, create_process_1, 0);
 
 	if (forkin >= 0)
@@ -4309,9 +4308,8 @@
      compute the absolute time to return at.  */
   if (time_limit || 0 < nsecs)
     {
-      EMACS_GET_TIME (end_time);
-      EMACS_SET_SECS_NSECS (timeout, time_limit, nsecs);
-      EMACS_ADD_TIME (end_time, end_time, timeout);
+      timeout = make_emacs_time (time_limit, nsecs);
+      end_time = add_emacs_time (current_emacs_time (), timeout);
     }
 
   while (1)
@@ -4340,18 +4338,18 @@
 	     gobble output available now
 	     but don't wait at all. */
 
-	  EMACS_SET_SECS_USECS (timeout, 0, 0);
+	  timeout = make_emacs_time (0, 0);
 	}
       else if (time_limit || 0 < nsecs)
 	{
-	  EMACS_GET_TIME (timeout);
-	  if (EMACS_TIME_LE (end_time, timeout))
+	  EMACS_TIME now = current_emacs_time ();
+	  if (EMACS_TIME_LE (end_time, now))
 	    break;
-	  EMACS_SUB_TIME (timeout, end_time, timeout);
+	  timeout = sub_emacs_time (end_time, now);
 	}
       else
 	{
-	  EMACS_SET_SECS_USECS (timeout, 100000, 0);
+	  timeout = make_emacs_time (100000, 0);
 	}
 
       /* Normally we run timers here.
@@ -4436,7 +4434,7 @@
             Atemp = input_wait_mask;
 	  Ctemp = write_mask;
 
-	  EMACS_SET_SECS_USECS (timeout, 0, 0);
+	  timeout = make_emacs_time (0, 0);
 	  if ((pselect (max (max_process_desc, max_input_desc) + 1,
 			&Atemp,
 #ifdef NON_BLOCKING_CONNECT
@@ -4588,7 +4586,7 @@
 			nsecs = XPROCESS (proc)->read_output_delay;
 		    }
 		}
-	      EMACS_SET_SECS_NSECS (timeout, 0, nsecs);
+	      timeout = make_emacs_time (0, nsecs);
 	      process_output_skip = 0;
 	    }
 #endif
@@ -6424,7 +6422,7 @@
 	  /* Tell wait_reading_process_output that it needs to wake up and
 	     look around.  */
 	  if (input_available_clear_time)
-	    EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
+	    *input_available_clear_time = make_emacs_time (0, 0);
 	}
 
       /* There was no asynchronous process found for that pid: we have
@@ -6442,7 +6440,7 @@
 	  /* Tell wait_reading_process_output that it needs to wake up and
 	     look around.  */
 	  if (input_available_clear_time)
-	    EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
+	    *input_available_clear_time = make_emacs_time (0, 0);
 	}
 
     sigchld_end_of_loop:
@@ -6857,9 +6855,8 @@
   /* What does time_limit really mean?  */
   if (time_limit || 0 < nsecs)
     {
-      EMACS_GET_TIME (end_time);
-      EMACS_SET_SECS_NSECS (timeout, time_limit, nsecs);
-      EMACS_ADD_TIME (end_time, end_time, timeout);
+      timeout = make_emacs_time (time_limit, nsecs);
+      end_time = add_emacs_time (current_emacs_time (), timeout);
     }
 
   /* Turn off periodic alarms (in case they are in use)
@@ -6890,18 +6887,18 @@
 	     gobble output available now
 	     but don't wait at all. */
 
-	  EMACS_SET_SECS_USECS (timeout, 0, 0);
+	  timeout = make_emacs_time (0, 0);
 	}
       else if (time_limit || 0 < nsecs)
 	{
-	  EMACS_GET_TIME (timeout);
-	  if (EMACS_TIME_LE (end_time, timeout))
+	  EMACS_TIME now = current_emacs_time ();
+	  if (EMACS_TIME_LE (end_time, now))
 	    break;
-	  EMACS_SUB_TIME (timeout, end_time, timeout);
+	  timeout = sub_emacs_time (end_time, now);
 	}
       else
 	{
-	  EMACS_SET_SECS_USECS (timeout, 100000, 0);
+	  timeout = make_emacs_time (100000, 0);
 	}
 
       /* If our caller will not immediately handle keyboard events,

=== modified file 'src/sysdep.c'
--- src/sysdep.c	2012-07-07 18:16:15 +0000
+++ src/sysdep.c	2012-07-07 20:04:02 +0000
@@ -2586,7 +2586,6 @@
   unsigned long long s = tval / hz;
   unsigned long long frac = tval % hz;
   int ns;
-  EMACS_TIME t;
 
   if (TYPE_MAXIMUM (time_t) < s)
     time_overflow ();
@@ -2603,8 +2602,7 @@
       ns = frac / hz_per_ns;
     }
 
-  EMACS_SET_SECS_NSECS (t, s, ns);
-  return t;
+  return make_emacs_time (s, ns);
 }
 
 static Lisp_Object
@@ -2618,9 +2616,7 @@
 get_up_time (void)
 {
   FILE *fup;
-  EMACS_TIME up;
-
-  EMACS_SET_SECS_NSECS (up, 0, 0);
+  EMACS_TIME up = make_emacs_time (0, 0);
 
   BLOCK_INPUT;
   fup = fopen ("/proc/uptime", "r");
@@ -2649,7 +2645,7 @@
 		upfrac /= 10;
 	      upfrac = min (upfrac, EMACS_TIME_RESOLUTION - 1);
 	    }
-	  EMACS_SET_SECS_NSECS (up, upsec, upfrac);
+	  up = make_emacs_time (upsec, upfrac);
 	}
       fclose (fup);
     }
@@ -2877,15 +2873,15 @@
 	  attrs = Fcons (Fcons (Qpri, make_number (priority)), attrs);
 	  attrs = Fcons (Fcons (Qnice, make_number (niceness)), attrs);
 	  attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (thcount_eint)), attrs);
-	  EMACS_GET_TIME (tnow);
+	  tnow = current_emacs_time ();
 	  telapsed = get_up_time ();
-	  EMACS_SUB_TIME (tboot, tnow, telapsed);
+	  tboot = sub_emacs_time (tnow, telapsed);
 	  tstart = time_from_jiffies (start, clocks_per_sec);
-	  EMACS_ADD_TIME (tstart, tboot, tstart);
+	  tstart = add_emacs_time (tboot, tstart);
 	  attrs = Fcons (Fcons (Qstart, make_lisp_time (tstart)), attrs);
 	  attrs = Fcons (Fcons (Qvsize, make_fixnum_or_float (vsize/1024)), attrs);
 	  attrs = Fcons (Fcons (Qrss, make_fixnum_or_float (4*rss)), attrs);
-	  EMACS_SUB_TIME (telapsed, tnow, tstart);
+	  telapsed = sub_emacs_time (tnow, tstart);
 	  attrs = Fcons (Fcons (Qetime, make_lisp_time (telapsed)), attrs);
 	  us_time = time_from_jiffies (u_time + s_time, clocks_per_sec);
 	  pcpu = (EMACS_TIME_TO_DOUBLE (us_time)
@@ -3109,9 +3105,7 @@
 static EMACS_TIME
 timeval_to_EMACS_TIME (struct timeval t)
 {
-  EMACS_TIME e;
-  EMACS_SET_SECS_NSECS (e, t.tv_sec, t.tv_usec * 1000);
-  return e;
+  return make_emacs_time (t.tv_sec, t.tv_usec * 1000);
 }
 
 static Lisp_Object
@@ -3219,9 +3213,8 @@
 		 attrs);
   attrs = Fcons (Fcons (Qstime, make_lisp_timeval (proc.ki_rusage.ru_stime)),
 		 attrs);
-  EMACS_ADD_TIME (t,
-		  timeval_to_EMACS_TIME (proc.ki_rusage.ru_utime),
-		  timeval_to_EMACS_TIME (proc.ki_rusage.ru_stime));
+  t = add_emacs_time (timeval_to_EMACS_TIME (proc.ki_rusage.ru_utime),
+		      timeval_to_EMACS_TIME (proc.ki_rusage.ru_stime));
   attrs = Fcons (Fcons (Qtime, make_lisp_time (t)), attrs);
 
   attrs = Fcons (Fcons (Qcutime,
@@ -3230,9 +3223,8 @@
   attrs = Fcons (Fcons (Qcstime,
 			make_lisp_timeval (proc.ki_rusage_ch.ru_utime)),
 		 attrs);
-  EMACS_ADD_TIME (t,
-		  timeval_to_EMACS_TIME (proc.ki_rusage_ch.ru_utime),
-		  timeval_to_EMACS_TIME (proc.ki_rusage_ch.ru_stime));
+  t = add_emacs_time (timeval_to_EMACS_TIME (proc.ki_rusage_ch.ru_utime),
+		      timeval_to_EMACS_TIME (proc.ki_rusage_ch.ru_stime));
   attrs = Fcons (Fcons (Qctime, make_lisp_time (t)), attrs);
 
   attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (proc.ki_numthreads)),
@@ -3244,8 +3236,8 @@
   attrs = Fcons (Fcons (Qrss,   make_number (proc.ki_rssize * pagesize >> 10)),
 		 attrs);
 
-  EMACS_GET_TIME (now);
-  EMACS_SUB_TIME (t, now, timeval_to_EMACS_TIME (proc.ki_start));
+  now = current_emacs_time ();
+  t = sub_emacs_time (now, timeval_to_EMACS_TIME (proc.ki_start));
   attrs = Fcons (Fcons (Qetime, make_lisp_time (t)), attrs);
 
   len = sizeof fscale;

=== modified file 'src/systime.h'
--- src/systime.h	2012-07-07 01:57:42 +0000
+++ src/systime.h	2012-07-07 05:34:55 +0000
@@ -39,64 +39,91 @@
 #endif
 #endif
 
-#ifdef WINDOWSNT
 #include <sys/time.h>	/* for 'struct timeval' */
-#endif
 
-/* The type to use to represent temporal intervals.  It can be passed
+/* The type to use to represent temporal intervals.  Its address can be passed
    as the timeout argument to the pselect system call.  */
-#define EMACS_TIME struct timespec
+typedef struct timespec EMACS_TIME;
 
 /* Resolution of EMACS_TIME time stamps (in units per second), and log
    base 10 of the resolution.  The log must be a positive integer.  */
-#define EMACS_TIME_RESOLUTION		1000000000
-#define LOG10_EMACS_TIME_RESOLUTION	9
-
-/* EMACS_SECS (TIME) is an rvalue for the seconds component of TIME.
-   EMACS_SECS_ADDR (time) is the address of the seconds component.
-   EMACS_SET_SECS (TIME, SECONDS) sets that to SECONDS.
-
-   EMACS_NSECS (TIME) is an rvalue for the nanoseconds component of TIME.
-   EMACS_SET_NSECS (TIME, NANOSECONDS) sets that to NANOSECONDS.
-
-   EMACS_SET_SECS_NSECS (TIME, SECS, NSECS) sets both components of TIME.  */
-#define EMACS_SECS(time)		    ((time).tv_sec  + 0)
-#define EMACS_NSECS(time)		    ((time).tv_nsec + 0)
-#define EMACS_SECS_ADDR(time)		    (&(time).tv_sec)
-#define EMACS_SET_SECS(time, seconds)	    ((time).tv_sec  = (seconds))
-#define EMACS_SET_NSECS(time, ns)	    ((time).tv_nsec = (ns))
-#define EMACS_SET_SECS_NSECS(time, s, ns)				\
-  ((void) (EMACS_SET_SECS (time, s), EMACS_SET_NSECS (time, ns)))
-
-/* Convenience macros for older code that counts microseconds.  */
-#define EMACS_SET_USECS(time, us)  ((void) EMACS_SET_NSECS (time, (us) * 1000))
-#define EMACS_SET_SECS_USECS(time, secs, usecs) 		\
-  (EMACS_SET_SECS (time, secs), EMACS_SET_USECS (time, usecs))
-
-/* Set TIME to an invalid time stamp.  */
-#define EMACS_SET_INVALID_TIME(time)	    EMACS_SET_SECS_NSECS(time, 0, -1)
-
-/* Set TIME to the current system time.  */
-#define EMACS_GET_TIME(time)		    gettime (&(time))
-
-/* Put into DEST the result of adding SRC1 to SRC2, or of subtracting
-   SRC2 from SRC1.  On overflow, store an extremal value.  */
-#define EMACS_ADD_TIME(dest, src1, src2) ((dest) = timespec_add (src1, src2))
-#define EMACS_SUB_TIME(dest, src1, src2) ((dest) = timespec_sub (src1, src2))
+enum { EMACS_TIME_RESOLUTION = 1000000000 };
+enum { LOG10_EMACS_TIME_RESOLUTION = 9 };
+
+/* EMACS_SECS (TIME) is the seconds component of TIME.
+   EMACS_NSECS (TIME) is the nanoseconds component of TIME.
+   emacs_secs_addr (PTIME) is the address of *PTIME's seconds component.  */
+static inline time_t EMACS_SECS (EMACS_TIME t) { return t.tv_sec; }
+static inline int EMACS_NSECS (EMACS_TIME t) { return t.tv_nsec; }
+static inline time_t *emacs_secs_addr (EMACS_TIME *t) { return &t->tv_sec; }
+
+/* Return an Emacs time with seconds S and nanoseconds NS.  */
+static inline EMACS_TIME
+make_emacs_time (time_t s, int ns)
+{
+  EMACS_TIME r = { s, ns };
+  return r;
+}
+
+/* Return an invalid Emacs time.  */
+static inline EMACS_TIME
+invalid_emacs_time (void)
+{
+  EMACS_TIME r = { 0, -1 };
+  return r;
+}
+
+/* Return current system time.  */
+static inline EMACS_TIME
+current_emacs_time (void)
+{
+  EMACS_TIME r;
+  gettime (&r);
+  return r;
+}
+
+/* Return the result of adding A to B, or of subtracting B from A.
+   On overflow, return an extremal value.  */
+static inline EMACS_TIME
+add_emacs_time (EMACS_TIME a, EMACS_TIME b)
+{
+  return timespec_add (a, b);
+}
+static inline EMACS_TIME
+sub_emacs_time (EMACS_TIME a, EMACS_TIME b)
+{
+  return timespec_sub (a, b);
+}
 
 /* Return the sign of the valid time stamp TIME, either -1, 0, or 1.  */
-#define EMACS_TIME_SIGN(time)		timespec_sign (time)
+static inline int
+EMACS_TIME_SIGN (EMACS_TIME t)
+{
+  return timespec_sign (t);
+}
 
 /* Return 1 if TIME is a valid time stamp.  */
-#define EMACS_TIME_VALID_P(time)	(0 <= (time).tv_nsec)
+static inline int
+EMACS_TIME_VALID_P (EMACS_TIME t)
+{
+  return 0 <= t.tv_nsec;
+}
 
 /* Convert the double D to the greatest EMACS_TIME not greater than D.
    On overflow, return an extremal value.  Return the minimum
    EMACS_TIME if D is not a number.  */
-#define EMACS_TIME_FROM_DOUBLE(d)	dtotimespec (d)
+static inline EMACS_TIME
+EMACS_TIME_FROM_DOUBLE (double d)
+{
+  return dtotimespec (d);
+}
 
 /* Convert the Emacs time T to an approximate double value D.  */
-#define EMACS_TIME_TO_DOUBLE(t)		timespectod (t)
+static inline double
+EMACS_TIME_TO_DOUBLE (EMACS_TIME t)
+{
+  return timespectod (t);
+}
 
 /* defined in sysdep.c */
 extern int set_file_times (int, const char *, EMACS_TIME, EMACS_TIME);
@@ -117,12 +144,35 @@
 #endif
 
 /* Compare times T1 and T2 for equality, inequality etc.  */
-
-#define EMACS_TIME_EQ(T1, T2) (timespec_cmp (T1, T2) == 0)
-#define EMACS_TIME_NE(T1, T2) (timespec_cmp (T1, T2) != 0)
-#define EMACS_TIME_GT(T1, T2) (timespec_cmp (T1, T2) > 0)
-#define EMACS_TIME_GE(T1, T2) (timespec_cmp (T1, T2) >= 0)
-#define EMACS_TIME_LT(T1, T2) (timespec_cmp (T1, T2) < 0)
-#define EMACS_TIME_LE(T1, T2) (timespec_cmp (T1, T2) <= 0)
+static inline int
+EMACS_TIME_EQ (EMACS_TIME t1, EMACS_TIME t2)
+{
+  return timespec_cmp (t1, t2) == 0;
+}
+static inline int
+EMACS_TIME_NE (EMACS_TIME t1, EMACS_TIME t2)
+{
+  return timespec_cmp (t1, t2) != 0;
+}
+static inline int
+EMACS_TIME_GT (EMACS_TIME t1, EMACS_TIME t2)
+{
+  return timespec_cmp (t1, t2) > 0;
+}
+static inline int
+EMACS_TIME_GE (EMACS_TIME t1, EMACS_TIME t2)
+{
+  return timespec_cmp (t1, t2) >= 0;
+}
+static inline int
+EMACS_TIME_LT (EMACS_TIME t1, EMACS_TIME t2)
+{
+  return timespec_cmp (t1, t2) < 0;
+}
+static inline int
+EMACS_TIME_LE (EMACS_TIME t1, EMACS_TIME t2)
+{
+  return timespec_cmp (t1, t2) <= 0;
+}
 
 #endif /* EMACS_SYSTIME_H */

=== modified file 'src/undo.c'
--- src/undo.c	2012-07-07 01:57:42 +0000
+++ src/undo.c	2012-07-07 04:53:38 +0000
@@ -517,9 +517,9 @@
 		      && CONSP (XCDR (XCDR (XCDR (cdr))))
 		      && INTEGERP (XCAR (XCDR (XCDR (XCDR (cdr)))))
 		      && XINT (XCAR (XCDR (XCDR (XCDR (cdr))))) < 0)
-		    EMACS_SET_SECS_NSECS
-		      (mod_time, 0,
-		       XINT (XCAR (XCDR (XCDR (XCDR (cdr))))) / 1000);
+		    mod_time =
+		      (make_emacs_time
+		       (0, XINT (XCAR (XCDR (XCDR (XCDR (cdr))))) / 1000));
 		  else
 		    mod_time = lisp_time_argument (cdr);

=== modified file 'src/w32.c'
--- src/w32.c	2012-07-05 06:32:41 +0000
+++ src/w32.c	2012-07-07 04:53:38 +0000
@@ -1969,7 +1969,7 @@
      changed.  We could fix that by using GetSystemTime and
      GetTimeZoneInformation, but that doesn't seem necessary, since
      Emacs always calls gettimeofday with the 2nd argument NULL (see
-     EMACS_GET_TIME).  */
+     current_emacs_time).  */
   if (tz)
     {
       tz->tz_minuteswest = tb.timezone;	/* minutes west of Greenwich  */

=== modified file 'src/xdisp.c'
--- src/xdisp.c	2012-07-07 16:36:02 +0000
+++ src/xdisp.c	2012-07-07 20:04:02 +0000
@@ -29242,14 +29242,14 @@
 
   if (INTEGERP (Vhourglass_delay)
       && XINT (Vhourglass_delay) > 0)
-    EMACS_SET_SECS_NSECS (delay,
-			  min (XINT (Vhourglass_delay), TYPE_MAXIMUM (time_t)),
-			  0);
+    delay = make_emacs_time (min (XINT (Vhourglass_delay),
+				  TYPE_MAXIMUM (time_t)),
+			     0);
   else if (FLOATP (Vhourglass_delay)
 	   && XFLOAT_DATA (Vhourglass_delay) > 0)
     delay = EMACS_TIME_FROM_DOUBLE (XFLOAT_DATA (Vhourglass_delay));
   else
-    EMACS_SET_SECS_NSECS (delay, DEFAULT_HOURGLASS_DELAY, 0);
+    delay = make_emacs_time (DEFAULT_HOURGLASS_DELAY, 0);
 
   hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
 				   show_hourglass, NULL);

=== modified file 'src/xgselect.c'
--- src/xgselect.c	2012-07-05 18:35:48 +0000
+++ src/xgselect.c	2012-07-07 04:53:38 +0000
@@ -88,8 +88,8 @@
 
   if (tmo_in_millisec >= 0)
     {
-      EMACS_SET_SECS_USECS (tmo, tmo_in_millisec/1000,
-                            1000 * (tmo_in_millisec % 1000));
+      tmo = make_emacs_time (tmo_in_millisec / 1000,
+			     1000 * 1000 * (tmo_in_millisec % 1000));
       if (!timeout || EMACS_TIME_LT (tmo, *timeout))
 	tmop = &tmo;
     }

=== modified file 'src/xterm.c'
--- src/xterm.c	2012-07-05 18:35:48 +0000
+++ src/xterm.c	2012-07-07 04:53:38 +0000
@@ -3168,26 +3168,22 @@
       x_flush (f);
 
       {
-	EMACS_TIME wakeup, delay;
-
-	EMACS_GET_TIME (wakeup);
-	EMACS_SET_SECS_NSECS (delay, 0, 150 * 1000 * 1000);
-	EMACS_ADD_TIME (wakeup, wakeup, delay);
+	EMACS_TIME delay = make_emacs_time (0, 150 * 1000 * 1000);
+	EMACS_TIME wakeup = add_emacs_time (current_emacs_time (), delay);
 
 	/* Keep waiting until past the time wakeup or any input gets
 	   available.  */
 	while (! detect_input_pending ())
 	  {
-	    EMACS_TIME current, timeout;
-
-	    EMACS_GET_TIME (current);
+	    EMACS_TIME current = current_emacs_time ();
+	    EMACS_TIME timeout;
 
 	    /* Break if result would not be positive.  */
 	    if (EMACS_TIME_LE (wakeup, current))
 	      break;
 
 	    /* How long `select' should wait.  */
-	    EMACS_SET_SECS_NSECS (timeout, 0, 10 * 1000 * 1000);
+	    timeout = make_emacs_time (0, 10 * 1000 * 1000);
 
 	    /* Try to wait that long--but we might wake up sooner.  */
 	    pselect (0, NULL, NULL, NULL, &timeout, NULL);
@@ -8810,9 +8806,8 @@
 
   /* Set timeout to 0.1 second.  Hopefully not noticeable.
      Maybe it should be configurable.  */
-  EMACS_SET_SECS_USECS (tmo, 0, 100000);
-  EMACS_GET_TIME (tmo_at);
-  EMACS_ADD_TIME (tmo_at, tmo_at, tmo);
+  tmo = make_emacs_time (0, 100 * 1000 * 1000);
+  tmo_at = add_emacs_time (current_emacs_time (), tmo);
 
   while (pending_event_wait.eventtype)
     {
@@ -8825,11 +8820,11 @@
       FD_ZERO (&fds);
       FD_SET (fd, &fds);
 
-      EMACS_GET_TIME (time_now);
+      time_now = current_emacs_time ();
       if (EMACS_TIME_LT (tmo_at, time_now))
 	break;
 
-      EMACS_SUB_TIME (tmo, tmo_at, time_now);
+      tmo = sub_emacs_time (tmo_at, time_now);
       if (pselect (fd + 1, &fds, NULL, NULL, &tmo, NULL) == 0)
         break; /* Timeout */
     }
@@ -10602,9 +10597,7 @@
   BLOCK_INPUT;
   if (!x_timeout_atimer_activated_flag)
     {
-      EMACS_TIME interval;
-
-      EMACS_SET_SECS_USECS (interval, 0, 100000);
+      EMACS_TIME interval = make_emacs_time (0, 100 * 1000 * 1000);
       start_atimer (ATIMER_RELATIVE, interval, x_process_timeouts, 0);
       x_timeout_atimer_activated_flag = 1;
     }