Snap for 8398296 from 2ea843a95ce9963af2f77def731c676d951a6c2f to udc-release
Change-Id: I5822bbe188001ddc7aa2fccb1fd54e191bb730ec
This commit is contained in:
commit
6a8912bbd6
@ -17,8 +17,6 @@
|
|||||||
#include "AocStateResidencyDataProvider.h"
|
#include "AocStateResidencyDataProvider.h"
|
||||||
|
|
||||||
#include <android-base/logging.h>
|
#include <android-base/logging.h>
|
||||||
#include <chrono>
|
|
||||||
#include <pthread.h>
|
|
||||||
|
|
||||||
namespace aidl {
|
namespace aidl {
|
||||||
namespace android {
|
namespace android {
|
||||||
@ -26,22 +24,12 @@ namespace hardware {
|
|||||||
namespace power {
|
namespace power {
|
||||||
namespace stats {
|
namespace stats {
|
||||||
|
|
||||||
struct async_data_t {
|
|
||||||
pthread_cond_t *cond;
|
|
||||||
pthread_mutex_t *lock;
|
|
||||||
std::unordered_map<std::string, std::vector<StateResidency>> *residencies;
|
|
||||||
std::unordered_map<std::string,
|
|
||||||
std::vector<std::unique_ptr<GenericStateResidencyDataProvider>>> *providers;
|
|
||||||
};
|
|
||||||
|
|
||||||
AocStateResidencyDataProvider::AocStateResidencyDataProvider(std::vector<std::pair<std::string,
|
AocStateResidencyDataProvider::AocStateResidencyDataProvider(std::vector<std::pair<std::string,
|
||||||
std::string>> ids, std::vector<std::pair<std::string, std::string>> states,
|
std::string>> ids, std::vector<std::pair<std::string, std::string>> states) {
|
||||||
const uint64_t timeoutMillis) {
|
|
||||||
// AoC stats are reported in ticks of 244.140625ns. The transform
|
// AoC stats are reported in ticks of 244.140625ns. The transform
|
||||||
// function converts ticks to milliseconds.
|
// function converts ticks to milliseconds.
|
||||||
// 1000000 / 244.140625 = 4096.
|
// 1000000 / 244.140625 = 4096.
|
||||||
static const uint64_t AOC_CLK = 4096;
|
static const uint64_t AOC_CLK = 4096;
|
||||||
static const uint64_t TIMEOUT_MILLIS = 120;
|
|
||||||
std::function<uint64_t(uint64_t)> aocTickToMs = [](uint64_t a) { return a / AOC_CLK; };
|
std::function<uint64_t(uint64_t)> aocTickToMs = [](uint64_t a) { return a / AOC_CLK; };
|
||||||
GenericStateResidencyDataProvider::StateResidencyConfig config = {
|
GenericStateResidencyDataProvider::StateResidencyConfig config = {
|
||||||
.entryCountSupported = true,
|
.entryCountSupported = true,
|
||||||
@ -66,16 +54,13 @@ AocStateResidencyDataProvider::AocStateResidencyDataProvider(std::vector<std::pa
|
|||||||
mProviders[id.first].push_back(std::move(sdp));
|
mProviders[id.first].push_back(std::move(sdp));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mStateCount = states.size();
|
|
||||||
mTimeoutMillis = timeoutMillis == 0 ? TIMEOUT_MILLIS : timeoutMillis;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void *getStateResidenciesAsync(void *arg) {
|
bool AocStateResidencyDataProvider::getStateResidencies(
|
||||||
struct async_data_t *async = (struct async_data_t*)arg;
|
std::unordered_map<std::string, std::vector<StateResidency>> *residencies) {
|
||||||
const auto *originalContainer = async->residencies;
|
|
||||||
|
|
||||||
// States from the same power entity are merged.
|
// States from the same power entity are merged.
|
||||||
for (const auto &providerList : *async->providers) {
|
bool ret = true;
|
||||||
|
for (const auto &providerList : mProviders) {
|
||||||
int32_t stateId = 0;
|
int32_t stateId = 0;
|
||||||
std::string curEntity = providerList.first;
|
std::string curEntity = providerList.first;
|
||||||
std::vector<StateResidency> stateResidencies;
|
std::vector<StateResidency> stateResidencies;
|
||||||
@ -83,7 +68,7 @@ void *getStateResidenciesAsync(void *arg) {
|
|||||||
// Iterate over each provider in the providerList, appending each of the states
|
// Iterate over each provider in the providerList, appending each of the states
|
||||||
for (const auto &provider : providerList.second) {
|
for (const auto &provider : providerList.second) {
|
||||||
std::unordered_map<std::string, std::vector<StateResidency>> residency;
|
std::unordered_map<std::string, std::vector<StateResidency>> residency;
|
||||||
provider->getStateResidencies(&residency);
|
ret &= provider->getStateResidencies(&residency);
|
||||||
|
|
||||||
// Each provider should only return data for curEntity but checking anyway
|
// Each provider should only return data for curEntity but checking anyway
|
||||||
if (residency.find(curEntity) != residency.end()) {
|
if (residency.find(curEntity) != residency.end()) {
|
||||||
@ -99,74 +84,8 @@ void *getStateResidenciesAsync(void *arg) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (async->residencies != originalContainer) {
|
residencies->emplace(curEntity, stateResidencies);
|
||||||
/*
|
|
||||||
* When provider->gretStateResidencies() exceeds timeout expiration, the main thread
|
|
||||||
* stops waiting and continue, then the original residency pointer is erased in the
|
|
||||||
* main thread when AocStateResidencyDataProvider::getStateResidencies() ends, and new
|
|
||||||
* container will be created in the async thread later. In this situation, we ignore
|
|
||||||
* delayed residency data and end the async thread.
|
|
||||||
*/
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async->residencies->emplace(curEntity, stateResidencies);
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_mutex_lock(async->lock);
|
|
||||||
pthread_cond_signal(async->cond);
|
|
||||||
pthread_mutex_unlock(async->lock);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AocStateResidencyDataProvider::getStateResidencies(
|
|
||||||
std::unordered_map<std::string, std::vector<StateResidency>> *residencies) {
|
|
||||||
bool ret = true;
|
|
||||||
int condResult = 0;
|
|
||||||
pthread_t tid;
|
|
||||||
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
|
|
||||||
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
|
|
||||||
std::unordered_map<std::string, std::vector<StateResidency>> stateResidencies;
|
|
||||||
struct timespec start, timeout;
|
|
||||||
struct async_data_t async = {
|
|
||||||
.cond = &cond,
|
|
||||||
.lock = &lock,
|
|
||||||
.residencies = &stateResidencies,
|
|
||||||
.providers = &mProviders
|
|
||||||
};
|
|
||||||
|
|
||||||
pthread_create(&tid, NULL, &getStateResidenciesAsync, (void*)&async);
|
|
||||||
|
|
||||||
clock_gettime(CLOCK_REALTIME, &start);
|
|
||||||
|
|
||||||
uint64_t expirationMillis = mTimeoutMillis * mStateCount;
|
|
||||||
timeout.tv_sec = start.tv_sec + expirationMillis / 1000;
|
|
||||||
uint64_t nsec = start.tv_nsec + (expirationMillis % 1000) * 1000000;
|
|
||||||
if (nsec < 1000000000) {
|
|
||||||
timeout.tv_nsec = nsec;
|
|
||||||
} else {
|
|
||||||
timeout.tv_sec += 1;
|
|
||||||
timeout.tv_nsec = nsec - 1000000000;
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_mutex_lock(&lock);
|
|
||||||
condResult = pthread_cond_timedwait(&cond, &lock, &timeout);
|
|
||||||
pthread_mutex_unlock(&lock);
|
|
||||||
|
|
||||||
if (condResult != 0) {
|
|
||||||
if (condResult == ETIMEDOUT) {
|
|
||||||
LOG(WARNING) << __func__ << " latency for AoC timeout: " << expirationMillis << " ms";
|
|
||||||
} else {
|
|
||||||
LOG(ERROR) << "Failed to wait for the condition variable: " << condResult;
|
|
||||||
}
|
|
||||||
ret = false;
|
|
||||||
} else {
|
|
||||||
for (const auto &residency : stateResidencies) {
|
|
||||||
residencies->emplace(residency.first, residency.second);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,8 +27,7 @@ namespace stats {
|
|||||||
class AocStateResidencyDataProvider : public PowerStats::IStateResidencyDataProvider {
|
class AocStateResidencyDataProvider : public PowerStats::IStateResidencyDataProvider {
|
||||||
public:
|
public:
|
||||||
AocStateResidencyDataProvider(std::vector<std::pair<std::string, std::string>> ids,
|
AocStateResidencyDataProvider(std::vector<std::pair<std::string, std::string>> ids,
|
||||||
std::vector<std::pair<std::string, std::string>> states,
|
std::vector<std::pair<std::string, std::string>> states);
|
||||||
const uint64_t timeoutMillis);
|
|
||||||
~AocStateResidencyDataProvider() = default;
|
~AocStateResidencyDataProvider() = default;
|
||||||
bool getStateResidencies(
|
bool getStateResidencies(
|
||||||
std::unordered_map<std::string, std::vector<StateResidency>> *residencies) override;
|
std::unordered_map<std::string, std::vector<StateResidency>> *residencies) override;
|
||||||
@ -37,8 +36,6 @@ class AocStateResidencyDataProvider : public PowerStats::IStateResidencyDataProv
|
|||||||
private:
|
private:
|
||||||
std::unordered_map<std::string /* entity name */,
|
std::unordered_map<std::string /* entity name */,
|
||||||
std::vector<std::unique_ptr<GenericStateResidencyDataProvider>> /* providers */> mProviders;
|
std::vector<std::unique_ptr<GenericStateResidencyDataProvider>> /* providers */> mProviders;
|
||||||
int32_t mStateCount;
|
|
||||||
uint64_t mTimeoutMillis;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace stats
|
} // namespace stats
|
||||||
|
Loading…
x
Reference in New Issue
Block a user