[commit: ghc] ghc-8.0: Revert "rts/timer: use timerfd_* on Linux instead of alarm signals" (dcece19)
git at git.haskell.org
git at git.haskell.org
Thu Apr 21 15:22:31 UTC 2016
Repository : ssh://git@git.haskell.org/ghc
On branch : ghc-8.0
Link : http://ghc.haskell.org/trac/ghc/changeset/dcece1930d80f94e8fb3e56962c1d13055b30bd9/ghc
>---------------------------------------------------------------
commit dcece1930d80f94e8fb3e56962c1d13055b30bd9
Author: Ben Gamari <ben at smart-cactus.org>
Date: Thu Apr 21 13:30:45 2016 +0200
Revert "rts/timer: use timerfd_* on Linux instead of alarm signals"
This reverts commit bbdc52f3a6e6a28e209fb8f65699121d4ef3a4e3.
>---------------------------------------------------------------
dcece1930d80f94e8fb3e56962c1d13055b30bd9
configure.ac | 2 +-
rts/posix/Itimer.c | 91 +++++++-----------------------------------------------
2 files changed, 12 insertions(+), 81 deletions(-)
diff --git a/configure.ac b/configure.ac
index f7c2f33..271c216 100644
--- a/configure.ac
+++ b/configure.ac
@@ -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], [], [],
diff --git a/rts/posix/Itimer.c b/rts/posix/Itimer.c
index f6c00a6..57c7741 100644
--- a/rts/posix/Itimer.c
+++ b/rts/posix/Itimer.c
@@ -53,31 +53,6 @@
#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);
More information about the ghc-commits
mailing list