diff options
-rw-r--r-- | libs/binder/ActivityManager.cpp | 13 | ||||
-rw-r--r-- | libs/binder/IPCThreadState.cpp | 20 | ||||
-rw-r--r-- | libs/binder/IServiceManager.cpp | 31 | ||||
-rw-r--r-- | libs/binder/PermissionController.cpp | 12 | ||||
-rw-r--r-- | libs/binder/ProcessState.cpp | 2 | ||||
-rw-r--r-- | libs/binder/Utils.h | 7 | ||||
-rw-r--r-- | libs/binder/include/binder/ProcessState.h | 5 |
7 files changed, 54 insertions, 36 deletions
diff --git a/libs/binder/ActivityManager.cpp b/libs/binder/ActivityManager.cpp index 526427663b..98349c6ab3 100644 --- a/libs/binder/ActivityManager.cpp +++ b/libs/binder/ActivityManager.cpp @@ -23,10 +23,10 @@ #include <binder/IServiceManager.h> #include <binder/ProcessState.h> -#include <utils/SystemClock.h> - namespace android { +using namespace std::chrono_literals; + ActivityManager::ActivityManager() { } @@ -43,15 +43,16 @@ sp<IActivityManager> ActivityManager::getService() } } else { ALOGI("Thread pool not started. Polling for activity service."); - int64_t startTime = 0; + auto startTime = std::chrono::steady_clock::now().min(); while (service == nullptr || !IInterface::asBinder(service)->isBinderAlive()) { sp<IBinder> binder = defaultServiceManager()->checkService(String16("activity")); if (binder == nullptr) { // Wait for the activity service to come back... - if (startTime == 0) { - startTime = uptimeMillis(); + if (startTime == startTime.min()) { + startTime = std::chrono::steady_clock::now(); ALOGI("Waiting for activity service"); - } else if ((uptimeMillis() - startTime) > 1000000) { + } else if (std::chrono::steady_clock::now() - startTime > 1000s) { + // TODO(b/342453147): timeout of 1000s = 16min and 40s doesn't seem intended ALOGW("Waiting too long for activity service, giving up"); service = nullptr; break; diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp index c3bbdbadaa..61d0dbad31 100644 --- a/libs/binder/IPCThreadState.cpp +++ b/libs/binder/IPCThreadState.cpp @@ -25,7 +25,6 @@ #include <cutils/sched_policy.h> #include <utils/CallStack.h> #include <utils/Log.h> -#include <utils/SystemClock.h> #include <atomic> #include <errno.h> @@ -38,6 +37,7 @@ #include <sys/resource.h> #include <unistd.h> +#include "Utils.h" #include "binder_module.h" #if LOG_NDEBUG @@ -65,6 +65,8 @@ namespace android { +using namespace std::chrono_literals; + // Static const and functions will be optimized out if not used, // when LOG_NDEBUG and references in IF_LOG_COMMANDS() are optimized out. static const char* kReturnStrings[] = { @@ -647,8 +649,9 @@ status_t IPCThreadState::getAndExecuteCommand() size_t newThreadsCount = mProcess->mExecutingThreadsCount.fetch_add(1) + 1; if (newThreadsCount >= mProcess->mMaxThreads) { - int64_t expected = 0; - mProcess->mStarvationStartTimeMs.compare_exchange_strong(expected, uptimeMillis()); + auto expected = ProcessState::never(); + mProcess->mStarvationStartTime + .compare_exchange_strong(expected, std::chrono::steady_clock::now()); } result = executeCommand(cmd); @@ -656,12 +659,13 @@ status_t IPCThreadState::getAndExecuteCommand() size_t maxThreads = mProcess->mMaxThreads; newThreadsCount = mProcess->mExecutingThreadsCount.fetch_sub(1) - 1; if (newThreadsCount < maxThreads) { - size_t starvationStartTimeMs = mProcess->mStarvationStartTimeMs.exchange(0); - if (starvationStartTimeMs != 0) { - int64_t starvationTimeMs = uptimeMillis() - starvationStartTimeMs; - if (starvationTimeMs > 100) { + auto starvationStartTime = + mProcess->mStarvationStartTime.exchange(ProcessState::never()); + if (starvationStartTime != ProcessState::never()) { + auto starvationTime = std::chrono::steady_clock::now() - starvationStartTime; + if (starvationTime > 100ms) { ALOGE("binder thread pool (%zu threads) starved for %" PRId64 " ms", maxThreads, - starvationTimeMs); + to_ms(starvationTime)); } } } diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp index 5844c85d21..50d00ae2f2 100644 --- a/libs/binder/IServiceManager.cpp +++ b/libs/binder/IServiceManager.cpp @@ -21,6 +21,7 @@ #include <inttypes.h> #include <unistd.h> +#include <chrono> #include <condition_variable> #include <android-base/properties.h> @@ -30,7 +31,6 @@ #include <binder/Parcel.h> #include <utils/Log.h> #include <utils/String8.h> -#include <utils/SystemClock.h> #ifndef __ANDROID_VNDK__ #include <binder/IPermissionController.h> @@ -48,9 +48,12 @@ #endif #include "Static.h" +#include "Utils.h" namespace android { +using namespace std::chrono_literals; + using AidlRegistrationCallback = IServiceManager::LocalRegistrationCallback; using AidlServiceManager = android::os::IServiceManager; @@ -194,16 +197,16 @@ bool checkPermission(const String16& permission, pid_t pid, uid_t uid, bool logP pc = gPermissionController; gPermissionControllerLock.unlock(); - int64_t startTime = 0; + auto startTime = std::chrono::steady_clock::now().min(); while (true) { if (pc != nullptr) { bool res = pc->checkPermission(permission, pid, uid); if (res) { - if (startTime != 0) { - ALOGI("Check passed after %d seconds for %s from uid=%d pid=%d", - (int)((uptimeMillis() - startTime) / 1000), String8(permission).c_str(), - uid, pid); + if (startTime != startTime.min()) { + const auto waitTime = std::chrono::steady_clock::now() - startTime; + ALOGI("Check passed after %" PRIu64 "ms for %s from uid=%d pid=%d", + to_ms(waitTime), String8(permission).c_str(), uid, pid); } return res; } @@ -229,8 +232,8 @@ bool checkPermission(const String16& permission, pid_t pid, uid_t uid, bool logP sp<IBinder> binder = defaultServiceManager()->checkService(_permission); if (binder == nullptr) { // Wait for the permission controller to come back... - if (startTime == 0) { - startTime = uptimeMillis(); + if (startTime == startTime.min()) { + startTime = std::chrono::steady_clock::now(); ALOGI("Waiting to check permission %s from uid=%d pid=%d", String8(permission).c_str(), uid, pid); } @@ -287,8 +290,8 @@ sp<IBinder> ServiceManagerShim::getService(const String16& name) const const bool isVendorService = strcmp(ProcessState::self()->getDriverName().c_str(), "/dev/vndbinder") == 0; - constexpr int64_t timeout = 5000; - int64_t startTime = uptimeMillis(); + constexpr auto timeout = 5s; + const auto startTime = std::chrono::steady_clock::now(); // Vendor code can't access system properties if (!gSystemBootCompleted && !isVendorService) { #ifdef __ANDROID__ @@ -306,15 +309,16 @@ sp<IBinder> ServiceManagerShim::getService(const String16& name) const ProcessState::self()->getDriverName().c_str()); int n = 0; - while (uptimeMillis() - startTime < timeout) { + while (std::chrono::steady_clock::now() - startTime < timeout) { n++; usleep(1000*sleepTime); sp<IBinder> svc = checkService(name); if (svc != nullptr) { - ALOGI("Waiting for service '%s' on '%s' successful after waiting %" PRIi64 "ms", + const auto waitTime = std::chrono::steady_clock::now() - startTime; + ALOGI("Waiting for service '%s' on '%s' successful after waiting %" PRIu64 "ms", String8(name).c_str(), ProcessState::self()->getDriverName().c_str(), - uptimeMillis() - startTime); + to_ms(waitTime)); return svc; } } @@ -416,7 +420,6 @@ sp<IBinder> ServiceManagerShim::waitForService(const String16& name16) // that another thread serves the callback, and we never get a // command, so we hang indefinitely. std::unique_lock<std::mutex> lock(waiter->mMutex); - using std::literals::chrono_literals::operator""s; waiter->mCv.wait_for(lock, 1s, [&] { return waiter->mBinder != nullptr; }); diff --git a/libs/binder/PermissionController.cpp b/libs/binder/PermissionController.cpp index 0c8924503d..c11eb7df42 100644 --- a/libs/binder/PermissionController.cpp +++ b/libs/binder/PermissionController.cpp @@ -19,10 +19,10 @@ #include <binder/Binder.h> #include <binder/IServiceManager.h> -#include <utils/SystemClock.h> - namespace android { +using namespace std::chrono_literals; + PermissionController::PermissionController() { } @@ -30,16 +30,16 @@ PermissionController::PermissionController() sp<IPermissionController> PermissionController::getService() { std::lock_guard<Mutex> scoped_lock(mLock); - int64_t startTime = 0; + auto startTime = std::chrono::steady_clock::now().min(); sp<IPermissionController> service = mService; while (service == nullptr || !IInterface::asBinder(service)->isBinderAlive()) { sp<IBinder> binder = defaultServiceManager()->checkService(String16("permission")); if (binder == nullptr) { // Wait for the activity service to come back... - if (startTime == 0) { - startTime = uptimeMillis(); + if (startTime == startTime.min()) { + startTime = std::chrono::steady_clock::now(); ALOGI("Waiting for permission service"); - } else if ((uptimeMillis() - startTime) > 10000) { + } else if (std::chrono::steady_clock::now() - startTime > 10s) { ALOGW("Waiting too long for permission service, giving up"); service = nullptr; break; diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp index ad5a6b32b6..5de152a42a 100644 --- a/libs/binder/ProcessState.cpp +++ b/libs/binder/ProcessState.cpp @@ -555,7 +555,7 @@ ProcessState::ProcessState(const char* driver) mMaxThreads(DEFAULT_MAX_BINDER_THREADS), mCurrentThreads(0), mKernelStartedThreads(0), - mStarvationStartTimeMs(0), + mStarvationStartTime(never()), mForked(false), mThreadPoolStarted(false), mThreadPoolSeq(1), diff --git a/libs/binder/Utils.h b/libs/binder/Utils.h index df8a4ce1f1..5e1012af01 100644 --- a/libs/binder/Utils.h +++ b/libs/binder/Utils.h @@ -18,6 +18,7 @@ #include <stddef.h> #include <sys/uio.h> +#include <chrono> #include <cstdint> #include <optional> @@ -114,4 +115,10 @@ struct Span { // Android is little-endian. LIBBINDER_INTERNAL_EXPORTED std::string HexString(const void* bytes, size_t len); +// Converts any std::chrono duration to the number of milliseconds +template <class Rep, class Period> +uint64_t to_ms(std::chrono::duration<Rep, Period> duration) { + return std::chrono::duration_cast<std::chrono::milliseconds>(duration).count(); +} + } // namespace android diff --git a/libs/binder/include/binder/ProcessState.h b/libs/binder/include/binder/ProcessState.h index 11898a0515..8908cb8ae0 100644 --- a/libs/binder/include/binder/ProcessState.h +++ b/libs/binder/include/binder/ProcessState.h @@ -24,6 +24,7 @@ #include <pthread.h> #include <atomic> +#include <chrono> #include <mutex> // --------------------------------------------------------------------------- @@ -177,7 +178,9 @@ private: // Current number of pooled threads inside the thread pool. std::atomic_size_t mKernelStartedThreads; // Time when thread pool was emptied - std::atomic_int64_t mStarvationStartTimeMs; + std::atomic<std::chrono::steady_clock::time_point> mStarvationStartTime; + + static constexpr auto never = &std::chrono::steady_clock::time_point::min; mutable std::mutex mLock; // protects everything below. |