Commit e7817396 authored by ian@well-typed.com's avatar ian@well-typed.com
Browse files

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.
parent be66c4ef
......@@ -44,6 +44,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;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment