diff options
Diffstat (limited to 'rts/posix/Itimer.c')
-rw-r--r-- | rts/posix/Itimer.c | 55 |
1 files changed, 50 insertions, 5 deletions
diff --git a/rts/posix/Itimer.c b/rts/posix/Itimer.c index b99ff8970b..4bcc3a1c2e 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; |