Home | History | Annotate | Download | only in base
      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 #include "locks.h"
     18 
     19 #include <errno.h>
     20 #include <sys/time.h>
     21 
     22 #include "android-base/logging.h"
     23 
     24 #include "base/atomic.h"
     25 #include "base/logging.h"
     26 #include "base/systrace.h"
     27 #include "base/time_utils.h"
     28 #include "base/value_object.h"
     29 #include "mutex-inl.h"
     30 #include "scoped_thread_state_change-inl.h"
     31 #include "thread-inl.h"
     32 
     33 namespace art {
     34 
     35 static Atomic<Locks::ClientCallback*> safe_to_call_abort_callback(nullptr);
     36 
     37 Mutex* Locks::abort_lock_ = nullptr;
     38 Mutex* Locks::alloc_tracker_lock_ = nullptr;
     39 Mutex* Locks::allocated_monitor_ids_lock_ = nullptr;
     40 Mutex* Locks::allocated_thread_ids_lock_ = nullptr;
     41 ReaderWriterMutex* Locks::breakpoint_lock_ = nullptr;
     42 ReaderWriterMutex* Locks::classlinker_classes_lock_ = nullptr;
     43 Mutex* Locks::custom_tls_lock_ = nullptr;
     44 Mutex* Locks::deoptimization_lock_ = nullptr;
     45 ReaderWriterMutex* Locks::heap_bitmap_lock_ = nullptr;
     46 Mutex* Locks::instrument_entrypoints_lock_ = nullptr;
     47 Mutex* Locks::intern_table_lock_ = nullptr;
     48 Mutex* Locks::jni_function_table_lock_ = nullptr;
     49 Mutex* Locks::jni_libraries_lock_ = nullptr;
     50 Mutex* Locks::logging_lock_ = nullptr;
     51 Mutex* Locks::modify_ldt_lock_ = nullptr;
     52 MutatorMutex* Locks::mutator_lock_ = nullptr;
     53 Mutex* Locks::profiler_lock_ = nullptr;
     54 ReaderWriterMutex* Locks::verifier_deps_lock_ = nullptr;
     55 ReaderWriterMutex* Locks::oat_file_manager_lock_ = nullptr;
     56 Mutex* Locks::host_dlopen_handles_lock_ = nullptr;
     57 Mutex* Locks::reference_processor_lock_ = nullptr;
     58 Mutex* Locks::reference_queue_cleared_references_lock_ = nullptr;
     59 Mutex* Locks::reference_queue_finalizer_references_lock_ = nullptr;
     60 Mutex* Locks::reference_queue_phantom_references_lock_ = nullptr;
     61 Mutex* Locks::reference_queue_soft_references_lock_ = nullptr;
     62 Mutex* Locks::reference_queue_weak_references_lock_ = nullptr;
     63 Mutex* Locks::runtime_shutdown_lock_ = nullptr;
     64 Mutex* Locks::runtime_thread_pool_lock_ = nullptr;
     65 Mutex* Locks::cha_lock_ = nullptr;
     66 Mutex* Locks::subtype_check_lock_ = nullptr;
     67 Mutex* Locks::thread_list_lock_ = nullptr;
     68 ConditionVariable* Locks::thread_exit_cond_ = nullptr;
     69 Mutex* Locks::thread_suspend_count_lock_ = nullptr;
     70 Mutex* Locks::trace_lock_ = nullptr;
     71 Mutex* Locks::unexpected_signal_lock_ = nullptr;
     72 Mutex* Locks::user_code_suspension_lock_ = nullptr;
     73 Uninterruptible Roles::uninterruptible_;
     74 ReaderWriterMutex* Locks::jni_globals_lock_ = nullptr;
     75 Mutex* Locks::jni_weak_globals_lock_ = nullptr;
     76 ReaderWriterMutex* Locks::dex_lock_ = nullptr;
     77 Mutex* Locks::native_debug_interface_lock_ = nullptr;
     78 std::vector<BaseMutex*> Locks::expected_mutexes_on_weak_ref_access_;
     79 Atomic<const BaseMutex*> Locks::expected_mutexes_on_weak_ref_access_guard_;
     80 
     81 // Wait for an amount of time that roughly increases in the argument i.
     82 // Spin for small arguments and yield/sleep for longer ones.
     83 static void BackOff(uint32_t i) {
     84   static constexpr uint32_t kSpinMax = 10;
     85   static constexpr uint32_t kYieldMax = 20;
     86   if (i <= kSpinMax) {
     87     // TODO: Esp. in very latency-sensitive cases, consider replacing this with an explicit
     88     // test-and-test-and-set loop in the caller.  Possibly skip entirely on a uniprocessor.
     89     volatile uint32_t x = 0;
     90     const uint32_t spin_count = 10 * i;
     91     for (uint32_t spin = 0; spin < spin_count; ++spin) {
     92       ++x;  // Volatile; hence should not be optimized away.
     93     }
     94     // TODO: Consider adding x86 PAUSE and/or ARM YIELD here.
     95   } else if (i <= kYieldMax) {
     96     sched_yield();
     97   } else {
     98     NanoSleep(1000ull * (i - kYieldMax));
     99   }
    100 }
    101 
    102 class Locks::ScopedExpectedMutexesOnWeakRefAccessLock final {
    103  public:
    104   explicit ScopedExpectedMutexesOnWeakRefAccessLock(const BaseMutex* mutex) : mutex_(mutex) {
    105     for (uint32_t i = 0;
    106          !Locks::expected_mutexes_on_weak_ref_access_guard_.CompareAndSetWeakAcquire(nullptr,
    107                                                                                      mutex);
    108          ++i) {
    109       BackOff(i);
    110     }
    111   }
    112 
    113   ~ScopedExpectedMutexesOnWeakRefAccessLock() {
    114     DCHECK_EQ(Locks::expected_mutexes_on_weak_ref_access_guard_.load(std::memory_order_relaxed),
    115               mutex_);
    116     Locks::expected_mutexes_on_weak_ref_access_guard_.store(nullptr, std::memory_order_release);
    117   }
    118 
    119  private:
    120   const BaseMutex* const mutex_;
    121 };
    122 
    123 void Locks::Init() {
    124   if (logging_lock_ != nullptr) {
    125     // Already initialized.
    126     if (kRuntimeISA == InstructionSet::kX86 || kRuntimeISA == InstructionSet::kX86_64) {
    127       DCHECK(modify_ldt_lock_ != nullptr);
    128     } else {
    129       DCHECK(modify_ldt_lock_ == nullptr);
    130     }
    131     DCHECK(abort_lock_ != nullptr);
    132     DCHECK(alloc_tracker_lock_ != nullptr);
    133     DCHECK(allocated_monitor_ids_lock_ != nullptr);
    134     DCHECK(allocated_thread_ids_lock_ != nullptr);
    135     DCHECK(breakpoint_lock_ != nullptr);
    136     DCHECK(classlinker_classes_lock_ != nullptr);
    137     DCHECK(custom_tls_lock_ != nullptr);
    138     DCHECK(deoptimization_lock_ != nullptr);
    139     DCHECK(heap_bitmap_lock_ != nullptr);
    140     DCHECK(oat_file_manager_lock_ != nullptr);
    141     DCHECK(verifier_deps_lock_ != nullptr);
    142     DCHECK(host_dlopen_handles_lock_ != nullptr);
    143     DCHECK(intern_table_lock_ != nullptr);
    144     DCHECK(jni_function_table_lock_ != nullptr);
    145     DCHECK(jni_libraries_lock_ != nullptr);
    146     DCHECK(logging_lock_ != nullptr);
    147     DCHECK(mutator_lock_ != nullptr);
    148     DCHECK(profiler_lock_ != nullptr);
    149     DCHECK(cha_lock_ != nullptr);
    150     DCHECK(subtype_check_lock_ != nullptr);
    151     DCHECK(thread_list_lock_ != nullptr);
    152     DCHECK(thread_suspend_count_lock_ != nullptr);
    153     DCHECK(trace_lock_ != nullptr);
    154     DCHECK(unexpected_signal_lock_ != nullptr);
    155     DCHECK(user_code_suspension_lock_ != nullptr);
    156     DCHECK(dex_lock_ != nullptr);
    157     DCHECK(native_debug_interface_lock_ != nullptr);
    158     DCHECK(runtime_thread_pool_lock_ != nullptr);
    159   } else {
    160     // Create global locks in level order from highest lock level to lowest.
    161     LockLevel current_lock_level = kUserCodeSuspensionLock;
    162     DCHECK(user_code_suspension_lock_ == nullptr);
    163     user_code_suspension_lock_ = new Mutex("user code suspension lock", current_lock_level);
    164 
    165     #define UPDATE_CURRENT_LOCK_LEVEL(new_level) \
    166       if ((new_level) >= current_lock_level) { \
    167         /* Do not use CHECKs or FATAL here, abort_lock_ is not setup yet. */ \
    168         fprintf(stderr, "New local level %d is not less than current level %d\n", \
    169                 new_level, current_lock_level); \
    170         exit(1); \
    171       } \
    172       current_lock_level = new_level;
    173 
    174     UPDATE_CURRENT_LOCK_LEVEL(kInstrumentEntrypointsLock);
    175     DCHECK(instrument_entrypoints_lock_ == nullptr);
    176     instrument_entrypoints_lock_ = new Mutex("instrument entrypoint lock", current_lock_level);
    177 
    178     UPDATE_CURRENT_LOCK_LEVEL(kMutatorLock);
    179     DCHECK(mutator_lock_ == nullptr);
    180     mutator_lock_ = new MutatorMutex("mutator lock", current_lock_level);
    181 
    182     UPDATE_CURRENT_LOCK_LEVEL(kHeapBitmapLock);
    183     DCHECK(heap_bitmap_lock_ == nullptr);
    184     heap_bitmap_lock_ = new ReaderWriterMutex("heap bitmap lock", current_lock_level);
    185 
    186     UPDATE_CURRENT_LOCK_LEVEL(kTraceLock);
    187     DCHECK(trace_lock_ == nullptr);
    188     trace_lock_ = new Mutex("trace lock", current_lock_level);
    189 
    190     UPDATE_CURRENT_LOCK_LEVEL(kRuntimeShutdownLock);
    191     DCHECK(runtime_shutdown_lock_ == nullptr);
    192     runtime_shutdown_lock_ = new Mutex("runtime shutdown lock", current_lock_level);
    193 
    194     UPDATE_CURRENT_LOCK_LEVEL(kRuntimeThreadPoolLock);
    195     DCHECK(runtime_thread_pool_lock_ == nullptr);
    196     runtime_thread_pool_lock_ = new Mutex("runtime thread pool lock", current_lock_level);
    197 
    198     UPDATE_CURRENT_LOCK_LEVEL(kProfilerLock);
    199     DCHECK(profiler_lock_ == nullptr);
    200     profiler_lock_ = new Mutex("profiler lock", current_lock_level);
    201 
    202     UPDATE_CURRENT_LOCK_LEVEL(kDeoptimizationLock);
    203     DCHECK(deoptimization_lock_ == nullptr);
    204     deoptimization_lock_ = new Mutex("Deoptimization lock", current_lock_level);
    205 
    206     UPDATE_CURRENT_LOCK_LEVEL(kAllocTrackerLock);
    207     DCHECK(alloc_tracker_lock_ == nullptr);
    208     alloc_tracker_lock_ = new Mutex("AllocTracker lock", current_lock_level);
    209 
    210     UPDATE_CURRENT_LOCK_LEVEL(kThreadListLock);
    211     DCHECK(thread_list_lock_ == nullptr);
    212     thread_list_lock_ = new Mutex("thread list lock", current_lock_level);
    213 
    214     UPDATE_CURRENT_LOCK_LEVEL(kJniLoadLibraryLock);
    215     DCHECK(jni_libraries_lock_ == nullptr);
    216     jni_libraries_lock_ = new Mutex("JNI shared libraries map lock", current_lock_level);
    217 
    218     UPDATE_CURRENT_LOCK_LEVEL(kBreakpointLock);
    219     DCHECK(breakpoint_lock_ == nullptr);
    220     breakpoint_lock_ = new ReaderWriterMutex("breakpoint lock", current_lock_level);
    221 
    222     UPDATE_CURRENT_LOCK_LEVEL(kSubtypeCheckLock);
    223     DCHECK(subtype_check_lock_ == nullptr);
    224     subtype_check_lock_ = new Mutex("SubtypeCheck lock", current_lock_level);
    225 
    226     UPDATE_CURRENT_LOCK_LEVEL(kClassLinkerClassesLock);
    227     DCHECK(classlinker_classes_lock_ == nullptr);
    228     classlinker_classes_lock_ = new ReaderWriterMutex("ClassLinker classes lock",
    229                                                       current_lock_level);
    230 
    231     UPDATE_CURRENT_LOCK_LEVEL(kMonitorPoolLock);
    232     DCHECK(allocated_monitor_ids_lock_ == nullptr);
    233     allocated_monitor_ids_lock_ =  new Mutex("allocated monitor ids lock", current_lock_level);
    234 
    235     UPDATE_CURRENT_LOCK_LEVEL(kAllocatedThreadIdsLock);
    236     DCHECK(allocated_thread_ids_lock_ == nullptr);
    237     allocated_thread_ids_lock_ =  new Mutex("allocated thread ids lock", current_lock_level);
    238 
    239     if (kRuntimeISA == InstructionSet::kX86 || kRuntimeISA == InstructionSet::kX86_64) {
    240       UPDATE_CURRENT_LOCK_LEVEL(kModifyLdtLock);
    241       DCHECK(modify_ldt_lock_ == nullptr);
    242       modify_ldt_lock_ = new Mutex("modify_ldt lock", current_lock_level);
    243     }
    244 
    245     UPDATE_CURRENT_LOCK_LEVEL(kDexLock);
    246     DCHECK(dex_lock_ == nullptr);
    247     dex_lock_ = new ReaderWriterMutex("ClassLinker dex lock", current_lock_level);
    248 
    249     UPDATE_CURRENT_LOCK_LEVEL(kOatFileManagerLock);
    250     DCHECK(oat_file_manager_lock_ == nullptr);
    251     oat_file_manager_lock_ = new ReaderWriterMutex("OatFile manager lock", current_lock_level);
    252 
    253     UPDATE_CURRENT_LOCK_LEVEL(kVerifierDepsLock);
    254     DCHECK(verifier_deps_lock_ == nullptr);
    255     verifier_deps_lock_ = new ReaderWriterMutex("verifier deps lock", current_lock_level);
    256 
    257     UPDATE_CURRENT_LOCK_LEVEL(kHostDlOpenHandlesLock);
    258     DCHECK(host_dlopen_handles_lock_ == nullptr);
    259     host_dlopen_handles_lock_ = new Mutex("host dlopen handles lock", current_lock_level);
    260 
    261     UPDATE_CURRENT_LOCK_LEVEL(kInternTableLock);
    262     DCHECK(intern_table_lock_ == nullptr);
    263     intern_table_lock_ = new Mutex("InternTable lock", current_lock_level);
    264 
    265     UPDATE_CURRENT_LOCK_LEVEL(kReferenceProcessorLock);
    266     DCHECK(reference_processor_lock_ == nullptr);
    267     reference_processor_lock_ = new Mutex("ReferenceProcessor lock", current_lock_level);
    268 
    269     UPDATE_CURRENT_LOCK_LEVEL(kReferenceQueueClearedReferencesLock);
    270     DCHECK(reference_queue_cleared_references_lock_ == nullptr);
    271     reference_queue_cleared_references_lock_ = new Mutex("ReferenceQueue cleared references lock", current_lock_level);
    272 
    273     UPDATE_CURRENT_LOCK_LEVEL(kReferenceQueueWeakReferencesLock);
    274     DCHECK(reference_queue_weak_references_lock_ == nullptr);
    275     reference_queue_weak_references_lock_ = new Mutex("ReferenceQueue cleared references lock", current_lock_level);
    276 
    277     UPDATE_CURRENT_LOCK_LEVEL(kReferenceQueueFinalizerReferencesLock);
    278     DCHECK(reference_queue_finalizer_references_lock_ == nullptr);
    279     reference_queue_finalizer_references_lock_ = new Mutex("ReferenceQueue finalizer references lock", current_lock_level);
    280 
    281     UPDATE_CURRENT_LOCK_LEVEL(kReferenceQueuePhantomReferencesLock);
    282     DCHECK(reference_queue_phantom_references_lock_ == nullptr);
    283     reference_queue_phantom_references_lock_ = new Mutex("ReferenceQueue phantom references lock", current_lock_level);
    284 
    285     UPDATE_CURRENT_LOCK_LEVEL(kReferenceQueueSoftReferencesLock);
    286     DCHECK(reference_queue_soft_references_lock_ == nullptr);
    287     reference_queue_soft_references_lock_ = new Mutex("ReferenceQueue soft references lock", current_lock_level);
    288 
    289     UPDATE_CURRENT_LOCK_LEVEL(kJniGlobalsLock);
    290     DCHECK(jni_globals_lock_ == nullptr);
    291     jni_globals_lock_ =
    292         new ReaderWriterMutex("JNI global reference table lock", current_lock_level);
    293 
    294     UPDATE_CURRENT_LOCK_LEVEL(kJniWeakGlobalsLock);
    295     DCHECK(jni_weak_globals_lock_ == nullptr);
    296     jni_weak_globals_lock_ = new Mutex("JNI weak global reference table lock", current_lock_level);
    297 
    298     UPDATE_CURRENT_LOCK_LEVEL(kJniFunctionTableLock);
    299     DCHECK(jni_function_table_lock_ == nullptr);
    300     jni_function_table_lock_ = new Mutex("JNI function table lock", current_lock_level);
    301 
    302     UPDATE_CURRENT_LOCK_LEVEL(kCustomTlsLock);
    303     DCHECK(custom_tls_lock_ == nullptr);
    304     custom_tls_lock_ = new Mutex("Thread::custom_tls_ lock", current_lock_level);
    305 
    306     UPDATE_CURRENT_LOCK_LEVEL(kCHALock);
    307     DCHECK(cha_lock_ == nullptr);
    308     cha_lock_ = new Mutex("CHA lock", current_lock_level);
    309 
    310     UPDATE_CURRENT_LOCK_LEVEL(kNativeDebugInterfaceLock);
    311     DCHECK(native_debug_interface_lock_ == nullptr);
    312     native_debug_interface_lock_ = new Mutex("Native debug interface lock", current_lock_level);
    313 
    314     UPDATE_CURRENT_LOCK_LEVEL(kAbortLock);
    315     DCHECK(abort_lock_ == nullptr);
    316     abort_lock_ = new Mutex("abort lock", current_lock_level, true);
    317 
    318     UPDATE_CURRENT_LOCK_LEVEL(kThreadSuspendCountLock);
    319     DCHECK(thread_suspend_count_lock_ == nullptr);
    320     thread_suspend_count_lock_ = new Mutex("thread suspend count lock", current_lock_level);
    321 
    322     UPDATE_CURRENT_LOCK_LEVEL(kUnexpectedSignalLock);
    323     DCHECK(unexpected_signal_lock_ == nullptr);
    324     unexpected_signal_lock_ = new Mutex("unexpected signal lock", current_lock_level, true);
    325 
    326     UPDATE_CURRENT_LOCK_LEVEL(kLoggingLock);
    327     DCHECK(logging_lock_ == nullptr);
    328     logging_lock_ = new Mutex("logging lock", current_lock_level, true);
    329 
    330     #undef UPDATE_CURRENT_LOCK_LEVEL
    331 
    332     // List of mutexes that we may hold when accessing a weak ref.
    333     AddToExpectedMutexesOnWeakRefAccess(dex_lock_, /*need_lock=*/ false);
    334     AddToExpectedMutexesOnWeakRefAccess(classlinker_classes_lock_, /*need_lock=*/ false);
    335     AddToExpectedMutexesOnWeakRefAccess(jni_libraries_lock_, /*need_lock=*/ false);
    336 
    337     InitConditions();
    338   }
    339 }
    340 
    341 void Locks::InitConditions() {
    342   thread_exit_cond_ = new ConditionVariable("thread exit condition variable", *thread_list_lock_);
    343 }
    344 
    345 void Locks::SetClientCallback(ClientCallback* safe_to_call_abort_cb) {
    346   safe_to_call_abort_callback.store(safe_to_call_abort_cb, std::memory_order_release);
    347 }
    348 
    349 // Helper to allow checking shutdown while ignoring locking requirements.
    350 bool Locks::IsSafeToCallAbortRacy() {
    351   Locks::ClientCallback* safe_to_call_abort_cb =
    352       safe_to_call_abort_callback.load(std::memory_order_acquire);
    353   return safe_to_call_abort_cb != nullptr && safe_to_call_abort_cb();
    354 }
    355 
    356 void Locks::AddToExpectedMutexesOnWeakRefAccess(BaseMutex* mutex, bool need_lock) {
    357   if (need_lock) {
    358     ScopedExpectedMutexesOnWeakRefAccessLock mu(mutex);
    359     mutex->SetShouldRespondToEmptyCheckpointRequest(true);
    360     expected_mutexes_on_weak_ref_access_.push_back(mutex);
    361   } else {
    362     mutex->SetShouldRespondToEmptyCheckpointRequest(true);
    363     expected_mutexes_on_weak_ref_access_.push_back(mutex);
    364   }
    365 }
    366 
    367 void Locks::RemoveFromExpectedMutexesOnWeakRefAccess(BaseMutex* mutex, bool need_lock) {
    368   if (need_lock) {
    369     ScopedExpectedMutexesOnWeakRefAccessLock mu(mutex);
    370     mutex->SetShouldRespondToEmptyCheckpointRequest(false);
    371     std::vector<BaseMutex*>& list = expected_mutexes_on_weak_ref_access_;
    372     auto it = std::find(list.begin(), list.end(), mutex);
    373     DCHECK(it != list.end());
    374     list.erase(it);
    375   } else {
    376     mutex->SetShouldRespondToEmptyCheckpointRequest(false);
    377     std::vector<BaseMutex*>& list = expected_mutexes_on_weak_ref_access_;
    378     auto it = std::find(list.begin(), list.end(), mutex);
    379     DCHECK(it != list.end());
    380     list.erase(it);
    381   }
    382 }
    383 
    384 bool Locks::IsExpectedOnWeakRefAccess(BaseMutex* mutex) {
    385   ScopedExpectedMutexesOnWeakRefAccessLock mu(mutex);
    386   std::vector<BaseMutex*>& list = expected_mutexes_on_weak_ref_access_;
    387   return std::find(list.begin(), list.end(), mutex) != list.end();
    388 }
    389 
    390 }  // namespace art
    391