Commit 354a661d authored by simonmar's avatar simonmar

[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
 */
parent fdb2b1fd
/* -----------------------------------------------------------------------------
* $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 <signal.h>
#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);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment