emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] trunk r117616: Simplify timerfd configuration and fix some


From: Paul Eggert
Subject: [Emacs-diffs] trunk r117616: Simplify timerfd configuration and fix some minor glitches.
Date: Thu, 31 Jul 2014 20:17:05 +0000
User-agent: Bazaar (2.6b2)

------------------------------------------------------------
revno: 117616
revision-id: address@hidden
parent: address@hidden
committer: Paul Eggert <address@hidden>
branch nick: trunk
timestamp: Thu 2014-07-31 13:17:01 -0700
message:
  Simplify timerfd configuration and fix some minor glitches.
  
  * configure.ac (HAVE_TIMERFD): Define only if TFD_CLOEXEC works,
  since the code leaked file descriptors to children when !TFD_CLOEXEC.
  (HAVE_TIMERFD_CLOEXEC): Remove; no longer used.
  * m4/clock_time.m4 (gl_CLOCK_TIME): Don't check for clock_getres.
  This reverts the previous change to this file, so it matches
  gnulib again.
  * src/atimer.c (TIMERFD_CREATE_FLAGS): Remove; we now assume TFD_CLOEXEC.
  (alarm_timer, alarm_timer_ok, set_alarm, init_atimer):
  Fall back on timer_create if timerfd_create fails at runtime.
  (resolution) [HAVE_CLOCK_GETRES]: Remove; we now rely on the
  kernel primitives to do resolution.  All uses removed.
  (timerfd) [!HAVE_TIMERFD]: Define to be -1, for convenience.
  (turn_on_atimers): Clear timer_create-based timers too,
  for consistency.
modified:
  ChangeLog                      changelog-20091113204419-o5vbwnq5f7feedwu-1538
  configure.ac                   
configure.in-20091113204419-o5vbwnq5f7feedwu-783
  m4/clock_time.m4               
clock_time.m4-20120622212453-poe1wduuhk4mz8vy-13
  src/ChangeLog                  changelog-20091113204419-o5vbwnq5f7feedwu-1438
  src/atimer.c                   atimer.c-20091113204419-o5vbwnq5f7feedwu-1759
=== modified file 'ChangeLog'
--- a/ChangeLog 2014-07-28 06:28:15 +0000
+++ b/ChangeLog 2014-07-31 20:17:01 +0000
@@ -1,3 +1,13 @@
+2014-07-31  Paul Eggert  <address@hidden>
+
+       Simplify timerfd configuration and fix some minor glitches.
+       * configure.ac (HAVE_TIMERFD): Define only if TFD_CLOEXEC works,
+       since the code leaked file descriptors to children when !TFD_CLOEXEC.
+       (HAVE_TIMERFD_CLOEXEC): Remove; no longer used.
+       * m4/clock_time.m4 (gl_CLOCK_TIME): Don't check for clock_getres.
+       This reverts the previous change to this file, so it matches
+       gnulib again.
+
 2014-07-28  Dmitry Antipov  <address@hidden>
 
        * configure.ac (toplevel): Check whether GNU/Linux-specific

=== modified file 'configure.ac'
--- a/configure.ac      2014-07-28 06:28:15 +0000
+++ b/configure.ac      2014-07-31 20:17:01 +0000
@@ -1539,7 +1539,7 @@
       AC_DEFINE(LINUX_SYSINFO_UNIT, 1,
                 [Define to 1 if Linux sysinfo sizes are in multiples of 
mem_unit bytes.]))
   fi
-fi  
+fi
 
 dnl On Solaris 8 there's a compilation warning for term.h because
 dnl it doesn't define `bool'.
@@ -3711,25 +3711,18 @@
 AC_SUBST(TERMCAP_OBJ)
 
 # GNU/Linux-specific timer functions.
