Revert "rts/timer: use timerfd_* on Linux instead of alarm signals"
authorBen Gamari <ben@smart-cactus.org>
Thu, 21 Apr 2016 11:30:45 +0000 (13:30 +0200)
committerBen Gamari <ben@smart-cactus.org>
Thu, 21 Apr 2016 11:30:45 +0000 (13:30 +0200)
This reverts commit bbdc52f3a6e6a28e209fb8f65699121d4ef3a4e3.

configure.ac
rts/posix/Itimer.c

index f7c2f33..271c216 100644 (file)
@@ -776,7 +776,7 @@ dnl    off_t, because it will affect the result of that test.
 AC_SYS_LARGEFILE
 
 dnl ** check for specific header (.h) files that we are interested in
-AC_CHECK_HEADERS([ctype.h dirent.h dlfcn.h errno.h fcntl.h grp.h limits.h locale.h nlist.h pthread.h pwd.h signal.h sys/param.h sys/mman.h sys/resource.h sys/select.h sys/time.h sys/timeb.h sys/timerfd.h sys/timers.h sys/times.h sys/utsname.h sys/wait.h termios.h time.h utime.h windows.h winsock.h sched.h])
+AC_CHECK_HEADERS([ctype.h dirent.h dlfcn.h errno.h fcntl.h grp.h limits.h locale.h nlist.h pthread.h pwd.h signal.h sys/param.h sys/mman.h sys/resource.h sys/select.h sys/time.h sys/timeb.h sys/timers.h sys/times.h sys/utsname.h sys/wait.h termios.h time.h utime.h windows.h winsock.h sched.h])
 
 dnl sys/cpuset.h needs sys/param.h to be included first on FreeBSD 9.1; #7708
 AC_CHECK_HEADERS([sys/cpuset.h], [], [],
index f6c00a6..57c7741 100644 (file)
 #define USE_PTHREAD_FOR_ITIMER
 #endif
 
-/*
- * On Linux in the threaded RTS we can use timerfd_* (introduced in Linux
- * 2.6.25) and a thread instead of alarm signals. It avoids the risk of
- * interrupting syscalls (see #10840) and the risk of being accidentally
- * modified in user code using signals.
- */
-#if defined(linux_HOST_OS) && defined(THREADED_RTS) && HAVE_SYS_TIMERFD_H
-#include <sys/timerfd.h>
-#include <fcntl.h>
-#define USE_PTHREAD_FOR_ITIMER
-#define USE_TIMERFD_FOR_ITIMER 1
-#undef USE_TIMER_CREATE
-#else
-#define USE_TIMERFD_FOR_ITIMER 0
-#endif
-
-/*
- * TFD_CLOEXEC has been added in Linux 2.6.26.
- * If it is not available, we use fcntl(F_SETFD).
- */
-#ifndef TFD_CLOEXEC
-#define TFD_CLOEXEC 0
-#endif
-
-
 #if defined(USE_PTHREAD_FOR_ITIMER)
 #include <pthread.h>
 #include <unistd.h>
@@ -175,50 +150,15 @@ static void install_vtalrm_handler(TickProc handle_tick)
 #endif
 
 #if defined(USE_PTHREAD_FOR_ITIMER)
-enum ItimerState {STOPPED, RUNNING, STOPPING, EXITED};
-static volatile enum ItimerState itimer_state = STOPPED;
+static volatile int itimer_enabled;
 static void *itimer_thread_func(void *_handle_tick)
 {
     TickProc handle_tick = _handle_tick;
-    uint64_t nticks;
-    int timerfd = -1;
-
-#if USE_TIMERFD_FOR_ITIMER
-    struct itimerspec it;
-    it.it_value.tv_sec  = TimeToSeconds(itimer_interval);
-    it.it_value.tv_nsec = TimeToNS(itimer_interval) % 1000000000;
-    it.it_interval = it.it_value;
-
-    timerfd = timerfd_create(CLOCK_MONOTONIC,TFD_CLOEXEC);
-    if (timerfd == -1) {
-        sysErrorBelch("timerfd_create");
-        stg_exit(EXIT_FAILURE);
-    }
-    if (!TFD_CLOEXEC) {
-      fcntl(timerfd, F_SETFD, FD_CLOEXEC);
-    }
-    timerfd_settime(timerfd,0,&it,NULL);
-#endif
-
     while (1) {
-        if (USE_TIMERFD_FOR_ITIMER) {
-            read(timerfd, &nticks, sizeof(nticks));
-        } else {
-            usleep(TimeToUS(itimer_interval));
-        }
-        switch (itimer_state) {
-            case RUNNING:
-                handle_tick(0);
-                break;
-            case STOPPED:
-                break;
-            case STOPPING:
-                itimer_state = STOPPED;
-                break;
-            case EXITED:
-                if (USE_TIMERFD_FOR_ITIMER)
-                    close(timerfd);
-                return NULL;
+        usleep(TimeToUS(itimer_interval));
+        switch (itimer_enabled) {
+            case 1: handle_tick(0); break;
+            case 2: itimer_enabled = 0;
         }
     }
     return NULL;
@@ -232,13 +172,7 @@ initTicker (Time interval, TickProc handle_tick)
 
 #if defined(USE_PTHREAD_FOR_ITIMER)
     pthread_t tid;
-    int r = pthread_create(&tid, NULL, itimer_thread_func, (void*)handle_tick);
-    if (!r) {
-        pthread_detach(tid);
-#if HAVE_PTHREAD_SETNAME_NP
-        pthread_setname_np(tid, "ghc_ticker");
-#endif
-    }
+    pthread_create(&tid, NULL, itimer_thread_func, (void*)handle_tick);
 #elif defined(USE_TIMER_CREATE)
     {
         struct sigevent ev;
@@ -264,7 +198,7 @@ void
 startTicker(void)
 {
 #if defined(USE_PTHREAD_FOR_ITIMER)
-    itimer_state = RUNNING;
+    itimer_enabled = 1;
 #elif defined(USE_TIMER_CREATE)
     {
         struct itimerspec it;
@@ -298,11 +232,10 @@ void
 stopTicker(void)
 {
 #if defined(USE_PTHREAD_FOR_ITIMER)
-    if (itimer_state == RUNNING) {
-        itimer_state = STOPPING;
+    if (itimer_enabled == 1) {
+        itimer_enabled = 2;
         /* Wait for the thread to confirm it won't generate another tick. */
-        write_barrier();
-        while (itimer_state != STOPPED)
+        while (itimer_enabled != 0)
             sched_yield();
     }
 #elif defined(USE_TIMER_CREATE)
@@ -333,9 +266,7 @@ stopTicker(void)
 void
 exitTicker (rtsBool wait STG_UNUSED)
 {
-#if defined(USE_PTHREAD_FOR_ITIMER)
-    itimer_state = EXITED;
-#elif defined(USE_TIMER_CREATE)
+#if defined(USE_TIMER_CREATE)
     // Before deleting the timer set the signal to ignore to avoid the
     // possibility of the signal being delivered after the timer is deleted.
     signal(ITIMER_SIGNAL, SIG_IGN);