[commit: ghc] master: Fix bug causing polling instead of blocking in the non-threaded RTS (#5773) (fac8ecb)
Simon Marlow
marlowsd at gmail.com
Mon Jan 16 14:28:08 CET 2012
Repository : ssh://darcs.haskell.org//srv/darcs/ghc
On branch : master
http://hackage.haskell.org/trac/ghc/changeset/fac8ecbbafde17dd92439c41747223c43e9d2b80
>---------------------------------------------------------------
commit fac8ecbbafde17dd92439c41747223c43e9d2b80
Author: Simon Marlow <marlowsd at gmail.com>
Date: Mon Jan 16 09:49:24 2012 +0000
Fix bug causing polling instead of blocking in the non-threaded RTS (#5773)
This was a regression introduced accidentally in
6b1098511aaabd2c9503ee7be6da1944466f9cb4. We were previously passing
a large time value to select() to simulate blocking, and this broke
due to a change from unsigned to signed arithmetic. I've refactored
it to be less fragile now - we just pass NULL as the timeval parameter
to select(), which is the correct way to do blocking.
>---------------------------------------------------------------
rts/posix/Select.c | 33 ++++++++++++++++-----------------
1 files changed, 16 insertions(+), 17 deletions(-)
diff --git a/rts/posix/Select.c b/rts/posix/Select.c
index 45737ce..ffe72e8 100644
--- a/rts/posix/Select.c
+++ b/rts/posix/Select.c
@@ -118,13 +118,9 @@ awaitEvent(rtsBool wait)
int maxfd = -1;
rtsBool select_succeeded = rtsTrue;
rtsBool unblock_all = rtsFalse;
- struct timeval tv;
- Time min;
+ struct timeval tv, *ptv;
LowResTime now;
- tv.tv_sec = 0;
- tv.tv_usec = 0;
-
IF_DEBUG(scheduler,
debugBelch("scheduler: checking for threads blocked on I/O");
if (wait) {
@@ -145,14 +141,6 @@ awaitEvent(rtsBool wait)
return;
}
- if (!wait) {
- min = 0;
- } else if (sleeping_queue != END_TSO_QUEUE) {
- min = LowResTimeToTime(sleeping_queue->block_info.target - now);
- } else {
- min = (Time)-1;
- }
-
/*
* Collect all of the fd's that we're interested in
*/
@@ -194,12 +182,23 @@ awaitEvent(rtsBool wait)
}
}
- /* Check for any interesting events */
+ if (wait) {
+ ptv = NULL;
+ } else if (sleeping_queue != END_TSO_QUEUE) {
+ Time min = LowResTimeToTime(sleeping_queue->block_info.target - now);
+ tv.tv_sec = TimeToSeconds(min);
+ tv.tv_usec = TimeToUS(min) % 1000000;
+ ptv = &tv;
+ } else {
+ // just poll
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+ ptv = &tv;
+ }
- tv.tv_sec = TimeToSeconds(min);
- tv.tv_usec = TimeToUS(min) % 1000000;
+ /* Check for any interesting events */
- while ((numFound = select(maxfd+1, &rfd, &wfd, NULL, &tv)) < 0) {
+ while ((numFound = select(maxfd+1, &rfd, &wfd, NULL, ptv)) < 0) {
if (errno != EINTR) {
/* Handle bad file descriptors by unblocking all the
waiting threads. Why? Because a thread might have been
More information about the Cvs-ghc
mailing list