-if test $opsys = gnu-linux; then
-  AC_MSG_CHECKING([whether Linux timerfd functions are supported])
-  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/timerfd.h>]],
-                                    [[timerfd_create (CLOCK_REALTIME, 0);
-                                      timerfd_settime (0, 0, NULL, NULL)]])],
-  emacs_cv_linux_timerfd=yes, emacs_cv_linux_timerfd=no)
-  AC_MSG_RESULT([$emacs_cv_linux_timerfd])
-  if test $emacs_cv_linux_timerfd = yes; then
-    AC_DEFINE(HAVE_TIMERFD, 1, [Define to 1 if Linux timerfd functions are 
supported.])
-    AC_MSG_CHECKING([whether TFD_CLOEXEC is defined])
-      AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/timerfd.h>]],
-                                        [[timerfd_create (CLOCK_REALTIME, 
TFD_CLOEXEC)]])],
-    emacs_cv_tfd_cloexec=yes, emacs_cv_tfd_cloexec=no)
-    AC_MSG_RESULT([$emacs_cv_tfd_cloexec])
-    if test $emacs_cv_tfd_cloexec = yes; then
-      AC_DEFINE(HAVE_TIMERFD_CLOEXEC, 1, [Define to 1 if TFD_CLOEXEC is 
defined.])
-    fi
-  fi
-fi  
+AC_CACHE_CHECK([for timerfd interface], [emacs_cv_have_timerfd],
+  [AC_COMPILE_IFELSE(
+     [AC_LANG_PROGRAM([[#include <sys/timerfd.h>
+                     ]],
+                     [[timerfd_create (CLOCK_REALTIME, TFD_CLOEXEC);
+                       timerfd_settime (0, TFD_TIMER_ABSTIME, 0, 0);]])],
+     [emacs_cv_have_timerfd=yes],
+     [emacs_cv_have_timerfd=no])])
+if test "$emacs_cv_have_timerfd" = yes; then
+  AC_DEFINE([HAVE_TIMERFD], 1,
+    [Define to 1 if timerfd functions are supported as in GNU/Linux.])
+fi
 
 # Do we have res_init, for detecting changes in /etc/resolv.conf?
 # On Darwin, res_init appears not to be useful: see bug#562 and

=== modified file 'm4/clock_time.m4'
--- a/m4/clock_time.m4  2014-07-28 06:28:15 +0000
+++ b/m4/clock_time.m4  2014-07-31 20:17:01 +0000
@@ -26,6 +26,6 @@
     AC_SEARCH_LIBS([clock_gettime], [rt posix4],
                    [test "$ac_cv_search_clock_gettime" = "none required" ||
                     LIB_CLOCK_GETTIME=$ac_cv_search_clock_gettime])
-    AC_CHECK_FUNCS([clock_getres clock_gettime clock_settime])
+    AC_CHECK_FUNCS([clock_gettime clock_settime])
   LIBS=$gl_saved_libs
 ])

=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2014-07-31 13:55:12 +0000
+++ b/src/ChangeLog     2014-07-31 20:17:01 +0000
@@ -1,5 +1,15 @@
 2014-07-31  Paul Eggert  <address@hidden>
 
+       Simplify timerfd configuration and fix some minor glitches.
+       * atimer.c (TIMERFD_CREATE_FLAGS): Remove; we now assume TFD_CLOEXEC.
+       (alarm_timer, alarm_timer_ok, set_alarm, init_atimer):
+       Fall back on timer_create if timerfd_create fails at runtime.
+       (resolution) [HAVE_CLOCK_GETRES]: Remove; we now rely on the
+       kernel primitives to do resolution.  All uses removed.
+       (timerfd) [!HAVE_TIMERFD]: Define to be -1, for convenience.
+       (turn_on_atimers): Clear timer_create-based timers too,
+       for consistency.
+
        * frame.c (x_set_frame_parameters): Don't use uninitialized locals.
        Without this change, the code can access the local variable 'width'
        even when it has not been initialized, and likewise for 'height';

=== modified file 'src/atimer.c'
--- a/src/atimer.c      2014-07-28 14:50:55 +0000
+++ b/src/atimer.c      2014-07-31 20:17:01 +0000
@@ -27,13 +27,8 @@
 #include <unistd.h>
 
 #ifdef HAVE_TIMERFD
-#include <sys/timerfd.h>
-#ifdef HAVE_TIMERFD_CLOEXEC
-#define TIMERFD_CREATE_FLAGS TFD_CLOEXEC
-#else
-#define TIMERFD_CREATE_FLAGS 0
-#endif /* HAVE_TIMERFD_CLOEXEC */
-#endif /* HAVE_TIMERFD */
+# include <sys/timerfd.h>
+#endif
 
 /* Free-list of atimer structures.  */
 
