summaryrefslogtreecommitdiff
path: root/libraries/base/cbits/inputReady.c
diff options
context:
space:
mode:
authorNiklas Hambüchen <mail@nh2.me>2017-09-19 15:09:29 -0400
committerBen Gamari <ben@smart-cactus.org>2017-09-19 15:58:45 -0400
commit28a115e5e2c3c19b860545f1fcde4317bac3ee2a (patch)
tree35b97efde537ab5d79bb9abe4cf71c7a9c2d8961 /libraries/base/cbits/inputReady.c
parent7c7914d02a7ff189aba2f4feca31366fb4ab2664 (diff)
downloadhaskell-28a115e5e2c3c19b860545f1fcde4317bac3ee2a.tar.gz
base: fdReady(): Improve accuracy and simplify code.
This is done by reusing the existing cross-platform `getProcessElapsedTime()` function, which already provides nanosecond monotonic clocks, and fallback for platforms that don't have those. To do this, `getProcessElapsedTime()` had to be moved from a private RTS symbol into the public interface. Accuracy is improved in 2 ways: * Use of the monotonic clock where available * Measuring the total time spent waiting instead of a sum of intervals (between which there are small gaps) Reviewers: bgamari, austin, hvr, erikd, simonmar Reviewed By: bgamari Subscribers: rwbarton, thomie Differential Revision: https://phabricator.haskell.org/D3953
Diffstat (limited to 'libraries/base/cbits/inputReady.c')
-rw-r--r--libraries/base/cbits/inputReady.c31
1 files changed, 10 insertions, 21 deletions
diff --git a/libraries/base/cbits/inputReady.c b/libraries/base/cbits/inputReady.c
index e27851a2c7..dbfdb28b70 100644
--- a/libraries/base/cbits/inputReady.c
+++ b/libraries/base/cbits/inputReady.c
@@ -7,9 +7,9 @@
/* select and supporting types is not Posix */
/* #include "PosixSource.h" */
#include "HsBase.h"
+#include "Rts.h"
#if !defined(_WIN32)
#include <poll.h>
-#include <sys/time.h>
#endif
/*
@@ -25,37 +25,26 @@ fdReady(int fd, int write, int msecs, int isSock)
#if !defined(_WIN32)
struct pollfd fds[1];
- // if we need to track the then record the current time in case we are
+ // if we need to track the time then record the end time in case we are
// interrupted.
- struct timeval tv0;
+ Time endTime = 0;
if (msecs > 0) {
- if (gettimeofday(&tv0, NULL) != 0) {
- fprintf(stderr, "fdReady: gettimeofday failed: %s\n",
- strerror(errno));
- abort();
- }
+ endTime = getProcessElapsedTime() + MSToTime(msecs);
}
fds[0].fd = fd;
fds[0].events = write ? POLLOUT : POLLIN;
fds[0].revents = 0;
+ Time remaining = MSToTime(msecs);
+
int res;
- while ((res = poll(fds, 1, msecs)) < 0) {
+ while ((res = poll(fds, 1, TimeToMS(remaining))) < 0) {
if (errno == EINTR) {
if (msecs > 0) {
- struct timeval tv;
- if (gettimeofday(&tv, NULL) != 0) {
- fprintf(stderr, "fdReady: gettimeofday failed: %s\n",
- strerror(errno));
- abort();
- }
-
- int elapsed = 1000 * (tv.tv_sec - tv0.tv_sec)
- + (tv.tv_usec - tv0.tv_usec) / 1000;
- msecs -= elapsed;
- if (msecs <= 0) return 0;
- tv0 = tv;
+ Time now = getProcessElapsedTime();
+ if (now >= endTime) return 0;
+ remaining = endTime - now;
}
} else {
return (-1);