From ce71cb40f390139c4cc4882fb4768468608835d3 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 8 Aug 2006 19:18:50 +0000 Subject: [PATCH] avoid setitimer on OS X, because we can use a pthread instead svn: r3986 --- src/mzscheme/include/scheme.h | 2 +- src/mzscheme/sconfig.h | 9 ++++++ src/mzscheme/src/port.c | 61 +++++++++++++++++++++++++++++++++++ src/mzscheme/src/thread.c | 6 ++-- 4 files changed, 74 insertions(+), 4 deletions(-) diff --git a/src/mzscheme/include/scheme.h b/src/mzscheme/include/scheme.h index a7da81bd40..2ef9c93008 100644 --- a/src/mzscheme/include/scheme.h +++ b/src/mzscheme/include/scheme.h @@ -73,7 +73,7 @@ # undef USE_ITIMER #endif -#if defined(USE_ITIMER) || defined(USE_WIN32_THREAD_TIMER) +#if defined(USE_ITIMER) || defined(USE_WIN32_THREAD_TIMER) || defined(USE_PTHREAD_THREAD_TIMER) # define FUEL_AUTODECEREMENTS #endif diff --git a/src/mzscheme/sconfig.h b/src/mzscheme/sconfig.h index f112e8a1de..adee7737d3 100644 --- a/src/mzscheme/sconfig.h +++ b/src/mzscheme/sconfig.h @@ -631,6 +631,9 @@ # define SYSTEM_TYPE_NAME "macosx" #endif +# undef USE_ITIMER +# define USE_PTHREAD_THREAD_TIMER + # define USE_MAP_ANON # define USE_CARBON_FP_PREDS @@ -1044,6 +1047,12 @@ MzScheme-implemented threads). Define MZ_THREAD_QUANTUM_USEC to set the base time in usec allocated to each thread. */ + /* USE_WIN32_THREAD_TIMER uses a background Windows thread to implement + tread pre-emption. */ + + /* USE_PTHREAD_THREAD_TIMER uses a background pthread to implement + tread pre-emption. */ + /* SIGSET_IS_SIGNAL uses signal() in place of sigset() for Unix. This flag is often paired with SIGSET_NEEDS_REINSTALL for traditional Unix systems. */ diff --git a/src/mzscheme/src/port.c b/src/mzscheme/src/port.c index 72cc69e3df..da5dd9dff6 100644 --- a/src/mzscheme/src/port.c +++ b/src/mzscheme/src/port.c @@ -7949,6 +7949,67 @@ void scheme_start_itimer_thread(long usec) #endif +#ifdef USE_PTHREAD_THREAD_TIMER + +#include + +static int itimer = 0, itimer_continue = 0; +static pthread_mutex_t itimer_mutex; +static pthread_cond_t itimer_cond; +static volatile long itimer_delay; + +#ifdef MZ_XFORM +START_XFORM_SKIP; +#endif +static void *run_itimer(void *p) +{ + while (1) { + usleep(itimer_delay); + scheme_fuel_counter = 0; + + pthread_mutex_lock(&itimer_mutex); + if (itimer_continue) { + itimer_continue = 0; + } else { + itimer_continue = -1; + pthread_cond_wait(&itimer_cond, &itimer_mutex); + } + pthread_mutex_unlock(&itimer_mutex); + } +} +#ifdef MZ_XFORM +END_XFORM_SKIP; +#endif + +void scheme_start_itimer_thread(long usec) +{ + itimer_delay = usec; + + if (!itimer) { + pthread_t t; + pthread_mutex_init(&itimer_mutex, NULL); + pthread_cond_init(&itimer_cond, NULL); + pthread_create(&t, NULL, run_itimer, NULL); + itimer = 1; + } else { + pthread_mutex_lock(&itimer_mutex); + if (!itimer_continue) { + /* itimer thread is currently running working */ + itimer_continue = 1; + } else if (itimer_continue < 0) { + /* itimer thread is waiting on cond */ + itimer_continue = 0; + pthread_cond_signal(&itimer_cond); + } else { + /* itimer thread is working, and we've already + asked it to continue */ + } + pthread_mutex_unlock(&itimer_mutex); + } +} + +#endif + /*========================================================================*/ /* memory debugging help */ /*========================================================================*/ diff --git a/src/mzscheme/src/thread.c b/src/mzscheme/src/thread.c index 3339c60336..044cc704be 100644 --- a/src/mzscheme/src/thread.c +++ b/src/mzscheme/src/thread.c @@ -3722,6 +3722,8 @@ void scheme_thread_block(float sleep_time) if (do_atomic) missed_context_switch = 1; + MZTHREADELEM(p, fuel_counter) = p->engine_weight; + #ifdef USE_ITIMER { struct itimerval t, old; @@ -3739,14 +3741,12 @@ void scheme_thread_block(float sleep_time) setitimer(ITIMER_PROF, &t, &old); } #endif -#ifdef USE_WIN32_THREAD_TIMER +#if defined(USE_WIN32_THREAD_TIMER) || defined(USE_PTHREAD_THREAD_TIMER) scheme_start_itimer_thread(MZ_THREAD_QUANTUM_USEC); #endif /* Check scheduled_kills early and often. */ check_scheduled_kills(); - - MZTHREADELEM(p, fuel_counter) = p->engine_weight; } void scheme_making_progress()