summaryrefslogtreecommitdiff
path: root/native
diff options
context:
space:
mode:
Diffstat (limited to 'native')
-rw-r--r--native/android/Android.bp1
-rw-r--r--native/android/performance_hint.cpp35
-rw-r--r--native/android/tests/performance_hint/PerformanceHintNativeTest.cpp4
-rw-r--r--native/android/thermal.cpp26
4 files changed, 39 insertions, 27 deletions
diff --git a/native/android/Android.bp b/native/android/Android.bp
index 8945bd1444f0..c4c41028f969 100644
--- a/native/android/Android.bp
+++ b/native/android/Android.bp
@@ -41,6 +41,7 @@ cc_defaults {
"-Wextra",
"-Wunused",
"-Wunreachable-code",
+ "-Wthread-safety",
],
}
diff --git a/native/android/performance_hint.cpp b/native/android/performance_hint.cpp
index 44fa677b59f7..e91c7a9ecda8 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 @@ private:
// 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;
@@ -243,6 +244,12 @@ int APerformanceHintSession::updateTargetWorkDuration(int64_t targetDurationNano
ALOGE("%s: targetDurationNanos must be positive", __FUNCTION__);
return EINVAL;
}
+ {
+ std::scoped_lock lock(sHintMutex);
+ if (mTargetDurationNanos == targetDurationNanos) {
+ return 0;
+ }
+ }
ndk::ScopedAStatus ret = mHintSession->updateTargetWorkDuration(targetDurationNanos);
if (!ret.isOk()) {
ALOGE("%s: HintSession updateTargetWorkDuration failed: %s", __FUNCTION__,
diff --git a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
index 78a53578f5ca..d19fa98f1171 100644
--- a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
+++ b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
@@ -159,6 +159,10 @@ TEST_F(PerformanceHintTest, TestSession) {
int result = APerformanceHint_updateTargetWorkDuration(session, targetDurationNanos);
EXPECT_EQ(0, result);
+ // subsequent call with same target should be ignored but return no error
+ result = APerformanceHint_updateTargetWorkDuration(session, targetDurationNanos);
+ EXPECT_EQ(0, result);
+
usleep(2); // Sleep for longer than preferredUpdateRateNanos.
int64_t actualDurationNanos = 20;
std::vector<int64_t> actualDurations;
diff --git a/native/android/thermal.cpp b/native/android/thermal.cpp
index b43f2f16a7cb..f7a3537d3f4a 100644
--- a/native/android/thermal.cpp
+++ b/native/android/thermal.cpp
@@ -99,21 +99,21 @@ AThermalManager::AThermalManager(sp<IThermalService> service)
: 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::notifyStateChange(int32_t status) {
}
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::addListener(AThermal_StatusCallback callback, void *da
}
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::getThermalHeadroom(int32_t forecastSeconds, float *res
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());