Home | History | Annotate | Download | only in runtime
      1 /*
      2  * Copyright (C) 2011 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 
     17 #ifndef ART_RUNTIME_THREAD_LIST_H_
     18 #define ART_RUNTIME_THREAD_LIST_H_
     19 
     20 #include "base/mutex.h"
     21 #include "gc_root.h"
     22 #include "jni.h"
     23 #include "object_callbacks.h"
     24 
     25 #include <bitset>
     26 #include <list>
     27 
     28 namespace art {
     29 class Closure;
     30 class Thread;
     31 class TimingLogger;
     32 
     33 class ThreadList {
     34  public:
     35   static const uint32_t kMaxThreadId = 0xFFFF;
     36   static const uint32_t kInvalidThreadId = 0;
     37   static const uint32_t kMainThreadId = 1;
     38 
     39   explicit ThreadList();
     40   ~ThreadList();
     41 
     42   void DumpForSigQuit(std::ostream& os)
     43       LOCKS_EXCLUDED(Locks::thread_list_lock_)
     44       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
     45   void DumpLocked(std::ostream& os)  // For thread suspend timeout dumps.
     46       EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_lock_)
     47       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
     48   pid_t GetLockOwner();  // For SignalCatcher.
     49 
     50   // Thread suspension support.
     51   void ResumeAll()
     52       UNLOCK_FUNCTION(Locks::mutator_lock_)
     53       LOCKS_EXCLUDED(Locks::thread_list_lock_,
     54                      Locks::thread_suspend_count_lock_);
     55   void Resume(Thread* thread, bool for_debugger = false)
     56       LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_);
     57 
     58   // Suspends all threads and gets exclusive access to the mutator_lock_.
     59   void SuspendAll()
     60       EXCLUSIVE_LOCK_FUNCTION(Locks::mutator_lock_)
     61       LOCKS_EXCLUDED(Locks::thread_list_lock_,
     62                      Locks::thread_suspend_count_lock_);
     63 
     64 
     65   // Suspend a thread using a peer, typically used by the debugger. Returns the thread on success,
     66   // else NULL. The peer is used to identify the thread to avoid races with the thread terminating.
     67   // If the thread should be suspended then value of request_suspension should be true otherwise
     68   // the routine will wait for a previous suspend request. If the suspension times out then *timeout
     69   // is set to true.
     70   Thread* SuspendThreadByPeer(jobject peer, bool request_suspension, bool debug_suspension,
     71                               bool* timed_out)
     72       EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_suspend_thread_lock_)
     73       LOCKS_EXCLUDED(Locks::mutator_lock_,
     74                      Locks::thread_list_lock_,
     75                      Locks::thread_suspend_count_lock_);
     76 
     77   // Suspend a thread using its thread id, typically used by lock/monitor inflation. Returns the
     78   // thread on success else NULL. The thread id is used to identify the thread to avoid races with
     79   // the thread terminating. Note that as thread ids are recycled this may not suspend the expected
     80   // thread, that may be terminating. If the suspension times out then *timeout is set to true.
     81   Thread* SuspendThreadByThreadId(uint32_t thread_id, bool debug_suspension, bool* timed_out)
     82       EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_suspend_thread_lock_)
     83       LOCKS_EXCLUDED(Locks::mutator_lock_,
     84                      Locks::thread_list_lock_,
     85                      Locks::thread_suspend_count_lock_);
     86 
     87   // Find an already suspended thread (or self) by its id.
     88   Thread* FindThreadByThreadId(uint32_t thin_lock_id);
     89 
     90   // Run a checkpoint on threads, running threads are not suspended but run the checkpoint inside
     91   // of the suspend check. Returns how many checkpoints we should expect to run.
     92   size_t RunCheckpoint(Closure* checkpoint_function)
     93       LOCKS_EXCLUDED(Locks::thread_list_lock_,
     94                      Locks::thread_suspend_count_lock_);
     95 
     96   size_t RunCheckpointOnRunnableThreads(Closure* checkpoint_function)
     97       LOCKS_EXCLUDED(Locks::thread_list_lock_, Locks::thread_suspend_count_lock_);
     98 
     99   // Suspends all threads
    100   void SuspendAllForDebugger()
    101       LOCKS_EXCLUDED(Locks::mutator_lock_,
    102                      Locks::thread_list_lock_,
    103                      Locks::thread_suspend_count_lock_);
    104 
    105   void SuspendSelfForDebugger()
    106       LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_);
    107 
    108   // Resume all threads
    109   void ResumeAllForDebugger()
    110       LOCKS_EXCLUDED(Locks::thread_list_lock_,
    111                      Locks::thread_suspend_count_lock_);
    112 
    113   void UndoDebuggerSuspensions()
    114       LOCKS_EXCLUDED(Locks::thread_list_lock_,
    115                      Locks::thread_suspend_count_lock_);
    116 
    117   // Iterates over all the threads.
    118   void ForEach(void (*callback)(Thread*, void*), void* context)
    119       EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_lock_);
    120 
    121   // Add/remove current thread from list.
    122   void Register(Thread* self)
    123       EXCLUSIVE_LOCKS_REQUIRED(Locks::runtime_shutdown_lock_)
    124       LOCKS_EXCLUDED(Locks::mutator_lock_, Locks::thread_list_lock_);
    125   void Unregister(Thread* self) LOCKS_EXCLUDED(Locks::mutator_lock_, Locks::thread_list_lock_);
    126 
    127   void VisitRoots(RootCallback* callback, void* arg) const
    128       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    129 
    130   // Return a copy of the thread list.
    131   std::list<Thread*> GetList() EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_lock_) {
    132     return list_;
    133   }
    134 
    135   void DumpNativeStacks(std::ostream& os)
    136       LOCKS_EXCLUDED(Locks::thread_list_lock_);
    137 
    138  private:
    139   uint32_t AllocThreadId(Thread* self);
    140   void ReleaseThreadId(Thread* self, uint32_t id) LOCKS_EXCLUDED(Locks::allocated_thread_ids_lock_);
    141 
    142   bool Contains(Thread* thread) EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_lock_);
    143   bool Contains(pid_t tid) EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_lock_);
    144 
    145   void DumpUnattachedThreads(std::ostream& os)
    146       LOCKS_EXCLUDED(Locks::thread_list_lock_);
    147 
    148   void SuspendAllDaemonThreads()
    149       LOCKS_EXCLUDED(Locks::thread_list_lock_,
    150                      Locks::thread_suspend_count_lock_);
    151   void WaitForOtherNonDaemonThreadsToExit()
    152       LOCKS_EXCLUDED(Locks::thread_list_lock_,
    153                      Locks::thread_suspend_count_lock_);
    154 
    155   void AssertThreadsAreSuspended(Thread* self, Thread* ignore1, Thread* ignore2 = NULL)
    156       LOCKS_EXCLUDED(Locks::thread_list_lock_,
    157                      Locks::thread_suspend_count_lock_);
    158 
    159   std::bitset<kMaxThreadId> allocated_ids_ GUARDED_BY(Locks::allocated_thread_ids_lock_);
    160 
    161   // The actual list of all threads.
    162   std::list<Thread*> list_ GUARDED_BY(Locks::thread_list_lock_);
    163 
    164   // Ongoing suspend all requests, used to ensure threads added to list_ respect SuspendAll.
    165   int suspend_all_count_ GUARDED_BY(Locks::thread_suspend_count_lock_);
    166   int debug_suspend_all_count_ GUARDED_BY(Locks::thread_suspend_count_lock_);
    167 
    168   // Signaled when threads terminate. Used to determine when all non-daemons have terminated.
    169   ConditionVariable thread_exit_cond_ GUARDED_BY(Locks::thread_list_lock_);
    170 
    171   friend class Thread;
    172 
    173   DISALLOW_COPY_AND_ASSIGN(ThreadList);
    174 };
    175 
    176 }  // namespace art
    177 
    178 #endif  // ART_RUNTIME_THREAD_LIST_H_
    179