@@ -49,23 +44,18 @@
 
 static struct atimer *atimers;
 
-#if defined (HAVE_TIMERFD)
-/* File descriptor returned by timerfd_create.  GNU/Linux-specific.  */
+#ifdef HAVE_ITIMERSPEC
+/* The alarm timer and whether it was properly initialized, if
+   POSIX timers are available.  */
+static timer_t alarm_timer;
+static bool alarm_timer_ok;
+
+# ifdef HAVE_TIMERFD
+/* File descriptor for timer, or -1 if it could not be created.  */
 static int timerfd;
-#elif defined (HAVE_ITIMERSPEC)
-/* The alarm timer used if POSIX timers are available.  */
-static timer_t alarm_timer;
-#endif
-
-#if defined (HAVE_TIMERFD) || defined (HAVE_ITIMERSPEC)
-/* Non-zero if one of the above was successfully initialized.  Do not
-   use bool due to special treatment if HAVE_TIMERFD, see below.  */
-static int special_timer_available;
-#endif
-
-#ifdef HAVE_CLOCK_GETRES
-/* Resolution of CLOCK_REALTIME clock.  */
-static struct timespec resolution;
+# else
+enum { timerfd = -1 };
+# endif
 #endif
 
 /* Block/unblock SIGALRM.  */
@@ -92,20 +82,20 @@
 static struct atimer *append_atimer_lists (struct atimer *,
                                            struct atimer *);
 
-/* Start a new atimer of type TYPE.  TIME specifies when the timer is
+/* Start a new atimer of type TYPE.  TIMESTAMP specifies when the timer is
    ripe.  FN is the function to call when the timer fires.
    CLIENT_DATA is stored in the client_data member of the atimer
    structure returned and so made available to FN when it is called.
 
-   If TYPE is ATIMER_ABSOLUTE, TIME is the absolute time at which the
+   If TYPE is ATIMER_ABSOLUTE, TIMESTAMP is the absolute time at which the
    timer fires.
 
-   If TYPE is ATIMER_RELATIVE, the timer is ripe TIME s/us in the
+   If TYPE is ATIMER_RELATIVE, the timer is ripe TIMESTAMP seconds in the
    future.
 
    In both cases, the timer is automatically freed after it has fired.
 
-   If TYPE is ATIMER_CONTINUOUS, the timer fires every TIME s/us.
+   If TYPE is ATIMER_CONTINUOUS, the timer fires every TIMESTAMP seconds.
 
    Value is a pointer to the atimer started.  It can be used in calls
    to cancel_atimer; don't free it yourself.  */
@@ -117,16 +107,10 @@
   struct atimer *t;
   sigset_t oldset;
 
-#if !defined (HAVE_SETITIMER)
-  /* Round TIME up to the next full second if we don't have itimers.  */
+  /* Round TIMESTAMP up to the next full second if we don't have itimers.  */
+#ifndef HAVE_SETITIMER
   if (timestamp.tv_nsec != 0 && timestamp.tv_sec < TYPE_MAXIMUM (time_t))
     timestamp = make_timespec (timestamp.tv_sec + 1, 0);
-#elif defined (HAVE_CLOCK_GETRES)
-  /* Check that the system clock is precise enough.  If
-     not, round TIME up to the system clock resolution.  */
-  if (timespec_valid_p (resolution)
-      && timespec_cmp (timestamp, resolution) < 0)
-    timestamp = resolution;
 #endif /* not HAVE_SETITIMER */
 
   /* Get an atimer structure from the free-list, or allocate
@@ -311,25 +295,24 @@
 #endif
       struct timespec now, interval;
 
-#if defined (HAVE_TIMERFD) || defined (HAVE_ITIMERSPEC)
-      if (special_timer_available)
+#ifdef HAVE_ITIMERSPEC
+      if (0 <= timerfd || alarm_timer_ok)
        {
          struct itimerspec ispec;
          ispec.it_value = atimers->expiration;
          ispec.it_interval.tv_sec = ispec.it_interval.tv_nsec = 0;
-#if defined (HAVE_TIMERFD)
-         if (special_timer_available == 1)
+# ifdef HAVE_TIMERFD
+         if (timerfd_settime (timerfd, TFD_TIMER_ABSTIME, &ispec, 0) == 0)
            {
              add_timer_wait_descriptor (timerfd);
-             special_timer_available++;
+             return;
            }
-         if (timerfd_settime (timerfd, TFD_TIMER_ABSTIME, &ispec, 0) == 0)
-#elif defined (HAVE_ITIMERSPEC)
-         if (timer_settime (alarm_timer, TIMER_ABSTIME, &ispec, 0) == 0)
-#endif     
+# endif
+         if (alarm_timer_ok
+             && timer_settime (alarm_timer, TIMER_ABSTIME, &ispec, 0) == 0)
            return;
        }
-#endif /* HAVE_TIMERFD || HAVE_ITIMERSPEC */
+#endif
 
       /* Determine interval till the next timer is ripe.
         Don't set the interval to 0; this disables the timer.  */
