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

Commit 83f04277 authored by Mikhail Naganov's avatar Mikhail Naganov
Browse files

audioflinger: Adjust priority of hal threads

HALs are prohibited from using framework binder, and there is
no equivalent scheduling policy service in hwbinder. Thus, in order
to match priorities of FastCapture / Mixer threads with their
counterparts in the HAL, it is needed to request the priority boost
from audioflinger on behalf of the HAL.

Test done to verify the priority was correctly set.

Bug: 34131400
Change-Id: If8b6b031c0fcba771fae901a5b8e7da89b3a1570
Test: check priority match between audioflinger's and hal's threads
parent ba05ff12
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -46,7 +46,8 @@ LOCAL_SHARED_LIBRARIES += \
    android.hardware.audio.common@2.0-util \
    android.hardware.audio.effect@2.0      \
    android.hidl.memory@1.0                \
    libmedia_helper
    libmedia_helper  \
    libmediautils

endif  # USE_LEGACY_LOCAL_AUDIO_HAL

+33 −7
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
//#define LOG_NDEBUG 0

#include <android/hardware/audio/2.0/IStreamOutCallback.h>
#include <mediautils/SchedulingPolicyService.h>
#include <utils/Log.h>

#include "DeviceHalHidl.h"
@@ -26,6 +27,7 @@

