99 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			99 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			C++
		
	
	
	
| /*
 | |
|  * Copyright (C) 2016 The Android Open Source Project
 | |
|  *
 | |
|  * Licensed under the Apache License, Version 2.0 (the "License");
 | |
|  * you may not use this file except in compliance with the License.
 | |
|  * You may obtain a copy of the License at
 | |
|  *
 | |
|  *      http://www.apache.org/licenses/LICENSE-2.0
 | |
|  *
 | |
|  * Unless required by applicable law or agreed to in writing, software
 | |
|  * distributed under the License is distributed on an "AS IS" BASIS,
 | |
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
|  * See the License for the specific language governing permissions and
 | |
|  * limitations under the License.
 | |
|  */
 | |
| 
 | |
| #ifndef ART_RUNTIME_GC_SYSTEM_WEAK_H_
 | |
| #define ART_RUNTIME_GC_SYSTEM_WEAK_H_
 | |
| 
 | |
| #include "base/mutex.h"
 | |
| #include "object_callbacks.h"
 | |
| #include "thread-inl.h"
 | |
| 
 | |
| namespace art {
 | |
| namespace gc {
 | |
| 
 | |
| class AbstractSystemWeakHolder {
 | |
|  public:
 | |
|   virtual ~AbstractSystemWeakHolder() {}
 | |
| 
 | |
|   virtual void Allow() REQUIRES_SHARED(Locks::mutator_lock_) = 0;
 | |
|   virtual void Disallow() REQUIRES_SHARED(Locks::mutator_lock_) = 0;
 | |
|   // See Runtime::BroadcastForNewSystemWeaks for the broadcast_for_checkpoint definition.
 | |
|   virtual void Broadcast(bool broadcast_for_checkpoint) = 0;
 | |
| 
 | |
|   virtual void Sweep(IsMarkedVisitor* visitor) REQUIRES_SHARED(Locks::mutator_lock_) = 0;
 | |
| };
 | |
| 
 | |
| class SystemWeakHolder : public AbstractSystemWeakHolder {
 | |
|  public:
 | |
|   explicit SystemWeakHolder(LockLevel level)
 | |
|       : allow_disallow_lock_("SystemWeakHolder", level),
 | |
|         new_weak_condition_("SystemWeakHolder new condition", allow_disallow_lock_),
 | |
|         allow_new_system_weak_(true) {
 | |
|   }
 | |
|   virtual ~SystemWeakHolder() {}
 | |
| 
 | |
|   void Allow() override
 | |
|       REQUIRES_SHARED(Locks::mutator_lock_)
 | |
|       REQUIRES(!allow_disallow_lock_) {
 | |
|     CHECK(!kUseReadBarrier);
 | |
|     MutexLock mu(Thread::Current(), allow_disallow_lock_);
 | |
|     allow_new_system_weak_ = true;
 | |
|     new_weak_condition_.Broadcast(Thread::Current());
 | |
|   }
 | |
| 
 | |
|   void Disallow() override
 | |
|       REQUIRES_SHARED(Locks::mutator_lock_)
 | |
|       REQUIRES(!allow_disallow_lock_) {
 | |
|     CHECK(!kUseReadBarrier);
 | |
|     MutexLock mu(Thread::Current(), allow_disallow_lock_);
 | |
|     allow_new_system_weak_ = false;
 | |
|   }
 | |
| 
 | |
|   void Broadcast(bool broadcast_for_checkpoint ATTRIBUTE_UNUSED) override
 | |
|       REQUIRES(!allow_disallow_lock_) {
 | |
|     MutexLock mu(Thread::Current(), allow_disallow_lock_);
 | |
|     new_weak_condition_.Broadcast(Thread::Current());
 | |
|   }
 | |
| 
 | |
|   // WARNING: For lock annotations only.
 | |
|   Mutex* GetAllowDisallowLock() const RETURN_CAPABILITY(allow_disallow_lock_) {
 | |
|     return nullptr;
 | |
|   }
 | |
| 
 | |
|  protected:
 | |
|   void Wait(Thread* self)
 | |
|       REQUIRES_SHARED(Locks::mutator_lock_)
 | |
|       REQUIRES(allow_disallow_lock_) {
 | |
|     // Wait for GC's sweeping to complete and allow new records
 | |
|     while (UNLIKELY((!kUseReadBarrier && !allow_new_system_weak_) ||
 | |
|                     (kUseReadBarrier && !self->GetWeakRefAccessEnabled()))) {
 | |
|       // Check and run the empty checkpoint before blocking so the empty checkpoint will work in the
 | |
|       // presence of threads blocking for weak ref access.
 | |
|       self->CheckEmptyCheckpointFromWeakRefAccess(&allow_disallow_lock_);
 | |
|       new_weak_condition_.WaitHoldingLocks(self);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   Mutex allow_disallow_lock_;
 | |
|   ConditionVariable new_weak_condition_ GUARDED_BY(allow_disallow_lock_);
 | |
|   bool allow_new_system_weak_ GUARDED_BY(allow_disallow_lock_);
 | |
| };
 | |
| 
 | |
| }  // namespace gc
 | |
| }  // namespace art
 | |
| 
 | |
| #endif  // ART_RUNTIME_GC_SYSTEM_WEAK_H_
 |