Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7aac258a authored by Matt Buckley's avatar Matt Buckley
Browse files

Fix blocking call on FMQ critical path

Prevent fmq creation from blocking session creation and delaying
boosts on the critical path.

Bug: 315894228
Test: atest PerformanceHintNativeTestCases
Flag: android.os.adpf_use_fmq_channel_fixed

Change-Id: I7c431ab1b35bb3f1a3afb681e20054702e185d5f
parent b5219782
Loading
Loading
Loading
Loading
+26 −19
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@
#include <utils/SystemClock.h>

#include <chrono>
#include <future>
#include <set>
#include <utility>
#include <vector>
@@ -104,6 +105,7 @@ private:
    size_t mAvailableSlots GUARDED_BY(sHintMutex) = 0;
    bool mHalSupported = true;
    HalMessageQueue::MemTransaction mFmqTransaction GUARDED_BY(sHintMutex);
    std::future<bool> mChannelCreationFinished;
};

struct APerformanceHintManager {
@@ -218,6 +220,8 @@ APerformanceHintManager::~APerformanceHintManager() {
}

APerformanceHintManager* APerformanceHintManager::getInstance() {
    static std::once_flag creationFlag;
    static APerformanceHintManager* instance = nullptr;
    if (gHintManagerForTesting) {
        return gHintManagerForTesting.get();
    }
@@ -226,7 +230,7 @@ APerformanceHintManager* APerformanceHintManager::getInstance() {
                std::shared_ptr<APerformanceHintManager>(create(*gIHintManagerForTesting));
        return gHintManagerForTesting.get();
    }
    static APerformanceHintManager* instance = create(nullptr);
    std::call_once(creationFlag, []() { instance = create(nullptr); });
    return instance;
}

@@ -522,7 +526,8 @@ bool FMQWrapper::isSupported() {
}

bool FMQWrapper::startChannel(IHintManager* manager) {
    if (isSupported() && !isActive()) {
    if (isSupported() && !isActive() && manager->isRemote()) {
        mChannelCreationFinished = std::async(std::launch::async, [&, this, manager]() {
            std::optional<hal::ChannelConfig> config;
            auto ret = manager->getSessionChannel(mToken, &config);
            if (ret.isOk() && config.has_value()) {
@@ -541,6 +546,8 @@ bool FMQWrapper::startChannel(IHintManager* manager) {
            } else {
                ALOGE("%s: FMQ channel initialization failed: %s", __FUNCTION__, ret.getMessage());
            }
            return true;
        });
    }
    return isActive();
}