Add lock guards to performance hint NDK
Test: atest PerformanceHintNativeTest
Bug: 343817997
Change-Id: Ic48949252be3122e2e13cfa5979f8831aea72a93
diff --git a/native/android/Android.bp b/native/android/Android.bp
index 8945bd1..c4c4102 100644
--- a/native/android/Android.bp
+++ b/native/android/Android.bp
@@ -41,6 +41,7 @@
"-Wextra",
"-Wunused",
"-Wunreachable-code",
+ "-Wthread-safety",
],
}
diff --git a/native/android/performance_hint.cpp b/native/android/performance_hint.cpp
index f64b847..a0e434e 100644
--- a/native/android/performance_hint.cpp
+++ b/native/android/performance_hint.cpp
@@ -23,6 +23,7 @@
#include <aidl/android/os/IHintManager.h>
#include <aidl/android/os/IHintSession.h>
#include <android-base/stringprintf.h>
+#include <android-base/thread_annotations.h>
#include <android/binder_manager.h>
#include <android/binder_status.h>
#include <android/performance_hint.h>
@@ -111,26 +112,26 @@
// HAL preferred update rate
const int64_t mPreferredRateNanos;
// Target duration for choosing update rate
- int64_t mTargetDurationNanos;
+ int64_t mTargetDurationNanos GUARDED_BY(sHintMutex);
// First target hit timestamp
- int64_t mFirstTargetMetTimestamp;
+ int64_t mFirstTargetMetTimestamp GUARDED_BY(sHintMutex);
// Last target hit timestamp
- int64_t mLastTargetMetTimestamp;
+ int64_t mLastTargetMetTimestamp GUARDED_BY(sHintMutex);
// Last hint reported from sendHint indexed by hint value
- std::vector<int64_t> mLastHintSentTimestamp;
+ std::vector<int64_t> mLastHintSentTimestamp GUARDED_BY(sHintMutex);
// Cached samples
- std::vector<hal::WorkDuration> mActualWorkDurations;
- std::string mSessionName;
- static int64_t sIDCounter;
+ std::vector<hal::WorkDuration> mActualWorkDurations GUARDED_BY(sHintMutex);
+ std::string mSessionName GUARDED_BY(sHintMutex);
+ static int64_t sIDCounter GUARDED_BY(sHintMutex);
// The most recent set of thread IDs
- std::vector<int32_t> mLastThreadIDs;
- std::optional<hal::SessionConfig> mSessionConfig;
+ std::vector<int32_t> mLastThreadIDs GUARDED_BY(sHintMutex);
+ std::optional<hal::SessionConfig> mSessionConfig GUARDED_BY(sHintMutex);
// Tracing helpers
- void traceThreads(std::vector<int32_t>& tids);
- void tracePowerEfficient(bool powerEfficient);
- void traceActualDuration(int64_t actualDuration);
- void traceBatchSize(size_t batchSize);
- void traceTargetDuration(int64_t targetDuration);
+ void traceThreads(std::vector<int32_t>& tids) REQUIRES(sHintMutex);
+ void tracePowerEfficient(bool powerEfficient) REQUIRES(sHintMutex);
+ void traceActualDuration(int64_t actualDuration) REQUIRES(sHintMutex);
+ void traceBatchSize(size_t batchSize) REQUIRES(sHintMutex);
+ void traceTargetDuration(int64_t targetDuration) REQUIRES(sHintMutex);
};
static std::shared_ptr<IHintManager>* gIHintManagerForTesting = nullptr;
diff --git a/native/android/thermal.cpp b/native/android/thermal.cpp
index b43f2f16..f7a3537 100644
--- a/native/android/thermal.cpp
+++ b/native/android/thermal.cpp
@@ -99,21 +99,21 @@
: mThermalSvc(std::move(service)), mServiceListener(nullptr) {}
AThermalManager::~AThermalManager() {
- std::unique_lock<std::mutex> listenerLock(mListenerMutex);
-
- mListeners.clear();
- if (mServiceListener != nullptr) {
- bool success = false;
- mThermalSvc->unregisterThermalStatusListener(mServiceListener, &success);
- mServiceListener = nullptr;
+ {
+ std::scoped_lock<std::mutex> listenerLock(mListenerMutex);
+ mListeners.clear();
+ if (mServiceListener != nullptr) {
+ bool success = false;
+ mThermalSvc->unregisterThermalStatusListener(mServiceListener, &success);
+ mServiceListener = nullptr;
+ }
}
- listenerLock.unlock();
- std::unique_lock<std::mutex> lock(mThresholdsMutex);
+ std::scoped_lock<std::mutex> lock(mThresholdsMutex);
delete[] mThresholds;
}
status_t AThermalManager::notifyStateChange(int32_t status) {
- std::unique_lock<std::mutex> lock(mListenerMutex);
+ std::scoped_lock<std::mutex> lock(mListenerMutex);
AThermalStatus thermalStatus = static_cast<AThermalStatus>(status);
for (auto listener : mListeners) {
@@ -123,7 +123,7 @@
}
status_t AThermalManager::addListener(AThermal_StatusCallback callback, void *data) {
- std::unique_lock<std::mutex> lock(mListenerMutex);
+ std::scoped_lock<std::mutex> lock(mListenerMutex);
if (callback == nullptr) {
// Callback can not be nullptr
@@ -157,7 +157,7 @@
}
status_t AThermalManager::removeListener(AThermal_StatusCallback callback, void *data) {
- std::unique_lock<std::mutex> lock(mListenerMutex);
+ std::scoped_lock<std::mutex> lock(mListenerMutex);
auto it = std::remove_if(mListeners.begin(),
mListeners.end(),
@@ -216,7 +216,7 @@
status_t AThermalManager::getThermalHeadroomThresholds(const AThermalHeadroomThreshold **result,
size_t *size) {
- std::unique_lock<std::mutex> lock(mThresholdsMutex);
+ std::scoped_lock<std::mutex> lock(mThresholdsMutex);
if (mThresholds == nullptr) {
auto thresholds = std::make_unique<std::vector<float>>();
binder::Status ret = mThermalSvc->getThermalHeadroomThresholds(thresholds.get());