/* * Copyright (c) 2022-2022 Huawei Device Co., Ltd. * 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 PANDA_RUNTIME_LOCK_ORDER_GRAPH_H_ #define PANDA_RUNTIME_LOCK_ORDER_GRAPH_H_ #include #include "libpandabase/os/mutex.h" #include "runtime/include/mem/panda_containers.h" #include "runtime/include/thread.h" #include "runtime/include/thread_status.h" namespace panda::mem::test { class LockOrderGraphTest; } // namespace panda::mem::test namespace panda { // This class is required to find a loop in lock order graph to detect a deadlock. class LockOrderGraph { public: using ThreadId = ManagedThread::ThreadId; using MonitorId = Monitor::MonitorId; static bool CheckForTerminationLoops(const PandaList &threads, const PandaList &daemon_threads, MTManagedThread *current); bool CheckForTerminationLoops() const; DEFAULT_MOVE_SEMANTIC(LockOrderGraph); DEFAULT_COPY_SEMANTIC(LockOrderGraph); ~LockOrderGraph() = default; private: LockOrderGraph(PandaMap nodes, PandaMap edges) { nodes_ = std::move(nodes); edges_ = std::move(edges); for (auto const &edge : edges_) { if (nodes_[edge.second]) { LOG(DEBUG, RUNTIME) << "Edge in LockOrderGraph: " << edge.first << " -> " << edge.second << " [T]"; } else { LOG(DEBUG, RUNTIME) << "Edge in LockOrderGraph: " << edge.first << " -> " << edge.second; } } } PandaMap nodes_; PandaMap edges_; friend class panda::mem::test::LockOrderGraphTest; }; } // namespace panda #endif // PANDA_RUNTIME_THREAD_MANAGER_H_