diff options
author | Rickard Green <[email protected]> | 2016-06-20 15:51:25 +0200 |
---|---|---|
committer | Rickard Green <[email protected]> | 2016-06-22 17:13:45 +0200 |
commit | b71dde8bd94985f5953a1647802ac312a798fe69 (patch) | |
tree | d9aa5f8970daaff01d2e925e6fea7727ad233a77 /erts/emulator/sys/common | |
parent | 3b7a6ffddc819bf305353a593904cea9e932e7dc (diff) | |
download | otp-b71dde8bd94985f5953a1647802ac312a798fe69.tar.gz otp-b71dde8bd94985f5953a1647802ac312a798fe69.tar.bz2 otp-b71dde8bd94985f5953a1647802ac312a798fe69.zip |
Improve accuracy of timeouts using premature timeouts
Improve accuracy of timeouts using a premature timeout then
return to sleep with a shorter timeout just before requested
timeout. This approach is only used on certain platforms where
we know it improves the accuracy of the timeouts, e.g. MacOS X.
Diffstat (limited to 'erts/emulator/sys/common')
-rw-r--r-- | erts/emulator/sys/common/erl_poll.c | 14 |
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); |