X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Frts%2FItimer.c;h=07d6dcd6fe80e572df9bb10ddf7189aebc15cf0c;hb=67a402e25d3707ce4e031e809b874f8341032d23;hp=1bdd2bb4a4294634cc8a9d7b7570206e5d1005f2;hpb=bbe3617e46aa95ecb2519285d824a64bca17d228;p=ghc-hetmet.git diff --git a/ghc/rts/Itimer.c b/ghc/rts/Itimer.c index 1bdd2bb..07d6dcd 100644 --- a/ghc/rts/Itimer.c +++ b/ghc/rts/Itimer.c @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------------- - * $Id: Itimer.c,v 1.9 2000/02/28 10:57:44 simonmar Exp $ + * $Id: Itimer.c,v 1.17 2000/08/25 13:12:07 simonmar Exp $ * * (c) The GHC Team, 1995-1999 * @@ -23,7 +23,9 @@ #endif #include "Rts.h" +#include "RtsFlags.h" #include "Itimer.h" +#include "Proftimer.h" #include "Schedule.h" /* As recommended in the autoconf manual */ @@ -43,9 +45,16 @@ #endif lnat total_ticks = 0; -rtsBool do_prof_ticks = rtsFalse; -static void handle_tick(int unused STG_UNUSED); +/* ticks left before next pre-emptive context switch */ +int ticks_to_ctxt_switch = 0; + +static +void +#if defined(mingw32_TARGET_OS) || (defined(cygwin32_TARGET_OS) && !defined(HAVE_SETITIMER)) +CALLBACK +#endif +handle_tick(int unused STG_UNUSED); /* ----------------------------------------------------------------------------- Tick handler @@ -58,19 +67,29 @@ static void handle_tick(int unused STG_UNUSED); signal handler. -------------------------------------------------------------------------- */ -static void +static +void +#if defined(mingw32_TARGET_OS) || (defined(cygwin32_TARGET_OS) && !defined(HAVE_SETITIMER)) +CALLBACK +#endif handle_tick(int unused STG_UNUSED) { total_ticks++; #ifdef PROFILING - if (do_prof_ticks == rtsTrue) { - CCS_TICK(CCCS); - } + handleProfTick(); #endif - /* For threadDelay etc., see Select.c */ - ticks_since_select++; + /* so we can get a rough indication of the current time at any point + * without having to call gettimeofday() (see Select.c): + */ + ticks_since_timestamp++; + + ticks_to_ctxt_switch--; + if (ticks_to_ctxt_switch <= 0) { + ticks_to_ctxt_switch = RtsFlags.ConcFlags.ctxtSwitchTicks; + context_switch = 1; /* schedule a context switch */ + } } @@ -124,6 +143,7 @@ initialize_virtual_timer(nat ms) 0, TIME_PERIODIC); # endif + return 0; } @@ -133,11 +153,14 @@ nat initialize_virtual_timer(nat ms) { # ifndef HAVE_SETITIMER - fprintf(stderr, "No virtual timer on this system\n"); + /* fprintf(stderr, "No virtual timer on this system\n"); */ return -1; # else struct itimerval it; + timestamp = getourtimeofday(); + ticks_since_timestamp = 0; + it.it_value.tv_sec = ms / 1000; it.it_value.tv_usec = 1000 * (ms - (1000 * it.it_value.tv_sec)); it.it_interval = it.it_value; @@ -156,6 +179,9 @@ initialize_virtual_timer(nat ms) struct itimerspec it; timer_t tid; + timestamp = getourtimeofday(); + ticks_since_timestamp = 0; + se.sigev_notify = SIGEV_SIGNAL; se.sigev_signo = SIGVTALRM; se.sigev_value.sival_int = SIGVTALRM; @@ -213,3 +239,15 @@ unblock_vtalrm_signal(void) (void) sigprocmask(SIG_UNBLOCK, &signals, NULL); } #endif + +/* gettimeofday() takes around 1us on our 500MHz PIII. Since we're + * only calling it 50 times/s, it shouldn't have any great impact. + */ +unsigned int +getourtimeofday(void) +{ + struct timeval tv; + gettimeofday(&tv, (struct timezone *) NULL); + return (tv.tv_sec * TICK_FREQUENCY + + tv.tv_usec * TICK_FREQUENCY / 1000000); +}