blob: 2b765cc22bf8720bff83f5188e2599b8bfbeef9e [file] [log] [blame]
Eric Laurent3528c932018-02-23 17:17:22 -08001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Eric Laurent42896a02019-09-27 15:40:33 -070017#define LOG_TAG "TimeCheck"
Eric Laurent3528c932018-02-23 17:17:22 -080018
Ytai Ben-Tsvi1ea62c92021-11-10 14:38:27 -080019#include <optional>
Ytai Ben-Tsvi34f26b12021-12-02 13:58:38 -080020#include <sstream>
Ytai Ben-Tsvi1ea62c92021-11-10 14:38:27 -080021
Marco Nelissencf90b492019-09-26 11:20:54 -070022#include <mediautils/EventLog.h>
Ytai Ben-Tsvi1ea62c92021-11-10 14:38:27 -080023#include <mediautils/TimeCheck.h>
24#include <utils/Log.h>
Eric Laurent42896a02019-09-27 15:40:33 -070025#include "debuggerd/handler.h"
Eric Laurent3528c932018-02-23 17:17:22 -080026
27namespace android {
28
Ytai Ben-Tsvi34f26b12021-12-02 13:58:38 -080029namespace {
30
31std::string formatTime(std::chrono::system_clock::time_point t) {
32 auto msSinceEpoch = std::chrono::round<std::chrono::milliseconds>(t.time_since_epoch());
33 return (std::ostringstream() << msSinceEpoch.count()).str();
34}
35
36} // namespace
37
Eric Laurent42896a02019-09-27 15:40:33 -070038// Audio HAL server pids vector used to generate audio HAL processes tombstone
39// when audioserver watchdog triggers.
40// We use a lockless storage to avoid potential deadlocks in the context of watchdog
41// trigger.
42// Protection again simultaneous writes is not needed given one update takes place
43// during AudioFlinger construction and other comes necessarily later once the IAudioFlinger
44// interface is available.
45// The use of an atomic index just guaranties that current vector is fully initialized
46// when read.
47/* static */
48void TimeCheck::accessAudioHalPids(std::vector<pid_t>* pids, bool update) {
49 static constexpr int kNumAudioHalPidsVectors = 3;
50 static std::vector<pid_t> audioHalPids[kNumAudioHalPidsVectors];
51 static std::atomic<int> curAudioHalPids = 0;
52
53 if (update) {
Eric Laurent1ad278b2021-03-05 18:09:01 +010054 audioHalPids[(curAudioHalPids++ + 1) % kNumAudioHalPidsVectors] = *pids;
Eric Laurent42896a02019-09-27 15:40:33 -070055 } else {
Eric Laurent1ad278b2021-03-05 18:09:01 +010056 *pids = audioHalPids[curAudioHalPids % kNumAudioHalPidsVectors];
Eric Laurent42896a02019-09-27 15:40:33 -070057 }
58}
59
60/* static */
61void TimeCheck::setAudioHalPids(const std::vector<pid_t>& pids) {
62 accessAudioHalPids(&(const_cast<std::vector<pid_t>&>(pids)), true);
63}
64
65/* static */
66std::vector<pid_t> TimeCheck::getAudioHalPids() {
67 std::vector<pid_t> pids;
68 accessAudioHalPids(&pids, false);
69 return pids;
70}
71
Eric Laurent3528c932018-02-23 17:17:22 -080072/* static */
Ytai Ben-Tsvi1ea62c92021-11-10 14:38:27 -080073TimerThread* TimeCheck::getTimeCheckThread() {
74 static TimerThread* sTimeCheckThread = new TimerThread();
Eric Laurent3528c932018-02-23 17:17:22 -080075 return sTimeCheckThread;
76}
77
Ytai Ben-Tsvi1ea62c92021-11-10 14:38:27 -080078TimeCheck::TimeCheck(const char* tag, uint32_t timeoutMs)
Ytai Ben-Tsvi34f26b12021-12-02 13:58:38 -080079 : mTimerHandle(getTimeCheckThread()->scheduleTask(
80 [tag, startTime = std::chrono::system_clock::now()] { crash(tag, startTime); },
81 std::chrono::milliseconds(timeoutMs))) {}
Eric Laurent3528c932018-02-23 17:17:22 -080082
83TimeCheck::~TimeCheck() {
Ytai Ben-Tsvi1ea62c92021-11-10 14:38:27 -080084 getTimeCheckThread()->cancelTask(mTimerHandle);
Eric Laurent3528c932018-02-23 17:17:22 -080085}
86
Ytai Ben-Tsvi1ea62c92021-11-10 14:38:27 -080087/* static */
Ytai Ben-Tsvi34f26b12021-12-02 13:58:38 -080088void TimeCheck::crash(const char* tag, std::chrono::system_clock::time_point startTime) {
89 std::chrono::system_clock::time_point endTime = std::chrono::system_clock::now();
90
Ytai Ben-Tsvi1ea62c92021-11-10 14:38:27 -080091 // Generate audio HAL processes tombstones and allow time to complete
92 // before forcing restart
93 std::vector<pid_t> pids = getAudioHalPids();
94 if (pids.size() != 0) {
95 for (const auto& pid : pids) {
96 ALOGI("requesting tombstone for pid: %d", pid);
97 sigqueue(pid, DEBUGGER_SIGNAL, {.sival_int = 0});
Eric Laurent3528c932018-02-23 17:17:22 -080098 }
Ytai Ben-Tsvi1ea62c92021-11-10 14:38:27 -080099 sleep(1);
100 } else {
101 ALOGI("No HAL process pid available, skipping tombstones");
Eric Laurent39b09b52018-06-29 12:24:40 -0700102 }
Ytai Ben-Tsvi1ea62c92021-11-10 14:38:27 -0800103 LOG_EVENT_STRING(LOGTAG_AUDIO_BINDER_TIMEOUT, tag);
Ytai Ben-Tsvi34f26b12021-12-02 13:58:38 -0800104 LOG_ALWAYS_FATAL("TimeCheck timeout for %s (start=%s, end=%s)", tag,
105 formatTime(startTime).c_str(), formatTime(endTime).c_str());
Eric Laurent3528c932018-02-23 17:17:22 -0800106}
107
Ytai Ben-Tsvi1ea62c92021-11-10 14:38:27 -0800108}; // namespace android