[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