[commit: ghc] master: Use a pthread-based implementation of Itimer.c on iOS (e781739)

Ian Lynagh igloo at earth.li
Sun Apr 21 21:59:31 CEST 2013


Repository : http://darcs.haskell.org/ghc.git/

On branch  : master

https://github.com/ghc/ghc/commit/e7817396e8ec5c45689b1c7d6fa852623bb12b33

>---------------------------------------------------------------

commit e7817396e8ec5c45689b1c7d6fa852623bb12b33
Author: Ian Lynagh <ian at well-typed.com>
Date:   Sun Apr 21 17:54:57 2013 +0100

    Use a pthread-based implementation of Itimer.c on iOS
    
    Patch from Stephen Blackheath.
    
    timer_create doesn't exist and setitimer doesn't fire on iOS, so we're
    using a pthreads-based implementation. It may be to do with
    interference with the signals of the debugger. Revisit. See #7723.

>---------------------------------------------------------------

 rts/posix/Itimer.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 50 insertions(+), 5 deletions(-)

diff --git a/rts/posix/Itimer.c b/rts/posix/Itimer.c
index b99ff89..4bcc3a1 100644
--- a/rts/posix/Itimer.c
+++ b/rts/posix/Itimer.c
@@ -45,6 +45,20 @@
 #include <string.h>
 
 /*
+ * timer_create doesn't exist and setitimer doesn't fire on iOS, so we're using
+ * a pthreads-based implementation. It may be to do with interference with the
+ * signals of the debugger. Revisit. See #7723.
+ */
+#if defined(ios_HOST_OS)
+#define USE_PTHREAD_FOR_ITIMER
+#endif
+
+#if defined(USE_PTHREAD_FOR_ITIMER)
+#include <pthread.h>
+#include <unistd.h>
+#endif
+
+/*
  * We use a realtime timer by default.  I found this much more
  * reliable than a CPU timer:
  *
@@ -107,6 +121,7 @@ static timer_t timer;
 
 static Time itimer_interval = DEFAULT_TICK_INTERVAL;
 
+#if !defined(USE_PTHREAD_FOR_ITIMER)
 static void install_vtalrm_handler(TickProc handle_tick)
 {
     struct sigaction action;
@@ -132,13 +147,33 @@ static void install_vtalrm_handler(TickProc handle_tick)
         stg_exit(EXIT_FAILURE);
     }
 }
+#endif
+
+#if defined(USE_PTHREAD_FOR_ITIMER)
+static volatile int itimer_enabled;
+static void *itimer_thread_func(void *_handle_tick)
+{
+    TickProc handle_tick = _handle_tick;
+    while (1) {
+        usleep(TimeToUS(itimer_interval));
+        switch (itimer_enabled) {
+            case 1: handle_tick(0); break;
+            case 2: itimer_enabled = 0;
+        }
+    }
+    return NULL;
+}
+#endif
 
 void
 initTicker (Time interval, TickProc handle_tick)
 {
     itimer_interval = interval;
 
-#if defined(USE_TIMER_CREATE)
+#if defined(USE_PTHREAD_FOR_ITIMER)
+    pthread_t tid;
+    pthread_create(&tid, NULL, itimer_thread_func, (void*)handle_tick);
+#elif defined(USE_TIMER_CREATE)
     {
         struct sigevent ev;
 
@@ -153,15 +188,18 @@ initTicker (Time interval, TickProc handle_tick)
             stg_exit(EXIT_FAILURE);
         }
     }
-#endif
-
     install_vtalrm_handler(handle_tick);
+#else
+    install_vtalrm_handler(handle_tick);
+#endif
 }
 
 void
 startTicker(void)
 {
-#if defined(USE_TIMER_CREATE)
+#if defined(USE_PTHREAD_FOR_ITIMER)
+    itimer_enabled = 1;
+#elif defined(USE_TIMER_CREATE)
     {
         struct itimerspec it;
         
@@ -193,7 +231,14 @@ startTicker(void)
 void
 stopTicker(void)
 {
-#if defined(USE_TIMER_CREATE)
+#if defined(USE_PTHREAD_FOR_ITIMER)
+    if (itimer_enabled == 1) {
+        itimer_enabled = 2;
+        /* Wait for the thread to confirm it won't generate another tick. */
+        while (itimer_enabled != 0)
+            sched_yield();
+    }
+#elif defined(USE_TIMER_CREATE)
     struct itimerspec it;
 
     it.it_value.tv_sec = 0;





More information about the ghc-commits mailing list