Add a mechanism to monitor execution time of incoming binder calls to audio flinger and audio policy and cause native audioserver restart in case of timeout. Bug: 69250055 Test: manual. audio smoke tests Change-Id: I01b5bf2599fb2a4cd265cbbe8d4e34b2b059aaf4gugelfrei
parent
12cc6e7a41
commit
3528c9330f
@ -0,0 +1 @@
|
|||||||
|
../../media/libmedia/include/media/TimeCheck.h
|
@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <media/TimeCheck.h>
|
||||||
|
|
||||||
|
namespace android {
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
sp<TimeCheck::TimeCheckThread> TimeCheck::getTimeCheckThread()
|
||||||
|
{
|
||||||
|
static sp<TimeCheck::TimeCheckThread> sTimeCheckThread = new TimeCheck::TimeCheckThread();
|
||||||
|
return sTimeCheckThread;
|
||||||
|
}
|
||||||
|
|
||||||
|
TimeCheck::TimeCheck(const char *tag, uint32_t timeoutMs)
|
||||||
|
: mEndTimeNs(getTimeCheckThread()->startMonitoring(tag, timeoutMs))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
TimeCheck::~TimeCheck() {
|
||||||
|
getTimeCheckThread()->stopMonitoring(mEndTimeNs);
|
||||||
|
}
|
||||||
|
|
||||||
|
TimeCheck::TimeCheckThread::~TimeCheckThread()
|
||||||
|
{
|
||||||
|
AutoMutex _l(mMutex);
|
||||||
|
requestExit();
|
||||||
|
mMonitorRequests.clear();
|
||||||
|
mCond.signal();
|
||||||
|
}
|
||||||
|
|
||||||
|
nsecs_t TimeCheck::TimeCheckThread::startMonitoring(const char *tag, uint32_t timeoutMs) {
|
||||||
|
Mutex::Autolock _l(mMutex);
|
||||||
|
nsecs_t endTimeNs = systemTime() + milliseconds(timeoutMs);
|
||||||
|
for (; mMonitorRequests.indexOfKey(endTimeNs) >= 0; ++endTimeNs);
|
||||||
|
mMonitorRequests.add(endTimeNs, tag);
|
||||||
|
mCond.signal();
|
||||||
|
return endTimeNs;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimeCheck::TimeCheckThread::stopMonitoring(nsecs_t endTimeNs) {
|
||||||
|
Mutex::Autolock _l(mMutex);
|
||||||
|
mMonitorRequests.removeItem(endTimeNs);
|
||||||
|
mCond.signal();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TimeCheck::TimeCheckThread::threadLoop()
|
||||||
|
{
|
||||||
|
status_t status = TIMED_OUT;
|
||||||
|
const char *tag;
|
||||||
|
{
|
||||||
|
AutoMutex _l(mMutex);
|
||||||
|
|
||||||
|
if (exitPending()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsecs_t endTimeNs = INT64_MAX;
|
||||||
|
// KeyedVector mMonitorRequests is ordered so take first entry as next timeout
|
||||||
|
if (mMonitorRequests.size() != 0) {
|
||||||
|
endTimeNs = mMonitorRequests.keyAt(0);
|
||||||
|
tag = mMonitorRequests.valueAt(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const nsecs_t waitTimeNs = endTimeNs - systemTime();
|
||||||
|
if (waitTimeNs > 0) {
|
||||||
|
status = mCond.waitRelative(mMutex, waitTimeNs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOG_ALWAYS_FATAL_IF(status != NO_ERROR, "TimeCheck timeout for %s", tag);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}; // namespace android
|
@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef ANDROID_TIME_CHECK_H
|
||||||
|
#define ANDROID_TIME_CHECK_H
|
||||||
|
|
||||||
|
#include <utils/KeyedVector.h>
|
||||||
|
#include <utils/Thread.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace android {
|
||||||
|
|
||||||
|
// A class monitoring execution time for a code block (scoped variable) and causing an assert
|
||||||
|
// if it exceeds a certain time
|
||||||
|
|
||||||
|
class TimeCheck {
|
||||||
|
public:
|
||||||
|
|
||||||
|
// The default timeout is chosen to be less than system server watchdog timeout
|
||||||
|
static constexpr uint32_t kDefaultTimeOutMs = 5000;
|
||||||
|
|
||||||
|
TimeCheck(const char *tag, uint32_t timeoutMs = kDefaultTimeOutMs);
|
||||||
|
~TimeCheck();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
class TimeCheckThread : public Thread {
|
||||||
|
public:
|
||||||
|
|
||||||
|
TimeCheckThread() {}
|
||||||
|
virtual ~TimeCheckThread() override;
|
||||||
|
|
||||||
|
nsecs_t startMonitoring(const char *tag, uint32_t timeoutMs);
|
||||||
|
void stopMonitoring(nsecs_t endTimeNs);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// RefBase
|
||||||
|
virtual void onFirstRef() override { run("TimeCheckThread", PRIORITY_URGENT_AUDIO); }
|
||||||
|
|
||||||
|
// Thread
|
||||||
|
virtual bool threadLoop() override;
|
||||||
|
|
||||||
|
Condition mCond;
|
||||||
|
Mutex mMutex;
|
||||||
|
// using the end time in ns as key is OK given the risk is low that two entries
|
||||||
|
// are added in such a way that <add time> + <timeout> are the same for both.
|
||||||
|
KeyedVector< nsecs_t, const char*> mMonitorRequests;
|
||||||
|
};
|
||||||
|
|
||||||
|
static sp<TimeCheckThread> getTimeCheckThread();
|
||||||
|
|
||||||
|
const nsecs_t mEndTimeNs;
|
||||||
|
};
|
||||||
|
|
||||||
|
}; // namespace android
|
||||||
|
|
||||||
|
#endif // ANDROID_TIME_CHECK_H
|
Loading…
Reference in new issue