X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Frts%2FItimer.c;h=74801dba542ca6a45b0cf2cc7dc97c20ff2c4cf9;hb=425008f93f115f9d5c92543e32838a47a7a7790f;hp=bbc87384e0bd648448d35685ecba57c062412f70;hpb=95371b03d1e5310f3b344cc2ecf29982e2bc9f5d;p=ghc-hetmet.git diff --git a/ghc/rts/Itimer.c b/ghc/rts/Itimer.c index bbc8738..74801db 100644 --- a/ghc/rts/Itimer.c +++ b/ghc/rts/Itimer.c @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------------- - * $Id: Itimer.c,v 1.31 2002/08/16 13:29:06 simonmar Exp $ + * $Id: Itimer.c,v 1.35 2003/03/29 00:27:11 sof Exp $ * * (c) The GHC Team, 1995-1999 * @@ -17,12 +17,9 @@ * Hence, we use the old-fashioned @setitimer@ that just about everyone seems * to support. So much for standards. */ - -/* This is not posix compliant. */ -/* #include "PosixSource.h" */ - #include "Rts.h" #include "RtsFlags.h" +#include "Timer.h" #include "Itimer.h" #include "Proftimer.h" #include "Schedule.h" @@ -39,129 +36,13 @@ # endif # endif -#if HAVE_WINDOWS_H -# include -#endif - #ifdef HAVE_SIGNAL_H # include #endif -static lnat total_ticks = 0; - -/* ticks left before next pre-emptive context switch */ -static int ticks_to_ctxt_switch = 0; - -/* ----------------------------------------------------------------------------- - Tick handler - - We use the ticker for time profiling. - - SMP note: this signal could be delivered to *any* thread. We have - to ensure that it doesn't matter which thread actually runs the - signal handler. - -------------------------------------------------------------------------- */ - static -void -#if defined(mingw32_TARGET_OS) || (defined(cygwin32_TARGET_OS) && !defined(HAVE_SETITIMER)) - -CALLBACK -handle_tick(UINT uID STG_UNUSED, UINT uMsg STG_UNUSED, DWORD dwUser STG_UNUSED, - DWORD dw1 STG_UNUSED, DWORD d STG_UNUSED) -#else -handle_tick(int unused STG_UNUSED) -#endif -{ - total_ticks++; - -#ifdef PROFILING - handleProfTick(); -#endif - - if (RtsFlags.ConcFlags.ctxtSwitchTicks > 0) { - ticks_to_ctxt_switch--; - if (ticks_to_ctxt_switch <= 0) { - ticks_to_ctxt_switch = RtsFlags.ConcFlags.ctxtSwitchTicks; - context_switch = 1; /* schedule a context switch */ - } - } -} - - -/* - * Handling timer events under cygwin32 is not done with signal/setitimer. - * Instead of the two steps of first registering a signal handler to handle - * \tr{SIGVTALRM} and then start generating them via @setitimer()@, we use - * the Multimedia API (MM) and its @timeSetEvent@. (Internally, the MM API - * creates a separate thread that will notify the main thread of timer - * expiry). -- SOF 7/96 - * - * 11/98: if the cygwin DLL supports setitimer(), then use it instead. - */ - -#if defined(mingw32_TARGET_OS) || (defined(cygwin32_TARGET_OS) && !defined(HAVE_SETITIMER)) - -static LPTIMECALLBACK vtalrm_cback; -static unsigned int vtalrm_id = 0; -static unsigned int period = -1; - int -startVirtTimer(nat ms) -{ - /* On Win32 setups that don't have support for - setitimer(), we use the MultiMedia API's timer - support. - - The delivery of ticks isn't free; the performance hit should be checked. - */ - unsigned int delay; - TIMECAPS tc; - - vtalrm_cback = handle_tick; - - if ( timeGetDevCaps(&tc, sizeof(TIMECAPS)) == TIMERR_NOERROR) { - period = tc.wPeriodMin; - delay = timeBeginPeriod(period); - if (delay == TIMERR_NOCANDO) { /* error of some sort. */ - return -1; - } - } else { - return -1; - } - -#ifdef PROFILING - initProfTimer(); -#endif - - vtalrm_id = - timeSetEvent(ms, /* event every `delay' milliseconds. */ - 1, /* precision is within 1 ms */ - vtalrm_cback, - TIME_CALLBACK_FUNCTION, /* ordinary callback */ - TIME_PERIODIC); - - return 0; -} - -int -stopVirtTimer() -{ - /* Shutdown the MM timer */ - if ( vtalrm_id != 0 ) { - timeKillEvent(vtalrm_id); - } - if (period > 0) { - timeEndPeriod(period); - } - - return 0; -} - -#else -static -int -install_vtalrm_handler(void) +install_vtalrm_handler(TickProc handle_tick) { struct sigaction action; @@ -174,7 +55,7 @@ install_vtalrm_handler(void) } int -startVirtTimer(nat ms) +startTicker(nat ms, TickProc handle_tick) { # ifndef HAVE_SETITIMER /* fprintf(stderr, "No virtual timer on this system\n"); */ @@ -182,14 +63,10 @@ startVirtTimer(nat ms) # else struct itimerval it; - install_vtalrm_handler(); + install_vtalrm_handler(handle_tick); timestamp = getourtimeofday(); -#ifdef PROFILING - initProfTimer(); -#endif - 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; @@ -198,7 +75,7 @@ startVirtTimer(nat ms) } int -stopVirtTimer() +stopTicker() { # ifndef HAVE_SETITIMER /* fprintf(stderr, "No virtual timer on this system\n"); */ @@ -213,12 +90,10 @@ stopVirtTimer() # endif } -#endif /* !{mingw,cygwin32}_TARGET_OS */ - # if 0 /* This is a potential POSIX version */ int -startVirtTimer(nat ms) +startTicker(nat ms) { struct sigevent se; struct itimerspec it; @@ -226,10 +101,6 @@ startVirtTimer(nat ms) timestamp = getourtimeofday(); -#ifdef PROFILING - initProfTimer(); -#endif - se.sigev_notify = SIGEV_SIGNAL; se.sigev_signo = SIGVTALRM; se.sigev_value.sival_int = SIGVTALRM; @@ -243,7 +114,7 @@ startVirtTimer(nat ms) } int -stopVirtTimer() +stopTicker() { struct sigevent se; struct itimerspec it; @@ -262,11 +133,10 @@ stopVirtTimer() it.it_interval = it.it_value; return timer_settime(tid, TIMER_RELTIME, &it, NULL); } - # endif -#if defined(mingw32_TARGET_OS) || (defined(cygwin32_TARGET_OS) && !defined(HAVE_SETITIMER)) -#else +#if 0 +/* Currently unused */ void block_vtalrm_signal(void) { @@ -293,7 +163,6 @@ unblock_vtalrm_signal(void) /* gettimeofday() takes around 1us on our 500MHz PIII. Since we're * only calling it 50 times/s, it shouldn't have any great impact. */ -#if !defined(mingw32_TARGET_OS) unsigned int getourtimeofday(void) { @@ -302,10 +171,4 @@ getourtimeofday(void) return (tv.tv_sec * TICK_FREQUENCY + tv.tv_usec * TICK_FREQUENCY / 1000000); } -#else -unsigned int -getourtimeofday(void) -{ - return ((unsigned int)GetTickCount() * TICK_FREQUENCY) / 1000; -} -#endif +