diff --git a/audio/2.0/IStreamIn.hal b/audio/2.0/IStreamIn.hal index e34c95f4ef..6f1f9df7c1 100644 --- a/audio/2.0/IStreamIn.hal +++ b/audio/2.0/IStreamIn.hal @@ -91,7 +91,11 @@ interface IStreamIn extends IStream { * to the client; * -- status queue is used for reporting operation status * (e.g. amount of bytes actually read or error code). - * The driver operates on a dedicated thread. + * + * The driver operates on a dedicated thread. The client must ensure that + * the thread is given an appropriate priority and assigned to correct + * scheduler and cgroup. For this purpose, the method returns identifiers + * of the driver thread. * * @param frameSize the size of a single frame, in bytes. * @param framesCount the number of frames in a buffer. @@ -105,15 +109,15 @@ interface IStreamIn extends IStream { * specified at the stream opening. * @return statusMQ a message queue used for passing status from the driver * using ReadStatus structures. + * @return threadInfo identifiers of the driver's dedicated thread. */ - prepareForReading( - uint32_t frameSize, uint32_t framesCount, - ThreadPriority threadPriority) + prepareForReading(uint32_t frameSize, uint32_t framesCount) generates ( Result retval, fmq_sync commandMQ, fmq_sync dataMQ, - fmq_sync statusMQ); + fmq_sync statusMQ, + ThreadInfo threadInfo); /* * Return the amount of input frames lost in the audio driver since the last diff --git a/audio/2.0/IStreamOut.hal b/audio/2.0/IStreamOut.hal index 2ec080d029..9ee32c5be2 100644 --- a/audio/2.0/IStreamOut.hal +++ b/audio/2.0/IStreamOut.hal @@ -85,11 +85,14 @@ interface IStreamOut extends IStream { * to the driver; * -- status queue is used for reporting operation status * (e.g. amount of bytes actually written or error code). - * The driver operates on a dedicated thread. + * + * The driver operates on a dedicated thread. The client must ensure that + * the thread is given an appropriate priority and assigned to correct + * scheduler and cgroup. For this purpose, the method returns identifiers + * of the driver thread. * * @param frameSize the size of a single frame, in bytes. * @param framesCount the number of frames in a buffer. - * @param threadPriority priority of the driver thread. * @return retval OK if both message queues were created successfully. * INVALID_STATE if the method was already called. * INVALID_ARGUMENTS if there was a problem setting up @@ -99,15 +102,15 @@ interface IStreamOut extends IStream { * specified at the stream opening. * @return statusMQ a message queue used for passing status from the driver * using WriteStatus structures. + * @return threadInfo identifiers of the driver's dedicated thread. */ - prepareForWriting( - uint32_t frameSize, uint32_t framesCount, - ThreadPriority threadPriority) + prepareForWriting(uint32_t frameSize, uint32_t framesCount) generates ( Result retval, fmq_sync commandMQ, fmq_sync dataMQ, - fmq_sync statusMQ); + fmq_sync statusMQ, + ThreadInfo threadInfo); /* * Return the number of audio frames written by the audio DSP to DAC since diff --git a/audio/2.0/default/Android.mk b/audio/2.0/default/Android.mk index eeea92c217..cbeda359c9 100644 --- a/audio/2.0/default/Android.mk +++ b/audio/2.0/default/Android.mk @@ -38,7 +38,6 @@ LOCAL_SHARED_LIBRARIES := \ libhidltransport \ libhwbinder \ liblog \ - libmediautils \ libutils \ android.hardware.audio@2.0 \ android.hardware.audio.common@2.0 \ diff --git a/audio/2.0/default/StreamIn.cpp b/audio/2.0/default/StreamIn.cpp index 9c49170ef0..75bf3069aa 100644 --- a/audio/2.0/default/StreamIn.cpp +++ b/audio/2.0/default/StreamIn.cpp @@ -20,7 +20,6 @@ #include #include -#include #include #include "StreamIn.h" @@ -33,6 +32,8 @@ namespace audio { namespace V2_0 { namespace implementation { +using ::android::hardware::audio::common::V2_0::ThreadInfo; + namespace { class ReadThread : public Thread { @@ -43,8 +44,7 @@ class ReadThread : public Thread { StreamIn::CommandMQ* commandMQ, StreamIn::DataMQ* dataMQ, StreamIn::StatusMQ* statusMQ, - EventFlag* efGroup, - ThreadPriority threadPriority) + EventFlag* efGroup) : Thread(false /*canCallJava*/), mStop(stop), mStream(stream), @@ -52,13 +52,10 @@ class ReadThread : public Thread { mDataMQ(dataMQ), mStatusMQ(statusMQ), mEfGroup(efGroup), - mThreadPriority(threadPriority), mBuffer(new uint8_t[dataMQ->getQuantumCount()]) { } virtual ~ReadThread() {} - status_t readyToRun() override; - private: std::atomic* mStop; audio_stream_in_t* mStream; @@ -66,7 +63,6 @@ class ReadThread : public Thread { StreamIn::DataMQ* mDataMQ; StreamIn::StatusMQ* mStatusMQ; EventFlag* mEfGroup; - ThreadPriority mThreadPriority; std::unique_ptr mBuffer; IStreamIn::ReadParameters mParameters; IStreamIn::ReadStatus mStatus; @@ -77,16 +73,6 @@ class ReadThread : public Thread { void doRead(); }; -status_t ReadThread::readyToRun() { - if (mThreadPriority != ThreadPriority::NORMAL) { - int err = requestPriority( - getpid(), getTid(), static_cast(mThreadPriority), true /*asynchronous*/); - ALOGW_IF(err, "failed to set priority %d for pid %d tid %d; error %d", - static_cast(mThreadPriority), getpid(), getTid(), err); - } - return OK; -} - void ReadThread::doRead() { size_t availableToWrite = mDataMQ->availableToWrite(); size_t requestedToRead = mParameters.params.read; @@ -313,14 +299,14 @@ Return StreamIn::setGain(float gain) { } Return StreamIn::prepareForReading( - uint32_t frameSize, uint32_t framesCount, ThreadPriority threadPriority, - prepareForReading_cb _hidl_cb) { + uint32_t frameSize, uint32_t framesCount, prepareForReading_cb _hidl_cb) { status_t status; + ThreadInfo threadInfo = { 0, 0 }; // Create message queues. if (mDataMQ) { ALOGE("the client attempts to call prepareForReading twice"); _hidl_cb(Result::INVALID_STATE, - CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor()); + CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo); return Void(); } std::unique_ptr tempCommandMQ(new CommandMQ(1)); @@ -332,7 +318,7 @@ Return StreamIn::prepareForReading( ALOGE_IF(!tempDataMQ->isValid(), "data MQ is invalid"); ALOGE_IF(!tempStatusMQ->isValid(), "status MQ is invalid"); _hidl_cb(Result::INVALID_ARGUMENTS, - CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor()); + CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo); return Void(); } // TODO: Remove event flag management once blocking MQ is implemented. b/33815422 @@ -340,7 +326,7 @@ Return StreamIn::prepareForReading( if (status != OK || !mEfGroup) { ALOGE("failed creating event flag for data MQ: %s", strerror(-status)); _hidl_cb(Result::INVALID_ARGUMENTS, - CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor()); + CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo); return Void(); } @@ -351,20 +337,23 @@ Return StreamIn::prepareForReading( tempCommandMQ.get(), tempDataMQ.get(), tempStatusMQ.get(), - mEfGroup, - threadPriority); + mEfGroup); status = mReadThread->run("reader", PRIORITY_URGENT_AUDIO); if (status != OK) { ALOGW("failed to start reader thread: %s", strerror(-status)); _hidl_cb(Result::INVALID_ARGUMENTS, - CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor()); + CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo); return Void(); } mCommandMQ = std::move(tempCommandMQ); mDataMQ = std::move(tempDataMQ); mStatusMQ = std::move(tempStatusMQ); - _hidl_cb(Result::OK, *mCommandMQ->getDesc(), *mDataMQ->getDesc(), *mStatusMQ->getDesc()); + threadInfo.pid = getpid(); + threadInfo.tid = mReadThread->getTid(); + _hidl_cb(Result::OK, + *mCommandMQ->getDesc(), *mDataMQ->getDesc(), *mStatusMQ->getDesc(), + threadInfo); return Void(); } diff --git a/audio/2.0/default/StreamIn.h b/audio/2.0/default/StreamIn.h index 3566430392..b867387412 100644 --- a/audio/2.0/default/StreamIn.h +++ b/audio/2.0/default/StreamIn.h @@ -44,7 +44,6 @@ using ::android::hardware::audio::V2_0::IStream; using ::android::hardware::audio::V2_0::IStreamIn; using ::android::hardware::audio::V2_0::ParameterValue; using ::android::hardware::audio::V2_0::Result; -using ::android::hardware::audio::V2_0::ThreadPriority; using ::android::hardware::Return; using ::android::hardware::Void; using ::android::hardware::hidl_vec; @@ -89,8 +88,7 @@ struct StreamIn : public IStreamIn { Return getAudioSource(getAudioSource_cb _hidl_cb) override; Return setGain(float gain) override; Return prepareForReading( - uint32_t frameSize, uint32_t framesCount, ThreadPriority threadPriority, - prepareForReading_cb _hidl_cb) override; + uint32_t frameSize, uint32_t framesCount, prepareForReading_cb _hidl_cb) override; Return getInputFramesLost() override; Return getCapturePosition(getCapturePosition_cb _hidl_cb) override; Return start() override; diff --git a/audio/2.0/default/StreamOut.cpp b/audio/2.0/default/StreamOut.cpp index 6e46db23c6..4cd25aaa92 100644 --- a/audio/2.0/default/StreamOut.cpp +++ b/audio/2.0/default/StreamOut.cpp @@ -20,7 +20,6 @@ #include #include -#include #include #include "StreamOut.h" @@ -31,6 +30,8 @@ namespace audio { namespace V2_0 { namespace implementation { +using ::android::hardware::audio::common::V2_0::ThreadInfo; + namespace { class WriteThread : public Thread { @@ -41,8 +42,7 @@ class WriteThread : public Thread { StreamOut::CommandMQ* commandMQ, StreamOut::DataMQ* dataMQ, StreamOut::StatusMQ* statusMQ, - EventFlag* efGroup, - ThreadPriority threadPriority) + EventFlag* efGroup) : Thread(false /*canCallJava*/), mStop(stop), mStream(stream), @@ -50,13 +50,10 @@ class WriteThread : public Thread { mDataMQ(dataMQ), mStatusMQ(statusMQ), mEfGroup(efGroup), - mThreadPriority(threadPriority), mBuffer(new uint8_t[dataMQ->getQuantumCount()]) { } virtual ~WriteThread() {} - status_t readyToRun() override; - private: std::atomic* mStop; audio_stream_out_t* mStream; @@ -64,7 +61,6 @@ class WriteThread : public Thread { StreamOut::DataMQ* mDataMQ; StreamOut::StatusMQ* mStatusMQ; EventFlag* mEfGroup; - ThreadPriority mThreadPriority; std::unique_ptr mBuffer; IStreamOut::WriteStatus mStatus; @@ -75,16 +71,6 @@ class WriteThread : public Thread { void doWrite(); }; -status_t WriteThread::readyToRun() { - if (mThreadPriority != ThreadPriority::NORMAL) { - int err = requestPriority( - getpid(), getTid(), static_cast(mThreadPriority), true /*asynchronous*/); - ALOGW_IF(err, "failed to set priority %d for pid %d tid %d; error %d", - static_cast(mThreadPriority), getpid(), getTid(), err); - } - return OK; -} - void WriteThread::doWrite() { const size_t availToRead = mDataMQ->availableToRead(); mStatus.retval = Result::OK; @@ -297,14 +283,14 @@ Return StreamOut::setVolume(float left, float right) { } Return StreamOut::prepareForWriting( - uint32_t frameSize, uint32_t framesCount, ThreadPriority threadPriority, - prepareForWriting_cb _hidl_cb) { + uint32_t frameSize, uint32_t framesCount, prepareForWriting_cb _hidl_cb) { status_t status; + ThreadInfo threadInfo = { 0, 0 }; // Create message queues. if (mDataMQ) { ALOGE("the client attempts to call prepareForWriting twice"); _hidl_cb(Result::INVALID_STATE, - CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor()); + CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo); return Void(); } std::unique_ptr tempCommandMQ(new CommandMQ(1)); @@ -316,7 +302,7 @@ Return StreamOut::prepareForWriting( ALOGE_IF(!tempDataMQ->isValid(), "data MQ is invalid"); ALOGE_IF(!tempStatusMQ->isValid(), "status MQ is invalid"); _hidl_cb(Result::INVALID_ARGUMENTS, - CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor()); + CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo); return Void(); } // TODO: Remove event flag management once blocking MQ is implemented. b/33815422 @@ -324,7 +310,7 @@ Return StreamOut::prepareForWriting( if (status != OK || !mEfGroup) { ALOGE("failed creating event flag for data MQ: %s", strerror(-status)); _hidl_cb(Result::INVALID_ARGUMENTS, - CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor()); + CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo); return Void(); } @@ -335,20 +321,23 @@ Return StreamOut::prepareForWriting( tempCommandMQ.get(), tempDataMQ.get(), tempStatusMQ.get(), - mEfGroup, - threadPriority); + mEfGroup); status = mWriteThread->run("writer", PRIORITY_URGENT_AUDIO); if (status != OK) { ALOGW("failed to start writer thread: %s", strerror(-status)); _hidl_cb(Result::INVALID_ARGUMENTS, - CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor()); + CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo); return Void(); } mCommandMQ = std::move(tempCommandMQ); mDataMQ = std::move(tempDataMQ); mStatusMQ = std::move(tempStatusMQ); - _hidl_cb(Result::OK, *mCommandMQ->getDesc(), *mDataMQ->getDesc(), *mStatusMQ->getDesc()); + threadInfo.pid = getpid(); + threadInfo.tid = mWriteThread->getTid(); + _hidl_cb(Result::OK, + *mCommandMQ->getDesc(), *mDataMQ->getDesc(), *mStatusMQ->getDesc(), + threadInfo); return Void(); } diff --git a/audio/2.0/default/StreamOut.h b/audio/2.0/default/StreamOut.h index 661655759f..bbe64a1764 100644 --- a/audio/2.0/default/StreamOut.h +++ b/audio/2.0/default/StreamOut.h @@ -45,7 +45,6 @@ using ::android::hardware::audio::V2_0::IStreamOut; using ::android::hardware::audio::V2_0::IStreamOutCallback; 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::Return; using ::android::hardware::Void; @@ -91,8 +90,7 @@ struct StreamOut : public IStreamOut { Return getLatency() override; Return setVolume(float left, float right) override; Return prepareForWriting( - uint32_t frameSize, uint32_t framesCount, ThreadPriority threadPriority, - prepareForWriting_cb _hidl_cb) override; + uint32_t frameSize, uint32_t framesCount, prepareForWriting_cb _hidl_cb) override; Return getRenderPosition(getRenderPosition_cb _hidl_cb) override; Return getNextWriteTimestamp(getNextWriteTimestamp_cb _hidl_cb) override; Return setCallback(const sp& callback) override; diff --git a/audio/2.0/types.hal b/audio/2.0/types.hal index 8fc4314047..8e9ff1488e 100644 --- a/audio/2.0/types.hal +++ b/audio/2.0/types.hal @@ -98,12 +98,3 @@ enum MessageQueueFlagBits : uint32_t { NOT_EMPTY = 1 << 0, NOT_FULL = 1 << 1 }; - -/* - * The priority of threads executing reads and writes of audio data. - */ -enum ThreadPriority : int32_t { - NORMAL = 0, - FAST_CAPTURE = 3, - FAST_MIXER = 3 -}; diff --git a/audio/common/2.0/types.hal b/audio/common/2.0/types.hal index 63d66db92b..ae7f545a9a 100644 --- a/audio/common/2.0/types.hal +++ b/audio/common/2.0/types.hal @@ -933,3 +933,8 @@ struct AudioPort { AudioPortSessionExt session; } ext; }; + +struct ThreadInfo { + int64_t pid; + int64_t tid; +};