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 "barrier.h"
     21 #include "base/histogram.h"
     22 #include "base/mutex.h"
     23 #include "base/time_utils.h"
     24 #include "base/value_object.h"
     25 #include "gc_root.h"
     26 #include "jni.h"
     27 #include "object_callbacks.h"
     28 
     29 #include <bitset>
     30 #include <list>
     31 #include <vector>
     32 
     33 namespace art {
     34 namespace gc {
     35   namespace collector {
     36     class GarbageCollector;
     37   }  // namespac collector
     38 }  // namespace gc
     39 class Closure;
     40 class Thread;
     41 class TimingLogger;
     42 
     43 class ThreadList {
     44  public:
     45   static constexpr uint32_t kMaxThreadId = 0xFFFF;
     46   static constexpr uint32_t kInvalidThreadId = 0;
     47   static constexpr uint32_t kMainThreadId = 1;
     48   static constexpr uint64_t kDefaultThreadSuspendTimeout = MsToNs(kIsDebugBuild ? 50000 : 10000);
     49 
     50   explicit ThreadList(uint64_t thread_suspend_timeout_ns);
     51   ~ThreadList();
     52 
     53   void DumpForSigQuit(std::ostream& os)
     54       REQUIRES(!Locks::thread_list_lock_, !Locks::mutator_lock_);
     55   // For thread suspend timeout dumps.
     56   void Dump(std::ostream& os, bool dump_native_stack = true)
     57       REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_);
     58   pid_t GetLockOwner();  // For SignalCatcher.
     59 
     60   // Thread suspension support.
     61   void ResumeAll()
     62       REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_)
     63       UNLOCK_FUNCTION(Locks::mutator_lock_);
     64   void Resume(Thread* thread, bool for_debugger = false)
     65       REQUIRES(!Locks::thread_suspend_count_lock_);
     66 
     67   // Suspends all threads and gets exclusive access to the mutator_lock_.
     68   // If long_suspend is true, then other threads who try to suspend will never timeout.
     69   // long_suspend is currenly used for hprof since large heaps take a long time.
     70   void SuspendAll(const char* cause, bool long_suspend = false)
     71       EXCLUSIVE_LOCK_FUNCTION(Locks::mutator_lock_)
     72       REQUIRES(!Locks::thread_list_lock_,
     73                !Locks::thread_suspend_count_lock_,
     74                !Locks::mutator_lock_);
     75 
     76   // Suspend a thread using a peer, typically used by the debugger. Returns the thread on success,
     77   // else null. The peer is used to identify the thread to avoid races with the thread terminating.
     78   // If the thread should be suspended then value of request_suspension should be true otherwise
     79   // the routine will wait for a previous suspend request. If the suspension times out then *timeout
     80   // is set to true.
     81   Thread* SuspendThreadByPeer(jobject peer, bool request_suspension, bool debug_suspension,
     82                               bool* timed_out)
     83       REQUIRES(!Locks::mutator_lock_,
     84                !Locks::thread_list_lock_,
     85                !Locks::thread_suspend_count_lock_);
     86 
     87   // Suspend a thread using its thread id, typically used by lock/monitor inflation. Returns the
     88   // thread on success else null. The thread id is used to identify the thread to avoid races with
     89   // the thread terminating. Note that as thread ids are recycled this may not suspend the expected
     90   // thread, that may be terminating. If the suspension times out then *timeout is set to true.
     91   Thread* SuspendThreadByThreadId(uint32_t thread_id, bool debug_suspension, bool* timed_out)
     92       REQUIRES(!Locks::mutator_lock_,
     93                !Locks::thread_list_lock_,
     94                !Locks::thread_suspend_count_lock_);
     95 
     96   // Find an existing thread (or self) by its thread id (not tid).
     97   Thread* FindThreadByThreadId(uint32_t thread_id) REQUIRES(Locks::thread_list_lock_);
     98 
     99   // Run a checkpoint on threads, running threads are not suspended but run the checkpoint inside
    100   // of the suspend check. Returns how many checkpoints that are expected to run, including for
    101   // already suspended threads for b/24191051. Run the callback, if non-null, inside the
    102   // thread_list_lock critical section after determining the runnable/suspended states of the
    103   // threads.
    104   size_t RunCheckpoint(Closure* checkpoint_function, Closure* callback = nullptr)
    105       REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_);
    106 
    107   // Run an empty checkpoint on threads. Wait until threads pass the next suspend point or are
    108   // suspended. This is used to ensure that the threads finish or aren't in the middle of an
    109   // in-flight mutator heap access (eg. a read barrier.) Runnable threads will respond by
    110   // decrementing the empty checkpoint barrier count. This works even when the weak ref access is
    111   // disabled. Only one concurrent use is currently supported.
    112   void RunEmptyCheckpoint()
    113       REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_);
    114 
    115   size_t RunCheckpointOnRunnableThreads(Closure* checkpoint_function)
    116       REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_);
    117 
    118   // Flip thread roots from from-space refs to to-space refs. Used by
    119   // the concurrent copying collector.
    120   size_t FlipThreadRoots(Closure* thread_flip_visitor,
    121                          Closure* flip_callback,
    122                          gc::collector::GarbageCollector* collector)
    123       REQUIRES(!Locks::mutator_lock_,
    124                !Locks::thread_list_lock_,
    125                !Locks::thread_suspend_count_lock_);
    126 
    127   // Suspends all threads
    128   void SuspendAllForDebugger()
    129       REQUIRES(!Locks::mutator_lock_,
    130                !Locks::thread_list_lock_,
    131                !Locks::thread_suspend_count_lock_);
    132 
    133   void SuspendSelfForDebugger()
    134       REQUIRES(!Locks::thread_suspend_count_lock_);
    135 
    136   // Resume all threads
    137   void ResumeAllForDebugger()
    138       REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_);
    139 
    140   void UndoDebuggerSuspensions()
    141       REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_);
    142 
    143   // Iterates over all the threads.
    144   void ForEach(void (*callback)(Thread*, void*), void* context)
    145       REQUIRES(Locks::thread_list_lock_);
    146 
    147   // Add/remove current thread from list.
    148   void Register(Thread* self)
    149       REQUIRES(Locks::runtime_shutdown_lock_)
    150       REQUIRES(!Locks::mutator_lock_,
    151                !Locks::thread_list_lock_,
    152                !Locks::thread_suspend_count_lock_);
    153   void Unregister(Thread* self)
    154       REQUIRES(!Locks::mutator_lock_,
    155                !Locks::thread_list_lock_,
    156                !Locks::thread_suspend_count_lock_);
    157 
    158   void VisitRoots(RootVisitor* visitor, VisitRootFlags flags) const
    159       REQUIRES_SHARED(Locks::mutator_lock_);
    160 
    161   void VisitRootsForSuspendedThreads(RootVisitor* visitor)
    162       REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_)
    163       REQUIRES_SHARED(Locks::mutator_lock_);
    164 
    165   // Return a copy of the thread list.
    166   std::list<Thread*> GetList() REQUIRES(Locks::thread_list_lock_) {
    167     return list_;
    168   }
    169 
    170   void DumpNativeStacks(std::ostream& os)
    171       REQUIRES(!Locks::thread_list_lock_);
    172 
    173   Barrier* EmptyCheckpointBarrier() {
    174     return empty_checkpoint_barrier_.get();
    175   }
    176 
    177  private:
    178   uint32_t AllocThreadId(Thread* self);
    179   void ReleaseThreadId(Thread* self, uint32_t id) REQUIRES(!Locks::allocated_thread_ids_lock_);
    180 
    181   bool Contains(Thread* thread) REQUIRES(Locks::thread_list_lock_);
    182   bool Contains(pid_t tid) REQUIRES(Locks::thread_list_lock_);
    183   size_t RunCheckpoint(Closure* checkpoint_function, bool includeSuspended)
    184       REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_);
    185 
    186   void DumpUnattachedThreads(std::ostream& os, bool dump_native_stack)
    187       REQUIRES(!Locks::thread_list_lock_);
    188 
    189   void SuspendAllDaemonThreadsForShutdown()
    190       REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_);
    191   void WaitForOtherNonDaemonThreadsToExit()
    192       REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_);
    193 
    194   void SuspendAllInternal(Thread* self,
    195                           Thread* ignore1,
    196                           Thread* ignore2 = nullptr,
    197                           bool debug_suspend = false)
    198       REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_);
    199 
    200   void AssertThreadsAreSuspended(Thread* self, Thread* ignore1, Thread* ignore2 = nullptr)
    201       REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_);
    202 
    203   std::bitset<kMaxThreadId> allocated_ids_ GUARDED_BY(Locks::allocated_thread_ids_lock_);
    204 
    205   // The actual list of all threads.
    206   std::list<Thread*> list_ GUARDED_BY(Locks::thread_list_lock_);
    207 
    208   // Ongoing suspend all requests, used to ensure threads added to list_ respect SuspendAll.
    209   int suspend_all_count_ GUARDED_BY(Locks::thread_suspend_count_lock_);
    210   int debug_suspend_all_count_ GUARDED_BY(Locks::thread_suspend_count_lock_);
    211 
    212   // Number of threads unregistering, ~ThreadList blocks until this hits 0.
    213   int unregistering_count_ GUARDED_BY(Locks::thread_list_lock_);
    214 
    215   // Thread suspend time histogram. Only modified when all the threads are suspended, so guarding
    216   // by mutator lock ensures no thread can read when another thread is modifying it.
    217   Histogram<uint64_t> suspend_all_historam_ GUARDED_BY(Locks::mutator_lock_);
    218 
    219   // Whether or not the current thread suspension is long.
    220   bool long_suspend_;
    221 
    222   // Thread suspension timeout in nanoseconds.
    223   const uint64_t thread_suspend_timeout_ns_;
    224 
    225   std::unique_ptr<Barrier> empty_checkpoint_barrier_;
    226 
    227   friend class Thread;
    228 
    229   DISALLOW_COPY_AND_ASSIGN(ThreadList);
    230 };
    231 
    232 // Helper for suspending all threads and
    233 class ScopedSuspendAll : public ValueObject {
    234  public:
    235   explicit ScopedSuspendAll(const char* cause, bool long_suspend = false)
    236      EXCLUSIVE_LOCK_FUNCTION(Locks::mutator_lock_)
    237      REQUIRES(!Locks::thread_list_lock_,
    238               !Locks::thread_suspend_count_lock_,
    239               !Locks::mutator_lock_);
    240   // No REQUIRES(mutator_lock_) since the unlock function already asserts this.
    241   ~ScopedSuspendAll()
    242       REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_)
    243       UNLOCK_FUNCTION(Locks::mutator_lock_);
    244 };
    245 
    246 }  // namespace art
    247 
    248 #endif  // ART_RUNTIME_THREAD_LIST_H_
    249