X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Frts%2FItimer.c;h=60e30e786d649780815d0e8d0d21faabc00118ce;hb=c5725b16ca7090841e54222ccf9122bdcb3f7047;hp=99811c7a0359dc181d65ca957d9de434cc1880fc;hpb=438596897ebbe25a07e1c82085cfbc5bdb00f09e;p=ghc-hetmet.git diff --git a/ghc/rts/Itimer.c b/ghc/rts/Itimer.c index 99811c7..60e30e7 100644 --- a/ghc/rts/Itimer.c +++ b/ghc/rts/Itimer.c @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- - * $Id: Itimer.c,v 1.2 1998/12/02 13:28:27 simonm Exp $ + * $Id: Itimer.c,v 1.13 2000/04/03 15:54:49 simonmar Exp $ * - * (c) The GHC Team, 1995-1998 + * (c) The GHC Team, 1995-1999 * * Interval timer for profiling and pre-emptive scheduling. * @@ -24,6 +24,8 @@ #include "Rts.h" #include "Itimer.h" +#include "Proftimer.h" +#include "Schedule.h" /* As recommended in the autoconf manual */ # ifdef TIME_WITH_SYS_TIME @@ -36,7 +38,49 @@ # include # endif # endif + +#if HAVE_WINDOWS_H +# include +#endif +lnat total_ticks = 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 + + We use the ticker for two things: supporting threadDelay, and 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 +#endif +handle_tick(int unused STG_UNUSED) +{ + total_ticks++; + +#ifdef PROFILING + handleProfTick(); +#endif + + /* For threadDelay etc., see Select.c */ + ticks_since_select++; +} + + /* * Handling timer events under cygwin32 is not done with signal/setitimer. * Instead of the two steps of first registering a signal handler to handle @@ -48,28 +92,47 @@ * 11/98: if the cygwin DLL supports setitimer(), then use it instead. */ -#if defined(cygwin32_TARGET_OS) && !defined(HAVE_SETITIMER) - -#include /* OK, bring it all in... */ +#if defined(mingw32_TARGET_OS) || (defined(cygwin32_TARGET_OS) && !defined(HAVE_SETITIMER)) +/* + * Sigh - to avoid requiring anyone that wants to build ghc to have + * to augment the Win32 header files that comes with cygwinb20.1, + * include the missing MM API decls here inline. + * + * ToDo: check and remove these once the next version of cygwin is + * released. + */ +#define TIMERR_NOERROR 0 +#define TIMERR_NOCANDO 97 +#define TIME_PERIODIC 1 + +typedef UINT MMRESULT; +typedef void CALLBACK (*TIMECALLBACK) (UINT, UINT, DWORD, DWORD, DWORD); +typedef TIMECALLBACK *LPTIMECALLBACK; +MMRESULT STDCALL timeSetEvent(UINT, UINT, LPTIMECALLBACK, DWORD, UINT); /* - vtalrm_handler is assigned and set up in - main/Signals.lc. + vtalrm_handler is assigned and set up in Signals.c - vtalrm_id (defined in main/Signals.lc) holds + vtalrm_id (defined in Signals.c) holds the system id for the current timer (used to - later block/kill the timer) + later block/kill it.) */ extern nat vtalrm_id; -extern TIMECALLBACK *vtalrm_cback; +TIMECALLBACK *vtalrm_cback; nat initialize_virtual_timer(nat ms) { - /* VTALRM is currently not supported by cygwin32, - so we use the Timer support provided by the - MultiMedia API that is part of Win32. The - parameters to timeSetEvent may require some tweaking. +# ifdef PROFILING + /* On Win32 setups that don't have support for + setitimer(), we use the MultiMedia API's timer + support. + + As the delivery of ticks isn't free, we only + enable it if we really needed, i.e., when profiling. + (the RTS now also needs timer ticks to implement + threadDelay in non-profiling mode, but the pure + Win32 port doesn't support that.....yet.) */ unsigned int delay,vtalrm_id; @@ -83,6 +146,7 @@ initialize_virtual_timer(nat ms) (LPTIMECALLBACK)vtalrm_cback, 0, TIME_PERIODIC); +# endif return 0; } @@ -92,7 +156,7 @@ 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; @@ -119,8 +183,7 @@ initialize_virtual_timer(nat ms) se.sigev_signo = SIGVTALRM; se.sigev_value.sival_int = SIGVTALRM; if (timer_create(CLOCK_VIRTUAL, &se, &tid)) { - fprintf(stderr, "Can't create virtual timer.\n"); - EXIT(EXIT_FAILURE); + barf("can't create virtual timer"); } it.it_value.tv_sec = ms / 1000; it.it_value.tv_nsec = 1000000 * (ms - 1000 * it.it_value.tv_sec); @@ -129,12 +192,21 @@ initialize_virtual_timer(nat ms) } # endif +#if defined(mingw32_TARGET_OS) || (defined(cygwin32_TARGET_OS) && !defined(HAVE_SETITIMER)) int -install_vtalrm_handler(void (*handler)(int)) +install_vtalrm_handler(void) +{ + vtalrm_cback = handle_tick; + return 0; +} + +#else +int +install_vtalrm_handler(void) { struct sigaction action; - action.sa_handler = handler; + action.sa_handler = handle_tick; sigemptyset(&action.sa_mask); action.sa_flags = 0; @@ -163,3 +235,14 @@ unblock_vtalrm_signal(void) (void) sigprocmask(SIG_UNBLOCK, &signals, NULL); } +#endif + +#if !defined(HAVE_SETITIMER) && !defined(mingw32_TARGET_OS) +unsigned int +getourtimeofday(void) +{ + struct timeval tv; + gettimeofday(&tv, (struct timezone *) NULL); + return (tv.tv_sec * 1000000 + tv.tv_usec); +} +#endif