using ::android::hardware::audio::common::V2_0::AudioChannelMask;
using ::android::hardware::audio::common::V2_0::AudioFormat;
using ::android::hardware::audio::common::V2_0::ThreadInfo;
using ::android::hardware::audio::V2_0::AudioDrain;
using ::android::hardware::audio::V2_0::IStreamOutCallback;
using ::android::hardware::audio::V2_0::MessageQueueFlagBits;
@@ -33,7 +35,6 @@ using ::android::hardware::audio::V2_0::MmapBufferInfo;
using ::android::hardware::audio::V2_0::MmapPosition;
using ::android::hardware::audio::V2_0::ParameterValue;
using ::android::hardware::audio::V2_0::Result;
using ::android::hardware::audio::V2_0::ThreadPriority;
using ::android::hardware::audio::V2_0::TimeSpec;
using ::android::hardware::MQDescriptorSync;
using ::android::hardware::Return;
@@ -44,8 +45,8 @@ namespace android {

StreamHalHidl::StreamHalHidl(IStream *stream)
        : ConversionHelperHidl("Stream"),
          mHalThreadPriority(static_cast<int>(ThreadPriority::NORMAL)),
          mStream(stream) {
          mStream(stream),
          mHalThreadPriority(HAL_THREAD_PRIORITY_DEFAULT) {
}

StreamHalHidl::~StreamHalHidl() {
@@ -187,6 +188,19 @@ status_t StreamHalHidl::setHalThreadPriority(int priority) {
    return OK;
}

bool StreamHalHidl::requestHalThreadPriority(pid_t threadPid, pid_t threadId) {
    if (mHalThreadPriority == HAL_THREAD_PRIORITY_DEFAULT) {
        return true;
    }
    int err = requestPriority(
            threadPid, threadId,
            mHalThreadPriority, false /*isForApp*/, true /*asynchronous*/);
    ALOGE_IF(err, "failed to set priority %d for pid %d tid %d; error %d",
            mHalThreadPriority, threadPid, threadId, err);
    // Audio will still work, but latency will be higher and sometimes unacceptable.
    return err == 0;
}

namespace {

/* Notes on callback ownership.
@@ -352,12 +366,14 @@ status_t StreamOutHalHidl::prepareForWriting(size_t bufferSize) {
    std::unique_ptr<DataMQ> tempDataMQ;
    std::unique_ptr<StatusMQ> tempStatusMQ;
    Result retval;
    pid_t halThreadPid, halThreadTid;
    Return<void> ret = mStream->prepareForWriting(
            1, bufferSize, ThreadPriority(mHalThreadPriority),
            1, bufferSize,
            [&](Result r,
                    const CommandMQ::Descriptor& commandMQ,
                    const DataMQ::Descriptor& dataMQ,
                    const StatusMQ::Descriptor& statusMQ) {
                    const StatusMQ::Descriptor& statusMQ,
                    const ThreadInfo& halThreadInfo) {
                retval = r;
                if (retval == Result::OK) {
                    tempCommandMQ.reset(new CommandMQ(commandMQ));
@@ -366,6 +382,8 @@ status_t StreamOutHalHidl::prepareForWriting(size_t bufferSize) {
                    if (tempDataMQ->isValid() && tempDataMQ->getEventFlagWord()) {
                        EventFlag::createEventFlag(tempDataMQ->getEventFlagWord(), &mEfGroup);
                    }
                    halThreadPid = halThreadInfo.pid;
                    halThreadTid = halThreadInfo.tid;
                }
            });
    if (!ret.isOk() || retval != Result::OK) {
@@ -386,6 +404,8 @@ status_t StreamOutHalHidl::prepareForWriting(size_t bufferSize) {
        ALOGE_IF(!mEfGroup, "Event flag creation for writing failed");
        return NO_INIT;
    }
    requestHalThreadPriority(halThreadPid, halThreadTid);

    mCommandMQ = std::move(tempCommandMQ);
    mDataMQ = std::move(tempDataMQ);
    mStatusMQ = std::move(tempStatusMQ);
@@ -605,12 +625,14 @@ status_t StreamInHalHidl::prepareForReading(size_t bufferSize) {
    std::unique_ptr<DataMQ> tempDataMQ;
    std::unique_ptr<StatusMQ> tempStatusMQ;
    Result retval;
    pid_t halThreadPid, halThreadTid;
    Return<void> ret = mStream->prepareForReading(
            1, bufferSize, ThreadPriority(mHalThreadPriority),
            1, bufferSize,
            [&](Result r,
                    const CommandMQ::Descriptor& commandMQ,
                    const DataMQ::Descriptor& dataMQ,
                    const StatusMQ::Descriptor& statusMQ) {
                    const StatusMQ::Descriptor& statusMQ,
                    const ThreadInfo& halThreadInfo) {
                retval = r;
                if (retval == Result::OK) {
                    tempCommandMQ.reset(new CommandMQ(commandMQ));
@@ -619,6 +641,8 @@ status_t StreamInHalHidl::prepareForReading(size_t bufferSize) {
                    if (tempDataMQ->isValid() && tempDataMQ->getEventFlagWord()) {
                        EventFlag::createEventFlag(tempDataMQ->getEventFlagWord(), &mEfGroup);
                    }
                    halThreadPid = halThreadInfo.pid;
                    halThreadTid = halThreadInfo.tid;
                }
            });
    if (!ret.isOk() || retval != Result::OK) {
@@ -639,6 +663,8 @@ status_t StreamInHalHidl::prepareForReading(size_t bufferSize) {
        ALOGE_IF(!mEfGroup, "Event flag creation for reading failed");
        return NO_INIT;
    }
    requestHalThreadPriority(halThreadPid, halThreadTid);

    mCommandMQ = std::move(tempCommandMQ);
    mDataMQ = std::move(tempDataMQ);
    mStatusMQ = std::move(tempStatusMQ);
+3 −1
Original line number Diff line number Diff line
@@ -101,10 +101,12 @@ class StreamHalHidl : public virtual StreamHalInterface, public ConversionHelper
    // The destructor automatically closes the stream.
    virtual ~StreamHalHidl();

    int mHalThreadPriority;
    bool requestHalThreadPriority(pid_t threadPid, pid_t threadId);

  private:
    const int HAL_THREAD_PRIORITY_DEFAULT = -1;
    IStream *mStream;
    int mHalThreadPriority;
};

class StreamOutHalHidl : public StreamOutHalInterface, public StreamHalHidl {
+3 −1
Original line number Diff line number Diff line
@@ -37,13 +37,15 @@ public:
    {
    }

    virtual int requestPriority(int32_t pid, int32_t tid, int32_t prio, bool asynchronous)
    virtual int requestPriority(int32_t pid, int32_t tid,
                                int32_t prio, bool isForApp, bool asynchronous)
    {
        Parcel data, reply;
        data.writeInterfaceToken(ISchedulingPolicyService::getInterfaceDescriptor());
        data.writeInt32(pid);
        data.writeInt32(tid);
        data.writeInt32(prio);
        data.writeBool(isForApp);
        uint32_t flags = asynchronous ? IBinder::FLAG_ONEWAY : 0;
        status_t status = remote()->transact(REQUEST_PRIORITY_TRANSACTION, data, &reply, flags);
        if (status != NO_ERROR) {
+1 −1
Original line number Diff line number Diff line
@@ -27,7 +27,7 @@ public:
    DECLARE_META_INTERFACE(SchedulingPolicyService);

    virtual int         requestPriority(/*pid_t*/int32_t pid, /*pid_t*/int32_t tid,
                                                int32_t prio, bool asynchronous) = 0;
                                        int32_t prio, bool isForApp, bool asynchronous) = 0;

};

Loading