From 19a43aba371c6ab9348dd698b3dc03116a2af005 Mon Sep 17 00:00:00 2001 From: sof Date: Tue, 21 Jan 1997 08:55:31 +0000 Subject: [PATCH] [project @ 1997-01-21 08:54:45 by sof] Added timer stuff for cygwin32 --- ghc/runtime/main/Itimer.lc | 54 ++++++++++++++++++- ghc/runtime/main/Signals.lc | 122 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 172 insertions(+), 4 deletions(-) diff --git a/ghc/runtime/main/Itimer.lc b/ghc/runtime/main/Itimer.lc index 8847c7c..1068825 100644 --- a/ghc/runtime/main/Itimer.lc +++ b/ghc/runtime/main/Itimer.lc @@ -8,7 +8,7 @@ %************************************************************************ The interval timer is used for profiling and for context switching in the -threaded build. Though POSIX 1003.4 includes a standard interface for +threaded build. Though POSIX 1003.1b includes a standard interface for such things, no one really seems to be implementing them yet. Even Solaris 2.3 only seems to provide support for @CLOCK_REAL@, whereas we're keen on getting access to @CLOCK_VIRTUAL@. @@ -37,6 +37,56 @@ to support. So much for standards. # include # endif # endif +\end{code} + +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 + +\begin{code} +#if defined(cygwin32_TARGET_OS) + +#include /* OK, bring it all in... */ + +/* + vtalrm_handler is assigned and set up in + main/Signals.lc. + + vtalrm_id (defined in main/Signals.lc) holds + the system id for the current timer (used to + later block/kill the timer) +*/ +extern I_ vtalrm_id; +extern TIMECALLBACK *vtalrm_cback; + +int +initialize_virtual_timer(ms) +int 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. + */ + unsigned int delay,vtalrm_id; + + delay = timeBeginPeriod(1); + if (delay == TIMERR_NOCANDO) { /* error of some sort. */ + return delay; + } + vtalrm_id = + timeSetEvent(ms, /* event every `delay' milliseconds. */ + 1, /* precision is within 5 millisecs. */ + (LPTIMECALLBACK)vtalrm_cback, + 0, + TIME_PERIODIC); + return 0; +} + +#else int initialize_virtual_timer(ms) @@ -55,6 +105,8 @@ int ms; # endif } +#endif /* !cygwin32_TARGET_OS */ + # if 0 /* This is a potential POSIX version */ int diff --git a/ghc/runtime/main/Signals.lc b/ghc/runtime/main/Signals.lc index bfc10c3..6569d49 100644 --- a/ghc/runtime/main/Signals.lc +++ b/ghc/runtime/main/Signals.lc @@ -61,6 +61,10 @@ much pain. # include #endif +#if defined(cygwin32_TARGET_OS) +#include +#endif + \end{code} %************************************************************************ @@ -138,6 +142,44 @@ install_segv_handler(void) # define si_addr _data._fault._addr # endif +#if defined(cygwin32_TARGET_OS) +/* + The signal handlers in cygwin32 (beta14) are only passed the signal + number, no sigcontext/siginfo is passed as event data..sigh. For + SIGSEGV, to get at the violating address, we need to use the Win32's + WaitForDebugEvent() to get out any status information. +*/ +static void +segv_handler(sig) + int sig; +{ + /* From gdb/win32-nat.c */ + DEBUG_EVENT event; + BOOL t = TRUE; /* WaitForDebugEvent (&event, INFINITE); */ + + fflush(stdout); + if (t == FALSE) { + fprintf(stderr, "Segmentation fault caught, address unknown\n"); + } else { + void *si_addr = event.u.Exception.ExceptionRecord.ExceptionAddress; + if (si_addr >= (void *) stks_space + && si_addr < (void *) (stks_space + RTSflags.GcFlags.stksSize)) + StackOverflow(); + + fprintf(stderr, "Segmentation fault caught, address = %08lx\n", (W_)si_addr); + } + abort(); +} + +int +install_segv_handler() +{ + return (int) signal(SIGSEGV, segv_handler) == -1; +} + + +#else /* !defined(cygwin32_TARGET_OS) */ + static void segv_handler(int sig, siginfo_t *sip) /* NB: the second "siginfo_t" argument is not really standard */ @@ -167,6 +209,8 @@ install_segv_handler(STG_NO_ARGS) return sigaction(SIGSEGV, &action, NULL); } +#endif /* not cygwin32_TARGET_OS */ + # endif /* not SunOS 4 */ #endif /* STACK_CHECK_BY_PAGE_FAULT */ @@ -195,8 +239,24 @@ extern I_ delayTicks; extern P_ CurrentTSO; # endif +/* + cygwin32 does not support VTALRM (sigh) - to do anything + sensible here we use the underlying Win32 calls. + (will this work??) +*/ +# if defined(cygwin32_TARGET_OS) +/* windows.h already included */ +static VOID CALLBACK +vtalrm_handler(uID,uMsg,dwUser,dw1,dw2) +int uID; +unsigned int uMsg; +unsigned int dwUser; +unsigned int dw1; +unsigned int dw2; +# else static void vtalrm_handler(int sig) +# endif { /* For the parallel world, currentTSO is set if there is any work @@ -273,7 +333,63 @@ vtalrm_handler(int sig) # endif -# if defined(sunos4_TARGET_OS) + +#if defined(cygwin32_TARGET_OS) /* really just Win32 */ +/* windows.h already included for the segv_handling above */ + +I_ vtalrm_id; +TIMECALLBACK *vtalrm_cback; + +#ifndef CONCURRENT +void (*tick_handle)(STG_NO_ARGS); + +static VOID CALLBACK +tick_handler(uID,uMsg,dwUser,dw1,dw2) +int uID; +unsigned int uMsg; +unsigned int dwUser; +unsigned int dw1; +unsigned int dw2; +{ + (*tick_handle)(); +} +#endif + +int install_vtalrm_handler() +{ +# ifdef CONCURRENT + vtalrm_cback = vtalrm_handler; +# else + /* + Only turn on ticking + */ + vtalrm_cback = tick_handler; + if (RTSflags.CcFlags.doCostCentres >= COST_CENTRES_VERBOSE + || RTSflags.ProfFlags.doHeapProfile) + tick_handle = handle_tick_serial; + else + tick_handle = handle_tick_noserial; +# endif + return (int)0; +} + +void +blockVtAlrmSignal(STG_NO_ARGS) +{ + timeKillEvent(vtalrm_id); +} + +void +unblockVtAlrmSignal(STG_NO_ARGS) +{ +#ifdef CONCURRENT + timeSetEvent(RTSflags.ConcFlags.ctxtSwitchTime,5,vtalrm_cback,NULL,TIME_PERIODIC); +#else + timeSetEvent(RTSflags.CcFlags.msecsPerTick,5,vtalrm_cback,NULL,TIME_PERIODIC); +#endif +} + +#elif defined(sunos4_TARGET_OS) int install_vtalrm_handler(void) @@ -396,8 +512,8 @@ sig_install(sig, spi, mask) # include -StgPtr deRefStablePointer PROTO((StgStablePtr)); -void freeStablePointer PROTO((I_)); +extern StgPtr deRefStablePointer PROTO((StgStablePtr)); +extern void freeStablePointer PROTO((I_)); extern jmp_buf restart_main; static I_ *handlers = NULL; /* Dynamically grown array of signal handlers */ -- 1.7.10.4