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 "root_visitor.h"
     22 
     23 #include <bitset>
     24 #include <list>
     25 
     26 namespace art {
     27 class Closure;
     28 class Thread;
     29 class TimingLogger;
     30 
     31 class ThreadList {
     32  public:
     33   static const uint32_t kMaxThreadId = 0xFFFF;
     34   static const uint32_t kInvalidId = 0;
     35   static const uint32_t kMainId = 1;
     36 
     37   explicit ThreadList();
     38   ~ThreadList();
     39 
     40   void DumpForSigQuit(std::ostream& os)
     41       LOCKS_EXCLUDED(Locks::thread_list_lock_)
     42       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
     43   void DumpLocked(std::ostream& os)  // For thread suspend timeout dumps.
     44       EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_lock_)
     45       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
     46   pid_t GetLockOwner();  // For SignalCatcher.
     47 
     48   // Thread suspension support.
     49   void ResumeAll()
     50       UNLOCK_FUNCTION(Locks::mutator_lock_)
     51       LOCKS_EXCLUDED(Locks::thread_list_lock_,
     52                      Locks::thread_suspend_count_lock_);
     53   void Resume(Thread* thread, bool for_debugger = false)
     54       LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_);
     55 
     56   // Suspends all threads and gets exclusive access to the mutator_lock_.
     57   void SuspendAll()
     58       EXCLUSIVE_LOCK_FUNCTION(Locks::mutator_lock_)
     59       LOCKS_EXCLUDED(Locks::thread_list_lock_,
     60                      Locks::thread_suspend_count_lock_);
     61 
     62   // Run a checkpoint on threads, running threads are not suspended but run the checkpoint inside
     63   // of the suspend check. Returns how many checkpoints we should expect to run.
     64   size_t RunCheckpoint(Closure* checkpoint_function);
     65       LOCKS_EXCLUDED(Locks::thread_list_lock_,
     66                      Locks::thread_suspend_count_lock_);
     67 
     68   // Suspends all threads
     69   void SuspendAllForDebugger()
     70       LOCKS_EXCLUDED(Locks::mutator_lock_,
     71                      Locks::thread_list_lock_,
     72                      Locks::thread_suspend_count_lock_);
     73 
     74   void SuspendSelfForDebugger()
     75       LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_);
     76 
     77   void UndoDebuggerSuspensions()
     78       LOCKS_EXCLUDED(Locks::thread_list_lock_,
     79                      Locks::thread_suspend_count_lock_);
     80 
     81   // Iterates over all the threads.
     82   void ForEach(void (*callback)(Thread*, void*), void* context)
     83       EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_lock_);
     84 
     85   // Add/remove current thread from list.
     86   void Register(Thread* self)
     87       EXCLUSIVE_LOCKS_REQUIRED(Locks::runtime_shutdown_lock_)
     88       LOCKS_EXCLUDED(Locks::mutator_lock_, Locks::thread_list_lock_);
     89   void Unregister(Thread* self) LOCKS_EXCLUDED(Locks::mutator_lock_, Locks::thread_list_lock_);
     90 
     91   void VisitRoots(RootVisitor* visitor, void* arg) const
     92       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
     93 
     94   void VerifyRoots(VerifyRootVisitor* visitor, void* arg) const
     95       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
     96 
     97   // Return a copy of the thread list.
     98   std::list<Thread*> GetList() EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_lock_) {
     99     return list_;
    100   }
    101 
    102   Thread* FindThreadByThinLockId(uint32_t thin_lock_id);
    103 
    104  private:
    105   uint32_t AllocThreadId(Thread* self);
    106   void ReleaseThreadId(Thread* self, uint32_t id) LOCKS_EXCLUDED(allocated_ids_lock_);
    107 
    108   bool Contains(Thread* thread) EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_lock_);
    109   bool Contains(pid_t tid) EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_lock_);
    110 
    111   void DumpUnattachedThreads(std::ostream& os)
    112       LOCKS_EXCLUDED(Locks::thread_list_lock_);
    113 
    114   void SuspendAllDaemonThreads()
    115       LOCKS_EXCLUDED(Locks::thread_list_lock_,
    116                      Locks::thread_suspend_count_lock_);
    117   void WaitForOtherNonDaemonThreadsToExit()
    118       LOCKS_EXCLUDED(Locks::thread_list_lock_,
    119                      Locks::thread_suspend_count_lock_);
    120 
    121   void AssertThreadsAreSuspended(Thread* self, Thread* ignore1, Thread* ignore2 = NULL)
    122       LOCKS_EXCLUDED(Locks::thread_list_lock_,
    123                      Locks::thread_suspend_count_lock_);
    124 
    125   mutable Mutex allocated_ids_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
    126   std::bitset<kMaxThreadId> allocated_ids_ GUARDED_BY(allocated_ids_lock_);
    127 
    128   // The actual list of all threads.
    129   std::list<Thread*> list_ GUARDED_BY(Locks::thread_list_lock_);
    130 
    131   // Ongoing suspend all requests, used to ensure threads added to list_ respect SuspendAll.
    132   int suspend_all_count_ GUARDED_BY(Locks::thread_suspend_count_lock_);
    133   int debug_suspend_all_count_ GUARDED_BY(Locks::thread_suspend_count_lock_);
    134 
    135   // Signaled when threads terminate. Used to determine when all non-daemons have terminated.
    136   ConditionVariable thread_exit_cond_ GUARDED_BY(Locks::thread_list_lock_);
    137 
    138   friend class Thread;
    139 
    140   DISALLOW_COPY_AND_ASSIGN(ThreadList);
    141 };
    142 
    143 }  // namespace art
    144 
    145 #endif  // ART_RUNTIME_THREAD_LIST_H_
    146