diff options
author | yusukes <yusukes@google.com> | 2018-02-13 18:28:50 -0800 |
---|---|---|
committer | yusukes <yusukes@google.com> | 2018-02-14 10:07:54 -0800 |
commit | d3b94042418ed7561efca31d2a460588ab1fc161 (patch) | |
tree | f79cfb0387174dac254ca4e846d03bcc5387c525 /base | |
parent | fd01164a8d3f350abf2ba26f6ff693d7ec4afa0e (diff) | |
download | core-d3b94042418ed7561efca31d2a460588ab1fc161.tar.gz core-d3b94042418ed7561efca31d2a460588ab1fc161.tar.bz2 core-d3b94042418ed7561efca31d2a460588ab1fc161.zip |
Prevent WaitForProperty() from using ~100% of CPU time on 32bit builds
Since 'struct timespec' members (time_t and long) are both 32bit on
32bit systems, and std::chrono::{seconds,nanoseconds}::rep are both
>32bit, timespec members assigned in DurationToTimeSpec() can have a
negative value, especially when WaitForProperty() is called with the
default timeout value which is std::chrono::milliseconds::max().
Regarding functionality, passing a negative value to
__system_property_wait() is okay because WaitForProperty() still
waits for the property value (so unit tests are passing), but while
WaitForProperty() does that, the function, to be more exact,
SystemProperties::Wait() in bionic/, consumes ~100% of CPU time. This
happens because SystemProperties::Wait() which implements
__system_property_wait() has a tight while-loop with a __futex_wait()
call, and the futex call immediately returns EINVAL when the timespec
passed in has a negative value.
With this CL, WaitForProperty() will never pass a negative timespec
to __system_property_wait(), and therefore the __futex_wait() call
in bionic works as expected without consuming too much CPU time even
on 32bit systems.
Bug: None
Test: libbase_test32 still passes
Test: strace no longer shows repeated EINVALs from __futex_wait
Change-Id: Id1834fac8cd2876b02dbe4479bf3d3eda2fa7da1
Diffstat (limited to 'base')
-rw-r--r-- | base/properties.cpp | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/base/properties.cpp b/base/properties.cpp index cde4d69e3..ca8e96fc4 100644 --- a/base/properties.cpp +++ b/base/properties.cpp @@ -23,6 +23,7 @@ #include <algorithm> #include <chrono> +#include <limits> #include <string> #include <android-base/parseint.h> @@ -109,7 +110,7 @@ static void WaitForPropertyCallback(void* data_ptr, const char*, const char* val static void DurationToTimeSpec(timespec& ts, const std::chrono::milliseconds d) { auto s = std::chrono::duration_cast<std::chrono::seconds>(d); auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(d - s); - ts.tv_sec = s.count(); + ts.tv_sec = std::min<std::chrono::seconds::rep>(s.count(), std::numeric_limits<time_t>::max()); ts.tv_nsec = ns.count(); } |