summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authoryusukes <yusukes@google.com>2018-02-13 18:28:50 -0800
committeryusukes <yusukes@google.com>2018-02-14 10:07:54 -0800
commitd3b94042418ed7561efca31d2a460588ab1fc161 (patch)
treef79cfb0387174dac254ca4e846d03bcc5387c525 /base
parentfd01164a8d3f350abf2ba26f6ff693d7ec4afa0e (diff)
downloadcore-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.cpp3
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();
}