summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authoryusukes2018-02-13 20:28:50 -0600
committeryusukes2018-02-14 12:07:54 -0600
commitd3b94042418ed7561efca31d2a460588ab1fc161 (patch)
treef79cfb0387174dac254ca4e846d03bcc5387c525 /base
parentfd01164a8d3f350abf2ba26f6ff693d7ec4afa0e (diff)
downloadplatform-system-core-d3b94042418ed7561efca31d2a460588ab1fc161.tar.gz
platform-system-core-d3b94042418ed7561efca31d2a460588ab1fc161.tar.xz
platform-system-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 @@
23 23
24#include <algorithm> 24#include <algorithm>
25#include <chrono> 25#include <chrono>
26#include <limits>
26#include <string> 27#include <string>
27 28
28#include <android-base/parseint.h> 29#include <android-base/parseint.h>
@@ -109,7 +110,7 @@ static void WaitForPropertyCallback(void* data_ptr, const char*, const char* val
109static void DurationToTimeSpec(timespec& ts, const std::chrono::milliseconds d) { 110static void DurationToTimeSpec(timespec& ts, const std::chrono::milliseconds d) {
110 auto s = std::chrono::duration_cast<std::chrono::seconds>(d); 111 auto s = std::chrono::duration_cast<std::chrono::seconds>(d);
111 auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(d - s); 112 auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(d - s);
112 ts.tv_sec = s.count(); 113 ts.tv_sec = std::min<std::chrono::seconds::rep>(s.count(), std::numeric_limits<time_t>::max());
113 ts.tv_nsec = ns.count(); 114 ts.tv_nsec = ns.count();
114} 115}
115 116