18daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes/*
28daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * Copyright (C) 2011 The Android Open Source Project
38daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes *
48daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
58daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * you may not use this file except in compliance with the License.
68daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * You may obtain a copy of the License at
78daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes *
88daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
98daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes *
108daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * Unless required by applicable law or agreed to in writing, software
118daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
128daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * See the License for the specific language governing permissions and
148daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * limitations under the License.
158daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes */
168daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
17fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#ifndef ART_RUNTIME_THREAD_LIST_H_
18fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#define ART_RUNTIME_THREAD_LIST_H_
198daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
2076b6167407c2b6f5d40ad895b2793a6b037f54b2Elliott Hughes#include "base/mutex.h"
212dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "root_visitor.h"
228daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
232dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include <bitset>
242dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include <list>
258daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
262dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace art {
272dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersclass Closure;
282dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersclass Thread;
297664f5cd118b355a5fe0c7536cb48ac991ed2b62Mathieu Chartierclass TimingLogger;
307664f5cd118b355a5fe0c7536cb48ac991ed2b62Mathieu Chartier
318daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughesclass ThreadList {
328daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes public:
338daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  static const uint32_t kMaxThreadId = 0xFFFF;
348daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  static const uint32_t kInvalidId = 0;
358daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  static const uint32_t kMainId = 1;
368daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
374dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes  explicit ThreadList();
388daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  ~ThreadList();
398daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
4000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  void DumpForSigQuit(std::ostream& os)
41b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      LOCKS_EXCLUDED(Locks::thread_list_lock_)
42b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
4300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  void DumpLocked(std::ostream& os)  // For thread suspend timeout dumps.
44b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_lock_)
45b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
467934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom  pid_t GetLockOwner();  // For SignalCatcher.
478daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
488d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes  // Thread suspension support.
4900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  void ResumeAll()
50b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      UNLOCK_FUNCTION(Locks::mutator_lock_)
51b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      LOCKS_EXCLUDED(Locks::thread_list_lock_,
52b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers                     Locks::thread_suspend_count_lock_);
5300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  void Resume(Thread* thread, bool for_debugger = false)
54b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_);
5500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
5600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Suspends all threads and gets exclusive access to the mutator_lock_.
5700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  void SuspendAll()
58b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      EXCLUSIVE_LOCK_FUNCTION(Locks::mutator_lock_)
59b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      LOCKS_EXCLUDED(Locks::thread_list_lock_,
60858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier                     Locks::thread_suspend_count_lock_);
61858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier
62858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier  // Run a checkpoint on threads, running threads are not suspended but run the checkpoint inside
63858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier  // of the suspend check. Returns how many checkpoints we should expect to run.
640e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier  size_t RunCheckpoint(Closure* checkpoint_function);
65858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier      LOCKS_EXCLUDED(Locks::thread_list_lock_,
66b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers                     Locks::thread_suspend_count_lock_);
6700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
6800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Suspends all threads
6900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  void SuspendAllForDebugger()
70b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      LOCKS_EXCLUDED(Locks::mutator_lock_,
71b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers                     Locks::thread_list_lock_,
72b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers                     Locks::thread_suspend_count_lock_);
7300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
7400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  void SuspendSelfForDebugger()
75b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_);
7600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
7700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  void UndoDebuggerSuspensions()
78b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      LOCKS_EXCLUDED(Locks::thread_list_lock_,
79b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers                     Locks::thread_suspend_count_lock_);
808daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
81f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes  // Iterates over all the threads.
8200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  void ForEach(void (*callback)(Thread*, void*), void* context)
83b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_lock_);
8447fce01c0f27dba716fa6b97242562fbc5c26eeaElliott Hughes
8500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Add/remove current thread from list.
8600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  void Register(Thread* self)
87120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers      EXCLUSIVE_LOCKS_REQUIRED(Locks::runtime_shutdown_lock_)
88120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers      LOCKS_EXCLUDED(Locks::mutator_lock_, Locks::thread_list_lock_);
89120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers  void Unregister(Thread* self) LOCKS_EXCLUDED(Locks::mutator_lock_, Locks::thread_list_lock_);
908daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
912dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  void VisitRoots(RootVisitor* visitor, void* arg) const
92b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
938daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
942dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  void VerifyRoots(VerifyRootVisitor* visitor, void* arg) const
956f1c94968ada57da433debf8e2d1b38a80ceb510Mathieu Chartier      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
966f1c94968ada57da433debf8e2d1b38a80ceb510Mathieu Chartier
9700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Return a copy of the thread list.
98b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers  std::list<Thread*> GetList() EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_lock_) {
9900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return list_;
10000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
10193e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes
102f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes  Thread* FindThreadByThinLockId(uint32_t thin_lock_id);
103f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes
1048daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes private:
105cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers  uint32_t AllocThreadId(Thread* self);
106cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers  void ReleaseThreadId(Thread* self, uint32_t id) LOCKS_EXCLUDED(allocated_ids_lock_);
107e52e49b32f5cf862a414da63e5dbd2eb04ad758eElliott Hughes
108b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers  bool Contains(Thread* thread) EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_lock_);
109b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers  bool Contains(pid_t tid) EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_lock_);
110abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes
11100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  void DumpUnattachedThreads(std::ostream& os)
112b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      LOCKS_EXCLUDED(Locks::thread_list_lock_);
113e52e49b32f5cf862a414da63e5dbd2eb04ad758eElliott Hughes
11400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  void SuspendAllDaemonThreads()
115b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      LOCKS_EXCLUDED(Locks::thread_list_lock_,
116b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers                     Locks::thread_suspend_count_lock_);
11700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  void WaitForOtherNonDaemonThreadsToExit()
118b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      LOCKS_EXCLUDED(Locks::thread_list_lock_,
119b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers                     Locks::thread_suspend_count_lock_);
1208daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
12150b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers  void AssertThreadsAreSuspended(Thread* self, Thread* ignore1, Thread* ignore2 = NULL)
122b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      LOCKS_EXCLUDED(Locks::thread_list_lock_,
123b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers                     Locks::thread_suspend_count_lock_);
124234ab15b00f8120282d1833e5d7480eca2e35a29Elliott Hughes
12500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  mutable Mutex allocated_ids_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
126f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes  std::bitset<kMaxThreadId> allocated_ids_ GUARDED_BY(allocated_ids_lock_);
127e52e49b32f5cf862a414da63e5dbd2eb04ad758eElliott Hughes
12800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // The actual list of all threads.
129b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers  std::list<Thread*> list_ GUARDED_BY(Locks::thread_list_lock_);
1308daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
13100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Ongoing suspend all requests, used to ensure threads added to list_ respect SuspendAll.
132b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers  int suspend_all_count_ GUARDED_BY(Locks::thread_suspend_count_lock_);
133b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers  int debug_suspend_all_count_ GUARDED_BY(Locks::thread_suspend_count_lock_);
1348d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes
13500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Signaled when threads terminate. Used to determine when all non-daemons have terminated.
136b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers  ConditionVariable thread_exit_cond_ GUARDED_BY(Locks::thread_list_lock_);
13793e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes
1388daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  friend class Thread;
1398daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
1408daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  DISALLOW_COPY_AND_ASSIGN(ThreadList);
1418daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes};
1428daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
1438daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes}  // namespace art
1448daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
145fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif  // ART_RUNTIME_THREAD_LIST_H_
146