X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=rts%2Fposix%2FItimer.c;h=a60f8f129546421e6e475e12256a69f2d596a4dc;hb=f5e36de375d03a0af3858c4222690bbaa5f8a1ee;hp=8600c0a99cd31061c3db4ab5a66e6d284189120c;hpb=e30aca19def5c629a8429bd57e56535b7f8f85c8;p=ghc-hetmet.git diff --git a/rts/posix/Itimer.c b/rts/posix/Itimer.c index 8600c0a..a60f8f1 100644 --- a/rts/posix/Itimer.c +++ b/rts/posix/Itimer.c @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------------- * - * (c) The GHC Team, 1995-1999 + * (c) The GHC Team, 1995-2007 * * Interval timer for profiling and pre-emptive scheduling. * @@ -42,6 +42,8 @@ # include #endif +#include + /* Major bogosity: * * In the threaded RTS, we can't set the virtual timer because the @@ -67,9 +69,8 @@ * For now, we're using (1), but this needs a better solution. --SDM */ -#if defined(HAVE_TIMER_CREATE) && defined(HAVE_TIMER_SETTIME) +#if defined(USE_TIMER_CREATE) -# define USE_TIMER_CREATE # define ITIMER_SIGNAL SIGVTALRM # ifdef THREADED_RTS # define TIMER_FLAVOUR CLOCK_REALTIME @@ -79,7 +80,6 @@ #elif defined(HAVE_SETITIMER) -# define USE_ITIMER # ifdef THREADED_RTS // Oh dear, we have to use SIGALRM if there's no timer_create and // we're using the THREADED_RTS. This leads to problems, see bug #850. @@ -97,9 +97,11 @@ #endif #if defined(USE_TIMER_CREATE) -timer_t timer; +static timer_t timer; #endif +static nat itimer_interval = 50; + static void install_vtalrm_handler(TickProc handle_tick) @@ -129,7 +131,7 @@ install_vtalrm_handler(TickProc handle_tick) } void -startTicker(nat ms, TickProc handle_tick) +initTicker (nat ms, TickProc handle_tick) { install_vtalrm_handler(handle_tick); @@ -137,23 +139,37 @@ startTicker(nat ms, TickProc handle_tick) timestamp = getourtimeofday(); #endif + itimer_interval = ms; + #if defined(USE_TIMER_CREATE) { - struct itimerspec it; struct sigevent ev; + // Keep programs like valgrind happy + memset(&ev, 0, sizeof(ev)); + ev.sigev_notify = SIGEV_SIGNAL; ev.sigev_signo = ITIMER_SIGNAL; - - it.it_value.tv_sec = ms / 1000; - it.it_value.tv_nsec = (ms % 1000) * 1000000; - it.it_interval = it.it_value; - + if (timer_create(TIMER_FLAVOUR, &ev, &timer) != 0) { sysErrorBelch("timer_create"); stg_exit(EXIT_FAILURE); } + } +#endif +} +void +startTicker(void) +{ +#if defined(USE_TIMER_CREATE) + { + struct itimerspec it; + + it.it_value.tv_sec = itimer_interval / 1000; + it.it_value.tv_nsec = (itimer_interval % 1000) * 1000000; + it.it_interval = it.it_value; + if (timer_settime(timer, 0, &it, NULL) != 0) { sysErrorBelch("timer_settime"); stg_exit(EXIT_FAILURE); @@ -163,8 +179,8 @@ startTicker(nat ms, TickProc handle_tick) { struct itimerval it; - it.it_value.tv_sec = ms / 1000; - it.it_value.tv_usec = (ms % 1000) * 1000; + it.it_value.tv_sec = itimer_interval / 1000; + it.it_value.tv_usec = (itimer_interval % 1000) * 1000; it.it_interval = it.it_value; if (setitimer(ITIMER_FLAVOUR, &it, NULL) != 0) { @@ -203,6 +219,15 @@ stopTicker(void) #endif } +void +exitTicker(void) +{ +#if defined(USE_TIMER_CREATE) + timer_delete(timer); + // ignore errors - we don't really care if it fails. +#endif +} + #if 0 /* Currently unused */ void @@ -235,8 +260,11 @@ lnat getourtimeofday(void) { struct timeval tv; + nat interval; + interval = RtsFlags.MiscFlags.tickInterval; + if (interval == 0) { interval = 50; } gettimeofday(&tv, (struct timezone *) NULL); // cast to lnat because nat may be 64 bit when int is only 32 bit - return ((lnat)tv.tv_sec * 1000 / RtsFlags.MiscFlags.tickInterval + - (lnat)tv.tv_usec / (RtsFlags.MiscFlags.tickInterval * 1000)); + return ((lnat)tv.tv_sec * 1000 / interval + + (lnat)tv.tv_usec / (interval * 1000)); }