aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/sys/common/erl_poll.c
diff options
context:
space:
mode:
authorRickard Green <[email protected]>2016-08-31 14:29:25 +0200
committerRickard Green <[email protected]>2016-08-31 14:29:25 +0200
commit451eb69edbe6c1b2ed53bcac18babda57e5f964c (patch)
tree6ab0a528a27a8c0437a01070ee64df9e8833af2d /erts/emulator/sys/common/erl_poll.c
parentc1e1c7b4caeda9637691c062d5c1337afe7aeeab (diff)
parentb71dde8bd94985f5953a1647802ac312a798fe69 (diff)
downloadotp-451eb69edbe6c1b2ed53bcac18babda57e5f964c.tar.gz
otp-451eb69edbe6c1b2ed53bcac18babda57e5f964c.tar.bz2
otp-451eb69edbe6c1b2ed53bcac18babda57e5f964c.zip
Merge branch 'rickard/premature-timeout/OTP-13698' into maint
* rickard/premature-timeout/OTP-13698: Improve accuracy of timeouts using premature timeouts
Diffstat (limited to 'erts/emulator/sys/common/erl_poll.c')
-rw-r--r--erts/emulator/sys/common/erl_poll.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/erts/emulator/sys/common/erl_poll.c b/erts/emulator/sys/common/erl_poll.c
index e394d84f73..b8a28bcc18 100644
--- a/erts/emulator/sys/common/erl_poll.c
+++ b/erts/emulator/sys/common/erl_poll.c
@@ -75,6 +75,7 @@
#include "erl_driver.h"
#include "erl_alloc.h"
#include "erl_msacc.h"
+#include "erl_misc_utils.h"
#if !defined(ERTS_POLL_USE_EPOLL) \
&& !defined(ERTS_POLL_USE_DEVPOLL) \
@@ -2132,16 +2133,19 @@ get_timeout(ErtsPollSet ps,
if (timeout > (ErtsMonotonicTime) INT_MAX)
timeout = (ErtsMonotonicTime) INT_MAX;
save_timeout_time += ERTS_MSEC_TO_MONOTONIC(timeout);
+ timeout -= ERTS_PREMATURE_TIMEOUT(timeout, 1000);
break;
case 1000000:
/* Round up to nearest even micro second */
timeout = ERTS_MONOTONIC_TO_USEC(diff_time - 1) + 1;
save_timeout_time += ERTS_USEC_TO_MONOTONIC(timeout);
+ timeout -= ERTS_PREMATURE_TIMEOUT(timeout, 1000*1000);
break;
case 1000000000:
/* Round up to nearest even nano second */
timeout = ERTS_MONOTONIC_TO_NSEC(diff_time - 1) + 1;
save_timeout_time += ERTS_NSEC_TO_MONOTONIC(timeout);
+ timeout -= ERTS_PREMATURE_TIMEOUT(timeout, 1000*1000*1000);
break;
default:
ERTS_INTERNAL_ERROR("Invalid resolution");
@@ -2452,7 +2456,15 @@ ERTS_POLL_EXPORT(erts_poll_wait)(ErtsPollSet ps,
}
#endif
- res = check_fd_events(ps, to, no_fds);
+ while (1) {
+ res = check_fd_events(ps, to, no_fds);
+ if (res != 0)
+ break;
+ if (to == ERTS_POLL_NO_TIMEOUT)
+ break;
+ if (erts_get_monotonic_time(NULL) >= timeout_time)
+ break;
+ }
woke_up(ps);