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
This commit is contained in:
parent
fd01164a8d
commit
d3b9404241
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue