From: simonmar Date: Mon, 22 Dec 2003 16:27:10 +0000 (+0000) Subject: [project @ 2003-12-22 16:27:10 by simonmar] X-Git-Tag: Approx_11550_changesets_converted~168 X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=commitdiff_plain;h=354a661d0164c8ac4e4e469ec77cf06c27e028f9 [project @ 2003-12-22 16:27:10 by simonmar] Fix threaded RTS problem that is currently causing the conc007 test to loop indefinitely. Comment from the source regarding this change: /* Major bogosity: * * In the threaded RTS, we can't set the virtual timer because the * thread which has the virtual timer might be sitting waiting for a * capability, and the virtual timer only ticks in CPU time. * * So, possible solutions: * * (1) tick in realtime. Not very good, because this ticker is used for * profiling, and this will give us unreliable time profiling * results. Furthermore, this requires picking a single OS thread * to be the timekeeper, which is a bad idea because the thread in * question might just be making a temporary call into Haskell land. * * (2) save/restore the virtual timer around excursions into STG land. * Sounds great, but I tried it and the resolution of the virtual timer * isn't good enough (on Linux) - most of our excursions fall * within the timer's resolution and we never make any progress. * * (3) have a virtual timer in every OS thread. Might be reasonable, * because most of the time there is only ever one of these * threads running, so it approximates a single virtual timer. * But still quite bogus (and I got crashes when I tried this). * * For now, we're using (1), but this needs a better solution. --SDM */ --- diff --git a/ghc/rts/Itimer.c b/ghc/rts/Itimer.c index 74801db..2f769d3 100644 --- a/ghc/rts/Itimer.c +++ b/ghc/rts/Itimer.c @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------------- - * $Id: Itimer.c,v 1.35 2003/03/29 00:27:11 sof Exp $ + * $Id: Itimer.c,v 1.36 2003/12/22 16:27:10 simonmar Exp $ * * (c) The GHC Team, 1995-1999 * @@ -40,6 +40,40 @@ # include #endif +/* Major bogosity: + * + * In the threaded RTS, we can't set the virtual timer because the + * thread which has the virtual timer might be sitting waiting for a + * capability, and the virtual timer only ticks in CPU time. + * + * So, possible solutions: + * + * (1) tick in realtime. Not very good, because this ticker is used for + * profiling, and this will give us unreliable time profiling + * results. Furthermore, this requires picking a single OS thread + * to be the timekeeper, which is a bad idea because the thread in + * question might just be making a temporary call into Haskell land. + * + * (2) save/restore the virtual timer around excursions into STG land. + * Sounds great, but I tried it and the resolution of the virtual timer + * isn't good enough (on Linux) - most of our excursions fall + * within the timer's resolution and we never make any progress. + * + * (3) have a virtual timer in every OS thread. Might be reasonable, + * because most of the time there is only ever one of these + * threads running, so it approximates a single virtual timer. + * But still quite bogus (and I got crashes when I tried this). + * + * For now, we're using (1), but this needs a better solution. --SDM + */ +#ifdef RTS_SUPPORTS_THREADS +#define ITIMER_FLAVOUR ITIMER_REAL +#define ITIMER_SIGNAL SIGALRM +#else +#define ITIMER_FLAVOUR ITIMER_VIRTUAL +#define ITIMER_SIGNAL SIGVTALRM +#endif + static int install_vtalrm_handler(TickProc handle_tick) @@ -51,7 +85,7 @@ install_vtalrm_handler(TickProc handle_tick) sigemptyset(&action.sa_mask); action.sa_flags = 0; - return sigaction(SIGVTALRM, &action, NULL); + return sigaction(ITIMER_SIGNAL, &action, NULL); } int @@ -70,7 +104,7 @@ startTicker(nat ms, TickProc handle_tick) 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; - return (setitimer(ITIMER_VIRTUAL, &it, NULL)); + return (setitimer(ITIMER_FLAVOUR, &it, NULL)); # endif } @@ -86,7 +120,7 @@ stopTicker() it.it_value.tv_sec = 0; it.it_value.tv_usec = 0; it.it_interval = it.it_value; - return (setitimer(ITIMER_VIRTUAL, &it, NULL)); + return (setitimer(ITIMER_FLAVOUR, &it, NULL)); # endif } @@ -102,8 +136,8 @@ startTicker(nat ms) timestamp = getourtimeofday(); se.sigev_notify = SIGEV_SIGNAL; - se.sigev_signo = SIGVTALRM; - se.sigev_value.sival_int = SIGVTALRM; + se.sigev_signo = ITIMER_SIGNAL; + se.sigev_value.sival_int = ITIMER_SIGNAL; if (timer_create(CLOCK_VIRTUAL, &se, &tid)) { barf("can't create virtual timer"); } @@ -123,8 +157,8 @@ stopTicker() timestamp = getourtimeofday(); se.sigev_notify = SIGEV_SIGNAL; - se.sigev_signo = SIGVTALRM; - se.sigev_value.sival_int = SIGVTALRM; + se.sigev_signo = ITIMER_SIGNAL; + se.sigev_value.sival_int = ITIMER_SIGNAL; if (timer_create(CLOCK_VIRTUAL, &se, &tid)) { barf("can't create virtual timer"); } @@ -143,7 +177,7 @@ block_vtalrm_signal(void) sigset_t signals; sigemptyset(&signals); - sigaddset(&signals, SIGVTALRM); + sigaddset(&signals, ITIMER_SIGNAL); (void) sigprocmask(SIG_BLOCK, &signals, NULL); } @@ -154,7 +188,7 @@ unblock_vtalrm_signal(void) sigset_t signals; sigemptyset(&signals); - sigaddset(&signals, SIGVTALRM); + sigaddset(&signals, ITIMER_SIGNAL); (void) sigprocmask(SIG_UNBLOCK, &signals, NULL); }