xref: /aosp_15_r20/art/runtime/gc/system_weak.h (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2016 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #ifndef ART_RUNTIME_GC_SYSTEM_WEAK_H_
18*795d594fSAndroid Build Coastguard Worker #define ART_RUNTIME_GC_SYSTEM_WEAK_H_
19*795d594fSAndroid Build Coastguard Worker 
20*795d594fSAndroid Build Coastguard Worker #include "base/macros.h"
21*795d594fSAndroid Build Coastguard Worker #include "base/mutex.h"
22*795d594fSAndroid Build Coastguard Worker #include "object_callbacks.h"
23*795d594fSAndroid Build Coastguard Worker #include "thread-inl.h"
24*795d594fSAndroid Build Coastguard Worker 
25*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
26*795d594fSAndroid Build Coastguard Worker namespace gc {
27*795d594fSAndroid Build Coastguard Worker 
28*795d594fSAndroid Build Coastguard Worker class AbstractSystemWeakHolder {
29*795d594fSAndroid Build Coastguard Worker  public:
~AbstractSystemWeakHolder()30*795d594fSAndroid Build Coastguard Worker   virtual ~AbstractSystemWeakHolder() {}
31*795d594fSAndroid Build Coastguard Worker 
32*795d594fSAndroid Build Coastguard Worker   virtual void Allow() REQUIRES_SHARED(Locks::mutator_lock_) = 0;
33*795d594fSAndroid Build Coastguard Worker   virtual void Disallow() REQUIRES_SHARED(Locks::mutator_lock_) = 0;
34*795d594fSAndroid Build Coastguard Worker   // See Runtime::BroadcastForNewSystemWeaks for the broadcast_for_checkpoint definition.
35*795d594fSAndroid Build Coastguard Worker   virtual void Broadcast(bool broadcast_for_checkpoint) = 0;
36*795d594fSAndroid Build Coastguard Worker 
37*795d594fSAndroid Build Coastguard Worker   virtual void Sweep(IsMarkedVisitor* visitor) REQUIRES_SHARED(Locks::mutator_lock_) = 0;
38*795d594fSAndroid Build Coastguard Worker };
39*795d594fSAndroid Build Coastguard Worker 
40*795d594fSAndroid Build Coastguard Worker class SystemWeakHolder : public AbstractSystemWeakHolder {
41*795d594fSAndroid Build Coastguard Worker  public:
SystemWeakHolder(LockLevel level)42*795d594fSAndroid Build Coastguard Worker   explicit SystemWeakHolder(LockLevel level)
43*795d594fSAndroid Build Coastguard Worker       : allow_disallow_lock_("SystemWeakHolder", level),
44*795d594fSAndroid Build Coastguard Worker         new_weak_condition_("SystemWeakHolder new condition", allow_disallow_lock_),
45*795d594fSAndroid Build Coastguard Worker         allow_new_system_weak_(true) {
46*795d594fSAndroid Build Coastguard Worker   }
~SystemWeakHolder()47*795d594fSAndroid Build Coastguard Worker   virtual ~SystemWeakHolder() {}
48*795d594fSAndroid Build Coastguard Worker 
Allow()49*795d594fSAndroid Build Coastguard Worker   void Allow() override
50*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_)
51*795d594fSAndroid Build Coastguard Worker       REQUIRES(!allow_disallow_lock_) {
52*795d594fSAndroid Build Coastguard Worker     CHECK(!gUseReadBarrier);
53*795d594fSAndroid Build Coastguard Worker     MutexLock mu(Thread::Current(), allow_disallow_lock_);
54*795d594fSAndroid Build Coastguard Worker     allow_new_system_weak_ = true;
55*795d594fSAndroid Build Coastguard Worker     new_weak_condition_.Broadcast(Thread::Current());
56*795d594fSAndroid Build Coastguard Worker   }
57*795d594fSAndroid Build Coastguard Worker 
Disallow()58*795d594fSAndroid Build Coastguard Worker   void Disallow() override
59*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_)
60*795d594fSAndroid Build Coastguard Worker       REQUIRES(!allow_disallow_lock_) {
61*795d594fSAndroid Build Coastguard Worker     CHECK(!gUseReadBarrier);
62*795d594fSAndroid Build Coastguard Worker     MutexLock mu(Thread::Current(), allow_disallow_lock_);
63*795d594fSAndroid Build Coastguard Worker     allow_new_system_weak_ = false;
64*795d594fSAndroid Build Coastguard Worker   }
65*795d594fSAndroid Build Coastguard Worker 
Broadcast(bool broadcast_for_checkpoint)66*795d594fSAndroid Build Coastguard Worker   void Broadcast([[maybe_unused]] bool broadcast_for_checkpoint) override
67*795d594fSAndroid Build Coastguard Worker       REQUIRES(!allow_disallow_lock_) {
68*795d594fSAndroid Build Coastguard Worker     MutexLock mu(Thread::Current(), allow_disallow_lock_);
69*795d594fSAndroid Build Coastguard Worker     new_weak_condition_.Broadcast(Thread::Current());
70*795d594fSAndroid Build Coastguard Worker   }
71*795d594fSAndroid Build Coastguard Worker 
72*795d594fSAndroid Build Coastguard Worker   // WARNING: For lock annotations only.
GetAllowDisallowLock()73*795d594fSAndroid Build Coastguard Worker   Mutex* GetAllowDisallowLock() const RETURN_CAPABILITY(allow_disallow_lock_) {
74*795d594fSAndroid Build Coastguard Worker     return nullptr;
75*795d594fSAndroid Build Coastguard Worker   }
76*795d594fSAndroid Build Coastguard Worker 
77*795d594fSAndroid Build Coastguard Worker  protected:
Wait(Thread * self)78*795d594fSAndroid Build Coastguard Worker   void Wait(Thread* self)
79*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_)
80*795d594fSAndroid Build Coastguard Worker       REQUIRES(allow_disallow_lock_) {
81*795d594fSAndroid Build Coastguard Worker     // Wait for GC's sweeping to complete and allow new records
82*795d594fSAndroid Build Coastguard Worker     while (UNLIKELY((!gUseReadBarrier && !allow_new_system_weak_) ||
83*795d594fSAndroid Build Coastguard Worker                     (gUseReadBarrier && !self->GetWeakRefAccessEnabled()))) {
84*795d594fSAndroid Build Coastguard Worker       // Check and run the empty checkpoint before blocking so the empty checkpoint will work in the
85*795d594fSAndroid Build Coastguard Worker       // presence of threads blocking for weak ref access.
86*795d594fSAndroid Build Coastguard Worker       self->CheckEmptyCheckpointFromWeakRefAccess(&allow_disallow_lock_);
87*795d594fSAndroid Build Coastguard Worker       new_weak_condition_.WaitHoldingLocks(self);
88*795d594fSAndroid Build Coastguard Worker     }
89*795d594fSAndroid Build Coastguard Worker   }
90*795d594fSAndroid Build Coastguard Worker 
91*795d594fSAndroid Build Coastguard Worker   Mutex allow_disallow_lock_;
92*795d594fSAndroid Build Coastguard Worker   ConditionVariable new_weak_condition_ GUARDED_BY(allow_disallow_lock_);
93*795d594fSAndroid Build Coastguard Worker   bool allow_new_system_weak_ GUARDED_BY(allow_disallow_lock_);
94*795d594fSAndroid Build Coastguard Worker };
95*795d594fSAndroid Build Coastguard Worker 
96*795d594fSAndroid Build Coastguard Worker }  // namespace gc
97*795d594fSAndroid Build Coastguard Worker }  // namespace art
98*795d594fSAndroid Build Coastguard Worker 
99*795d594fSAndroid Build Coastguard Worker #endif  // ART_RUNTIME_GC_SYSTEM_WEAK_H_
100