@@ -453,15 +436,15 @@
     set_alarm ();
   else
     {
-#ifdef HAVE_TIMERFD
-      if (special_timer_available > 1)
-       {
-         struct itimerspec ispec;
-         memset (&ispec, 0, sizeof (ispec));
-         /* Writing zero expiration time should disarm it.  */
-         timerfd_settime (timerfd, TFD_TIMER_ABSTIME, &ispec, 0);
-       }
-#endif /* HAVE_TIMERFD */
+#ifdef HAVE_ITIMERSPEC
+      struct itimerspec ispec;
+      memset (&ispec, 0, sizeof ispec);
+      if (alarm_timer_ok)
+       timer_settime (alarm_timer, TIMER_ABSTIME, &ispec, 0);
+# ifdef HAVE_TIMERFD
+      timerfd_settime (timerfd, TFD_TIMER_ABSTIME, &ispec, 0);
+# endif
+#endif
       alarm (0);
     }
 }
@@ -494,14 +477,14 @@
     r->intime = 0;
   else if (result >= 0)
     {
-#ifdef HAVE_SETITIMER      
+#ifdef HAVE_SETITIMER
       struct timespec delta = timespec_sub (now, r->expected);
       /* Too late if later than expected + 0.01s.  FIXME:
         this should depend from system clock resolution.  */
       if (timespec_cmp (delta, make_timespec (0, 10000000)) > 0)
        r->intime = 0;
       else
-#endif /* HAVE_SETITIMER */    
+#endif /* HAVE_SETITIMER */
        r->intime = 1;
     }
 }
@@ -543,21 +526,20 @@
 void
 init_atimer (void)
 {
-#if defined (HAVE_TIMERFD)
-  timerfd = timerfd_create (CLOCK_REALTIME, TIMERFD_CREATE_FLAGS);
-  special_timer_available = !!(timerfd != -1);
-#elif defined (HAVE_ITIMERSPEC)
-  struct sigevent sigev;
-  sigev.sigev_notify = SIGEV_SIGNAL;
-  sigev.sigev_signo = SIGALRM;
-  sigev.sigev_value.sival_ptr = &alarm_timer;
-  special_timer_available
-    = timer_create (CLOCK_REALTIME, &sigev, &alarm_timer) == 0;
-#endif /* HAVE_TIMERFD */
-#ifdef HAVE_CLOCK_GETRES
-  if (clock_getres (CLOCK_REALTIME, &resolution))
-    resolution = invalid_timespec ();
-#endif  
+#ifdef HAVE_ITIMERSPEC
+# ifdef HAVE_TIMERFD
+  timerfd = timerfd_create (CLOCK_REALTIME, TFD_CLOEXEC);
+# endif
+  if (timerfd < 0)
+    {
+      struct sigevent sigev;
+      sigev.sigev_notify = SIGEV_SIGNAL;
+      sigev.sigev_signo = SIGALRM;
+      sigev.sigev_value.sival_ptr = &alarm_timer;
+      alarm_timer_ok
+       = timer_create (CLOCK_REALTIME, &sigev, &alarm_timer) == 0;
+    }
+#endif
   free_atimers = stopped_atimers = atimers = NULL;
 
   /* pending_signals is initialized in init_keyboard.  */
@@ -567,5 +549,5 @@
 
 #ifdef ENABLE_CHECKING
   defsubr (&Sdebug_timer_check);
-#endif  
+#endif
 }


reply via email to

[Prev in Thread] Current Thread [Next in Thread]