blob: 878ae8c7a0c950afd6ff3b61f949a5ce573f5ac4 [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>
20
Marco Nelissencf90b492019-09-26 11:20:54 -070021#include <mediautils/EventLog.h>
Ytai Ben-Tsvi1ea62c92021-11-10 14:38:27 -080022#include <mediautils/TimeCheck.h>
23#include <utils/Log.h>
Eric Laurent42896a02019-09-27 15:40:33 -070024#include "debuggerd/handler.h"
Eric Laurent3528c932018-02-23 17:17:22 -080025
26namespace android {
27
Eric Laurent42896a02019-09-27 15:40:33 -070028// Audio HAL server pids vector used to generate audio HAL processes tombstone
29// when audioserver watchdog triggers.
30// We use a lockless storage to avoid potential deadlocks in the context of watchdog
31// trigger.
32// Protection again simultaneous writes is not needed given one update takes place
33// during AudioFlinger construction and other comes necessarily later once the IAudioFlinger
34// interface is available.
35// The use of an atomic index just guaranties that current vector is fully initialized
36// when read.
37/* static */
38void TimeCheck::accessAudioHalPids(std::vector<pid_t>* pids, bool update) {
39 static constexpr int kNumAudioHalPidsVectors = 3;
40 static std::vector<pid_t> audioHalPids[kNumAudioHalPidsVectors];
41 static std::atomic<int> curAudioHalPids = 0;
42
43 if (update) {
Eric Laurent1ad278b2021-03-05 18:09:01 +010044 audioHalPids[(curAudioHalPids++ + 1) % kNumAudioHalPidsVectors] = *pids;
Eric Laurent42896a02019-09-27 15:40:33 -070045 } else {
Eric Laurent1ad278b2021-03-05 18:09:01 +010046 *pids = audioHalPids[curAudioHalPids % kNumAudioHalPidsVectors];
Eric Laurent42896a02019-09-27 15:40:33 -070047 }
48}
49
50/* static */
51void TimeCheck::setAudioHalPids(const std::vector<pid_t>& pids) {
52 accessAudioHalPids(&(const_cast<std::vector<pid_t>&>(pids)), true);
53}
54
55/* static */
56std::vector<pid_t> TimeCheck::getAudioHalPids() {
57 std::vector<pid_t> pids;
58 accessAudioHalPids(&pids, false);
59 return pids;
60}
61
Eric Laurent3528c932018-02-23 17:17:22 -080062/* static */
Ytai Ben-Tsvi1ea62c92021-11-10 14:38:27 -080063TimerThread* TimeCheck::getTimeCheckThread() {
64 static TimerThread* sTimeCheckThread = new TimerThread();
Eric Laurent3528c932018-02-23 17:17:22 -080065 return sTimeCheckThread;
66}
67
Ytai Ben-Tsvi1ea62c92021-11-10 14:38:27 -080068TimeCheck::TimeCheck(const char* tag, uint32_t timeoutMs)
69 : mTimerHandle(getTimeCheckThread()->scheduleTask([tag] { crash(tag); },
70 std::chrono::milliseconds(timeoutMs))) {}
Eric Laurent3528c932018-02-23 17:17:22 -080071
72TimeCheck::~TimeCheck() {
Ytai Ben-Tsvi1ea62c92021-11-10 14:38:27 -080073 getTimeCheckThread()->cancelTask(mTimerHandle);
Eric Laurent3528c932018-02-23 17:17:22 -080074}
75
Ytai Ben-Tsvi1ea62c92021-11-10 14:38:27 -080076/* static */
77void TimeCheck::crash(const char* tag) {
78 // Generate audio HAL processes tombstones and allow time to complete
79 // before forcing restart
80 std::vector<pid_t> pids = getAudioHalPids();
81 if (pids.size() != 0) {
82 for (const auto& pid : pids) {
83 ALOGI("requesting tombstone for pid: %d", pid);
84 sigqueue(pid, DEBUGGER_SIGNAL, {.sival_int = 0});
Eric Laurent3528c932018-02-23 17:17:22 -080085 }
Ytai Ben-Tsvi1ea62c92021-11-10 14:38:27 -080086 sleep(1);
87 } else {
88 ALOGI("No HAL process pid available, skipping tombstones");
Eric Laurent39b09b52018-06-29 12:24:40 -070089 }
Ytai Ben-Tsvi1ea62c92021-11-10 14:38:27 -080090 LOG_EVENT_STRING(LOGTAG_AUDIO_BINDER_TIMEOUT, tag);
91 LOG_ALWAYS_FATAL("TimeCheck timeout for %s", tag);
Eric Laurent3528c932018-02-23 17:17:22 -080092}
93
Ytai Ben-Tsvi1ea62c92021-11-10 14:38:27 -080094}; // namespace android