• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #ifndef PANDA_RUNTIME_LOCK_ORDER_GRAPH_H_
16 #define PANDA_RUNTIME_LOCK_ORDER_GRAPH_H_
17 
18 #include <bitset>
19 
20 #include "libpandabase/os/mutex.h"
21 #include "runtime/include/mem/panda_containers.h"
22 #include "runtime/include/thread.h"
23 #include "runtime/include/thread_status.h"
24 
25 namespace panda::mem::test {
26 class LockOrderGraphTest;
27 }  // namespace panda::mem::test
28 
29 namespace panda {
30 // This class is required to find a loop in lock order graph to detect a deadlock.
31 class LockOrderGraph {
32 public:
33     using ThreadId = ManagedThread::ThreadId;
34     using MonitorId = Monitor::MonitorId;
35     static bool CheckForTerminationLoops(const PandaList<MTManagedThread *> &threads,
36                                          const PandaList<MTManagedThread *> &daemon_threads, MTManagedThread *current);
37 
38     bool CheckForTerminationLoops() const;
39 
40     DEFAULT_MOVE_SEMANTIC(LockOrderGraph);
41     DEFAULT_COPY_SEMANTIC(LockOrderGraph);
42 
43     ~LockOrderGraph() = default;
44 
45 private:
LockOrderGraph(PandaMap<ThreadId,bool> nodes,PandaMap<ThreadId,ThreadId> edges)46     LockOrderGraph(PandaMap<ThreadId, bool> nodes, PandaMap<ThreadId, ThreadId> edges)
47     {
48         nodes_ = std::move(nodes);
49         edges_ = std::move(edges);
50         for (auto const &edge : edges_) {
51             if (nodes_[edge.second]) {
52                 LOG(DEBUG, RUNTIME) << "Edge in LockOrderGraph: " << edge.first << " -> " << edge.second << " [T]";
53             } else {
54                 LOG(DEBUG, RUNTIME) << "Edge in LockOrderGraph: " << edge.first << " -> " << edge.second;
55             }
56         }
57     }
58     PandaMap<ThreadId, bool> nodes_;
59     PandaMap<ThreadId, ThreadId> edges_;
60 
61     friend class panda::mem::test::LockOrderGraphTest;
62 };
63 }  // namespace panda
64 
65 #endif  // PANDA_RUNTIME_THREAD_MANAGER_H_
66