Migrate from libutils SystemClock.h to std::chrono
Bug: 341997808
Test: mma
Change-Id: Ib4d60eeaaac73566cc79d473f6551e9abd20e69a
diff --git a/libs/binder/ActivityManager.cpp b/libs/binder/ActivityManager.cpp
index 5264276..98349c6 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 @@
}
} 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 c3bbdba..61d0dba 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 @@
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 @@
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 5844c85..50d00ae 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 @@
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 @@
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 @@
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 @@
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 @@
// 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 0c89245..c11eb7d 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 @@
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 ad5a6b3..5de152a 100644
--- a/libs/binder/ProcessState.cpp
+++ b/libs/binder/ProcessState.cpp
@@ -555,7 +555,7 @@
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 df8a4ce..5e1012a 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 @@
// 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 11898a0..8908cb8 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 @@
// 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.