xref: /aosp_15_r20/art/openjdkjvmti/ti_monitor.cc (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /* Copyright (C) 2017 The Android Open Source Project
2*795d594fSAndroid Build Coastguard Worker  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * This file implements interfaces from the file jvmti.h. This implementation
5*795d594fSAndroid Build Coastguard Worker  * is licensed under the same terms as the file jvmti.h.  The
6*795d594fSAndroid Build Coastguard Worker  * copyright and license information for the file jvmti.h follows.
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
9*795d594fSAndroid Build Coastguard Worker  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
10*795d594fSAndroid Build Coastguard Worker  *
11*795d594fSAndroid Build Coastguard Worker  * This code is free software; you can redistribute it and/or modify it
12*795d594fSAndroid Build Coastguard Worker  * under the terms of the GNU General Public License version 2 only, as
13*795d594fSAndroid Build Coastguard Worker  * published by the Free Software Foundation.  Oracle designates this
14*795d594fSAndroid Build Coastguard Worker  * particular file as subject to the "Classpath" exception as provided
15*795d594fSAndroid Build Coastguard Worker  * by Oracle in the LICENSE file that accompanied this code.
16*795d594fSAndroid Build Coastguard Worker  *
17*795d594fSAndroid Build Coastguard Worker  * This code is distributed in the hope that it will be useful, but WITHOUT
18*795d594fSAndroid Build Coastguard Worker  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19*795d594fSAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20*795d594fSAndroid Build Coastguard Worker  * version 2 for more details (a copy is included in the LICENSE file that
21*795d594fSAndroid Build Coastguard Worker  * accompanied this code).
22*795d594fSAndroid Build Coastguard Worker  *
23*795d594fSAndroid Build Coastguard Worker  * You should have received a copy of the GNU General Public License version
24*795d594fSAndroid Build Coastguard Worker  * 2 along with this work; if not, write to the Free Software Foundation,
25*795d594fSAndroid Build Coastguard Worker  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
26*795d594fSAndroid Build Coastguard Worker  *
27*795d594fSAndroid Build Coastguard Worker  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
28*795d594fSAndroid Build Coastguard Worker  * or visit www.oracle.com if you need additional information or have any
29*795d594fSAndroid Build Coastguard Worker  * questions.
30*795d594fSAndroid Build Coastguard Worker  */
31*795d594fSAndroid Build Coastguard Worker 
32*795d594fSAndroid Build Coastguard Worker #include "ti_monitor.h"
33*795d594fSAndroid Build Coastguard Worker 
34*795d594fSAndroid Build Coastguard Worker #include <atomic>
35*795d594fSAndroid Build Coastguard Worker #include <chrono>
36*795d594fSAndroid Build Coastguard Worker #include <condition_variable>
37*795d594fSAndroid Build Coastguard Worker #include <mutex>
38*795d594fSAndroid Build Coastguard Worker 
39*795d594fSAndroid Build Coastguard Worker #include "art_jvmti.h"
40*795d594fSAndroid Build Coastguard Worker #include "gc_root-inl.h"
41*795d594fSAndroid Build Coastguard Worker #include "mirror/object-inl.h"
42*795d594fSAndroid Build Coastguard Worker #include "monitor.h"
43*795d594fSAndroid Build Coastguard Worker #include "runtime.h"
44*795d594fSAndroid Build Coastguard Worker #include "scoped_thread_state_change-inl.h"
45*795d594fSAndroid Build Coastguard Worker #include "thread-current-inl.h"
46*795d594fSAndroid Build Coastguard Worker #include "ti_thread.h"
47*795d594fSAndroid Build Coastguard Worker #include "thread.h"
48*795d594fSAndroid Build Coastguard Worker #include "thread_pool.h"
49*795d594fSAndroid Build Coastguard Worker 
50*795d594fSAndroid Build Coastguard Worker namespace openjdkjvmti {
51*795d594fSAndroid Build Coastguard Worker 
52*795d594fSAndroid Build Coastguard Worker // We cannot use ART monitors, as they require the mutator lock for contention locking. We
53*795d594fSAndroid Build Coastguard Worker // also cannot use pthread mutexes and condition variables (or C++11 abstractions) directly,
54*795d594fSAndroid Build Coastguard Worker // as the do not have the right semantics for recursive mutexes and waiting (wait only unlocks
55*795d594fSAndroid Build Coastguard Worker // the mutex once).
56*795d594fSAndroid Build Coastguard Worker // So go ahead and use a wrapper that does the counting explicitly.
57*795d594fSAndroid Build Coastguard Worker 
58*795d594fSAndroid Build Coastguard Worker class JvmtiMonitor {
59*795d594fSAndroid Build Coastguard Worker  public:
JvmtiMonitor()60*795d594fSAndroid Build Coastguard Worker   JvmtiMonitor() : owner_(nullptr), count_(0) { }
61*795d594fSAndroid Build Coastguard Worker 
Destroy(art::Thread * self,JvmtiMonitor * monitor)62*795d594fSAndroid Build Coastguard Worker   static bool Destroy(art::Thread* self, JvmtiMonitor* monitor) NO_THREAD_SAFETY_ANALYSIS {
63*795d594fSAndroid Build Coastguard Worker     // Check whether this thread holds the monitor, or nobody does.
64*795d594fSAndroid Build Coastguard Worker     art::Thread* owner_thread = monitor->owner_.load(std::memory_order_relaxed);
65*795d594fSAndroid Build Coastguard Worker     if (owner_thread != nullptr && self != owner_thread) {
66*795d594fSAndroid Build Coastguard Worker       return false;
67*795d594fSAndroid Build Coastguard Worker     }
68*795d594fSAndroid Build Coastguard Worker 
69*795d594fSAndroid Build Coastguard Worker     if (monitor->count_ > 0) {
70*795d594fSAndroid Build Coastguard Worker       monitor->count_ = 0;
71*795d594fSAndroid Build Coastguard Worker       monitor->owner_.store(nullptr, std::memory_order_relaxed);
72*795d594fSAndroid Build Coastguard Worker       monitor->mutex_.unlock();
73*795d594fSAndroid Build Coastguard Worker     }
74*795d594fSAndroid Build Coastguard Worker 
75*795d594fSAndroid Build Coastguard Worker     delete monitor;
76*795d594fSAndroid Build Coastguard Worker     return true;
77*795d594fSAndroid Build Coastguard Worker   }
78*795d594fSAndroid Build Coastguard Worker 
MonitorEnter(art::Thread * self,bool suspend)79*795d594fSAndroid Build Coastguard Worker   void MonitorEnter(art::Thread* self, bool suspend) NO_THREAD_SAFETY_ANALYSIS {
80*795d594fSAndroid Build Coastguard Worker     // Perform a suspend-check. The spec doesn't require this but real-world agents depend on this
81*795d594fSAndroid Build Coastguard Worker     // behavior. We do this by performing a suspend-check then retrying if the thread is suspended
82*795d594fSAndroid Build Coastguard Worker     // before or after locking the internal mutex.
83*795d594fSAndroid Build Coastguard Worker     do {
84*795d594fSAndroid Build Coastguard Worker       if (suspend) {
85*795d594fSAndroid Build Coastguard Worker         ThreadUtil::SuspendCheck(self);
86*795d594fSAndroid Build Coastguard Worker         if (ThreadUtil::WouldSuspendForUserCode(self)) {
87*795d594fSAndroid Build Coastguard Worker           continue;
88*795d594fSAndroid Build Coastguard Worker         }
89*795d594fSAndroid Build Coastguard Worker       }
90*795d594fSAndroid Build Coastguard Worker 
91*795d594fSAndroid Build Coastguard Worker       // Check for recursive enter.
92*795d594fSAndroid Build Coastguard Worker       if (IsOwner(self)) {
93*795d594fSAndroid Build Coastguard Worker         count_++;
94*795d594fSAndroid Build Coastguard Worker         return;
95*795d594fSAndroid Build Coastguard Worker       }
96*795d594fSAndroid Build Coastguard Worker 
97*795d594fSAndroid Build Coastguard Worker       // Checking for user-code suspension takes acquiring 2 art::Mutexes so we want to avoid doing
98*795d594fSAndroid Build Coastguard Worker       // that if possible. To avoid it we try to get the internal mutex without sleeping. If we do
99*795d594fSAndroid Build Coastguard Worker       // this we don't bother doing another suspend check since it can linearize after the lock.
100*795d594fSAndroid Build Coastguard Worker       if (mutex_.try_lock()) {
101*795d594fSAndroid Build Coastguard Worker         break;
102*795d594fSAndroid Build Coastguard Worker       } else {
103*795d594fSAndroid Build Coastguard Worker         // Lock with sleep. We will need to check for suspension after this to make sure that agents
104*795d594fSAndroid Build Coastguard Worker         // won't deadlock.
105*795d594fSAndroid Build Coastguard Worker         mutex_.lock();
106*795d594fSAndroid Build Coastguard Worker         if (!suspend || !ThreadUtil::WouldSuspendForUserCode(self)) {
107*795d594fSAndroid Build Coastguard Worker           break;
108*795d594fSAndroid Build Coastguard Worker         } else {
109*795d594fSAndroid Build Coastguard Worker           // We got suspended in the middle of waiting for the mutex. We should release the mutex
110*795d594fSAndroid Build Coastguard Worker           // and try again so we can get it while not suspended. This lets some other
111*795d594fSAndroid Build Coastguard Worker           // (non-suspended) thread acquire the mutex in case it's waiting to wake us up.
112*795d594fSAndroid Build Coastguard Worker           mutex_.unlock();
113*795d594fSAndroid Build Coastguard Worker           continue;
114*795d594fSAndroid Build Coastguard Worker         }
115*795d594fSAndroid Build Coastguard Worker       }
116*795d594fSAndroid Build Coastguard Worker     } while (true);
117*795d594fSAndroid Build Coastguard Worker 
118*795d594fSAndroid Build Coastguard Worker     DCHECK(owner_.load(std::memory_order_relaxed) == nullptr);
119*795d594fSAndroid Build Coastguard Worker     owner_.store(self, std::memory_order_relaxed);
120*795d594fSAndroid Build Coastguard Worker     DCHECK_EQ(0u, count_);
121*795d594fSAndroid Build Coastguard Worker     count_ = 1;
122*795d594fSAndroid Build Coastguard Worker   }
123*795d594fSAndroid Build Coastguard Worker 
MonitorExit(art::Thread * self)124*795d594fSAndroid Build Coastguard Worker   bool MonitorExit(art::Thread* self) NO_THREAD_SAFETY_ANALYSIS {
125*795d594fSAndroid Build Coastguard Worker     if (!IsOwner(self)) {
126*795d594fSAndroid Build Coastguard Worker       return false;
127*795d594fSAndroid Build Coastguard Worker     }
128*795d594fSAndroid Build Coastguard Worker 
129*795d594fSAndroid Build Coastguard Worker     --count_;
130*795d594fSAndroid Build Coastguard Worker     if (count_ == 0u) {
131*795d594fSAndroid Build Coastguard Worker       owner_.store(nullptr, std::memory_order_relaxed);
132*795d594fSAndroid Build Coastguard Worker       mutex_.unlock();
133*795d594fSAndroid Build Coastguard Worker     }
134*795d594fSAndroid Build Coastguard Worker 
135*795d594fSAndroid Build Coastguard Worker     return true;
136*795d594fSAndroid Build Coastguard Worker   }
137*795d594fSAndroid Build Coastguard Worker 
Wait(art::Thread * self)138*795d594fSAndroid Build Coastguard Worker   bool Wait(art::Thread* self) {
139*795d594fSAndroid Build Coastguard Worker     auto wait_without_timeout = [&](std::unique_lock<std::mutex>& lk) {
140*795d594fSAndroid Build Coastguard Worker       cond_.wait(lk);
141*795d594fSAndroid Build Coastguard Worker     };
142*795d594fSAndroid Build Coastguard Worker     return Wait(self, wait_without_timeout);
143*795d594fSAndroid Build Coastguard Worker   }
144*795d594fSAndroid Build Coastguard Worker 
Wait(art::Thread * self,uint64_t timeout_in_ms)145*795d594fSAndroid Build Coastguard Worker   bool Wait(art::Thread* self, uint64_t timeout_in_ms) {
146*795d594fSAndroid Build Coastguard Worker     auto wait_with_timeout = [&](std::unique_lock<std::mutex>& lk) {
147*795d594fSAndroid Build Coastguard Worker       cond_.wait_for(lk, std::chrono::milliseconds(timeout_in_ms));
148*795d594fSAndroid Build Coastguard Worker     };
149*795d594fSAndroid Build Coastguard Worker     return Wait(self, wait_with_timeout);
150*795d594fSAndroid Build Coastguard Worker   }
151*795d594fSAndroid Build Coastguard Worker 
Notify(art::Thread * self)152*795d594fSAndroid Build Coastguard Worker   bool Notify(art::Thread* self) {
153*795d594fSAndroid Build Coastguard Worker     return Notify(self, [&]() { cond_.notify_one(); });
154*795d594fSAndroid Build Coastguard Worker   }
155*795d594fSAndroid Build Coastguard Worker 
NotifyAll(art::Thread * self)156*795d594fSAndroid Build Coastguard Worker   bool NotifyAll(art::Thread* self) {
157*795d594fSAndroid Build Coastguard Worker     return Notify(self, [&]() { cond_.notify_all(); });
158*795d594fSAndroid Build Coastguard Worker   }
159*795d594fSAndroid Build Coastguard Worker 
160*795d594fSAndroid Build Coastguard Worker  private:
IsOwner(art::Thread * self) const161*795d594fSAndroid Build Coastguard Worker   bool IsOwner(art::Thread* self) const {
162*795d594fSAndroid Build Coastguard Worker     // There's a subtle correctness argument here for a relaxed load outside the critical section.
163*795d594fSAndroid Build Coastguard Worker     // A thread is guaranteed to see either its own latest store or another thread's store. If a
164*795d594fSAndroid Build Coastguard Worker     // thread sees another thread's store than it cannot be holding the lock.
165*795d594fSAndroid Build Coastguard Worker     art::Thread* owner_thread = owner_.load(std::memory_order_relaxed);
166*795d594fSAndroid Build Coastguard Worker     return self == owner_thread;
167*795d594fSAndroid Build Coastguard Worker   }
168*795d594fSAndroid Build Coastguard Worker 
169*795d594fSAndroid Build Coastguard Worker   template <typename T>
Wait(art::Thread * self,T how_to_wait)170*795d594fSAndroid Build Coastguard Worker   bool Wait(art::Thread* self, T how_to_wait) {
171*795d594fSAndroid Build Coastguard Worker     if (!IsOwner(self)) {
172*795d594fSAndroid Build Coastguard Worker       return false;
173*795d594fSAndroid Build Coastguard Worker     }
174*795d594fSAndroid Build Coastguard Worker 
175*795d594fSAndroid Build Coastguard Worker     size_t old_count = count_;
176*795d594fSAndroid Build Coastguard Worker     DCHECK_GT(old_count, 0u);
177*795d594fSAndroid Build Coastguard Worker 
178*795d594fSAndroid Build Coastguard Worker     count_ = 0;
179*795d594fSAndroid Build Coastguard Worker     owner_.store(nullptr, std::memory_order_relaxed);
180*795d594fSAndroid Build Coastguard Worker 
181*795d594fSAndroid Build Coastguard Worker     {
182*795d594fSAndroid Build Coastguard Worker       std::unique_lock<std::mutex> lk(mutex_, std::adopt_lock);
183*795d594fSAndroid Build Coastguard Worker       how_to_wait(lk);
184*795d594fSAndroid Build Coastguard Worker       // Here we release the mutex. We will get it back below. We first need to do a suspend-check
185*795d594fSAndroid Build Coastguard Worker       // without holding it however. This is done in the MonitorEnter function.
186*795d594fSAndroid Build Coastguard Worker       // TODO We could do this more efficiently.
187*795d594fSAndroid Build Coastguard Worker       // We hold the mutex_ but the overall monitor is not owned at this point.
188*795d594fSAndroid Build Coastguard Worker       CHECK(owner_.load(std::memory_order_relaxed) == nullptr);
189*795d594fSAndroid Build Coastguard Worker       DCHECK_EQ(0u, count_);
190*795d594fSAndroid Build Coastguard Worker     }
191*795d594fSAndroid Build Coastguard Worker 
192*795d594fSAndroid Build Coastguard Worker     // Reaquire the mutex/monitor, also go to sleep if we were suspended.
193*795d594fSAndroid Build Coastguard Worker     // TODO Give an extension to wait without suspension as well.
194*795d594fSAndroid Build Coastguard Worker     MonitorEnter(self, /*suspend=*/ true);
195*795d594fSAndroid Build Coastguard Worker     CHECK(owner_.load(std::memory_order_relaxed) == self);
196*795d594fSAndroid Build Coastguard Worker     DCHECK_EQ(1u, count_);
197*795d594fSAndroid Build Coastguard Worker     // Reset the count.
198*795d594fSAndroid Build Coastguard Worker     count_ = old_count;
199*795d594fSAndroid Build Coastguard Worker 
200*795d594fSAndroid Build Coastguard Worker     return true;
201*795d594fSAndroid Build Coastguard Worker   }
202*795d594fSAndroid Build Coastguard Worker 
203*795d594fSAndroid Build Coastguard Worker   template <typename T>
Notify(art::Thread * self,T how_to_notify)204*795d594fSAndroid Build Coastguard Worker   bool Notify(art::Thread* self, T how_to_notify) {
205*795d594fSAndroid Build Coastguard Worker     if (!IsOwner(self)) {
206*795d594fSAndroid Build Coastguard Worker       return false;
207*795d594fSAndroid Build Coastguard Worker     }
208*795d594fSAndroid Build Coastguard Worker 
209*795d594fSAndroid Build Coastguard Worker     how_to_notify();
210*795d594fSAndroid Build Coastguard Worker 
211*795d594fSAndroid Build Coastguard Worker     return true;
212*795d594fSAndroid Build Coastguard Worker   }
213*795d594fSAndroid Build Coastguard Worker 
214*795d594fSAndroid Build Coastguard Worker   std::mutex mutex_;
215*795d594fSAndroid Build Coastguard Worker   std::condition_variable cond_;
216*795d594fSAndroid Build Coastguard Worker   std::atomic<art::Thread*> owner_;
217*795d594fSAndroid Build Coastguard Worker   size_t count_;
218*795d594fSAndroid Build Coastguard Worker };
219*795d594fSAndroid Build Coastguard Worker 
EncodeMonitor(JvmtiMonitor * monitor)220*795d594fSAndroid Build Coastguard Worker static jrawMonitorID EncodeMonitor(JvmtiMonitor* monitor) {
221*795d594fSAndroid Build Coastguard Worker   return reinterpret_cast<jrawMonitorID>(monitor);
222*795d594fSAndroid Build Coastguard Worker }
223*795d594fSAndroid Build Coastguard Worker 
DecodeMonitor(jrawMonitorID id)224*795d594fSAndroid Build Coastguard Worker static JvmtiMonitor* DecodeMonitor(jrawMonitorID id) {
225*795d594fSAndroid Build Coastguard Worker   return reinterpret_cast<JvmtiMonitor*>(id);
226*795d594fSAndroid Build Coastguard Worker }
227*795d594fSAndroid Build Coastguard Worker 
CreateRawMonitor(jvmtiEnv * env,const char * name,jrawMonitorID * monitor_ptr)228*795d594fSAndroid Build Coastguard Worker jvmtiError MonitorUtil::CreateRawMonitor([[maybe_unused]] jvmtiEnv* env,
229*795d594fSAndroid Build Coastguard Worker                                          const char* name,
230*795d594fSAndroid Build Coastguard Worker                                          jrawMonitorID* monitor_ptr) {
231*795d594fSAndroid Build Coastguard Worker   if (name == nullptr || monitor_ptr == nullptr) {
232*795d594fSAndroid Build Coastguard Worker     return ERR(NULL_POINTER);
233*795d594fSAndroid Build Coastguard Worker   }
234*795d594fSAndroid Build Coastguard Worker 
235*795d594fSAndroid Build Coastguard Worker   JvmtiMonitor* monitor = new JvmtiMonitor();
236*795d594fSAndroid Build Coastguard Worker   *monitor_ptr = EncodeMonitor(monitor);
237*795d594fSAndroid Build Coastguard Worker 
238*795d594fSAndroid Build Coastguard Worker   return ERR(NONE);
239*795d594fSAndroid Build Coastguard Worker }
240*795d594fSAndroid Build Coastguard Worker 
DestroyRawMonitor(jvmtiEnv * env,jrawMonitorID id)241*795d594fSAndroid Build Coastguard Worker jvmtiError MonitorUtil::DestroyRawMonitor([[maybe_unused]] jvmtiEnv* env, jrawMonitorID id) {
242*795d594fSAndroid Build Coastguard Worker   if (id == nullptr) {
243*795d594fSAndroid Build Coastguard Worker     return ERR(INVALID_MONITOR);
244*795d594fSAndroid Build Coastguard Worker   }
245*795d594fSAndroid Build Coastguard Worker 
246*795d594fSAndroid Build Coastguard Worker   JvmtiMonitor* monitor = DecodeMonitor(id);
247*795d594fSAndroid Build Coastguard Worker   art::Thread* self = art::Thread::Current();
248*795d594fSAndroid Build Coastguard Worker 
249*795d594fSAndroid Build Coastguard Worker   if (!JvmtiMonitor::Destroy(self, monitor)) {
250*795d594fSAndroid Build Coastguard Worker     return ERR(NOT_MONITOR_OWNER);
251*795d594fSAndroid Build Coastguard Worker   }
252*795d594fSAndroid Build Coastguard Worker 
253*795d594fSAndroid Build Coastguard Worker   return ERR(NONE);
254*795d594fSAndroid Build Coastguard Worker }
255*795d594fSAndroid Build Coastguard Worker 
RawMonitorEnterNoSuspend(jvmtiEnv * env,jrawMonitorID id)256*795d594fSAndroid Build Coastguard Worker jvmtiError MonitorUtil::RawMonitorEnterNoSuspend([[maybe_unused]] jvmtiEnv* env, jrawMonitorID id) {
257*795d594fSAndroid Build Coastguard Worker   if (id == nullptr) {
258*795d594fSAndroid Build Coastguard Worker     return ERR(INVALID_MONITOR);
259*795d594fSAndroid Build Coastguard Worker   }
260*795d594fSAndroid Build Coastguard Worker 
261*795d594fSAndroid Build Coastguard Worker   JvmtiMonitor* monitor = DecodeMonitor(id);
262*795d594fSAndroid Build Coastguard Worker   art::Thread* self = art::Thread::Current();
263*795d594fSAndroid Build Coastguard Worker 
264*795d594fSAndroid Build Coastguard Worker   monitor->MonitorEnter(self, /*suspend=*/false);
265*795d594fSAndroid Build Coastguard Worker 
266*795d594fSAndroid Build Coastguard Worker   return ERR(NONE);
267*795d594fSAndroid Build Coastguard Worker }
268*795d594fSAndroid Build Coastguard Worker 
RawMonitorEnter(jvmtiEnv * env,jrawMonitorID id)269*795d594fSAndroid Build Coastguard Worker jvmtiError MonitorUtil::RawMonitorEnter([[maybe_unused]] jvmtiEnv* env, jrawMonitorID id) {
270*795d594fSAndroid Build Coastguard Worker   if (id == nullptr) {
271*795d594fSAndroid Build Coastguard Worker     return ERR(INVALID_MONITOR);
272*795d594fSAndroid Build Coastguard Worker   }
273*795d594fSAndroid Build Coastguard Worker 
274*795d594fSAndroid Build Coastguard Worker   JvmtiMonitor* monitor = DecodeMonitor(id);
275*795d594fSAndroid Build Coastguard Worker   art::Thread* self = art::Thread::Current();
276*795d594fSAndroid Build Coastguard Worker 
277*795d594fSAndroid Build Coastguard Worker   monitor->MonitorEnter(self, /*suspend=*/true);
278*795d594fSAndroid Build Coastguard Worker 
279*795d594fSAndroid Build Coastguard Worker   return ERR(NONE);
280*795d594fSAndroid Build Coastguard Worker }
281*795d594fSAndroid Build Coastguard Worker 
RawMonitorExit(jvmtiEnv * env,jrawMonitorID id)282*795d594fSAndroid Build Coastguard Worker jvmtiError MonitorUtil::RawMonitorExit([[maybe_unused]] jvmtiEnv* env, jrawMonitorID id) {
283*795d594fSAndroid Build Coastguard Worker   if (id == nullptr) {
284*795d594fSAndroid Build Coastguard Worker     return ERR(INVALID_MONITOR);
285*795d594fSAndroid Build Coastguard Worker   }
286*795d594fSAndroid Build Coastguard Worker 
287*795d594fSAndroid Build Coastguard Worker   JvmtiMonitor* monitor = DecodeMonitor(id);
288*795d594fSAndroid Build Coastguard Worker   art::Thread* self = art::Thread::Current();
289*795d594fSAndroid Build Coastguard Worker 
290*795d594fSAndroid Build Coastguard Worker   if (!monitor->MonitorExit(self)) {
291*795d594fSAndroid Build Coastguard Worker     return ERR(NOT_MONITOR_OWNER);
292*795d594fSAndroid Build Coastguard Worker   }
293*795d594fSAndroid Build Coastguard Worker 
294*795d594fSAndroid Build Coastguard Worker   return ERR(NONE);
295*795d594fSAndroid Build Coastguard Worker }
296*795d594fSAndroid Build Coastguard Worker 
RawMonitorWait(jvmtiEnv * env,jrawMonitorID id,jlong millis)297*795d594fSAndroid Build Coastguard Worker jvmtiError MonitorUtil::RawMonitorWait([[maybe_unused]] jvmtiEnv* env,
298*795d594fSAndroid Build Coastguard Worker                                        jrawMonitorID id,
299*795d594fSAndroid Build Coastguard Worker                                        jlong millis) {
300*795d594fSAndroid Build Coastguard Worker   if (id == nullptr) {
301*795d594fSAndroid Build Coastguard Worker     return ERR(INVALID_MONITOR);
302*795d594fSAndroid Build Coastguard Worker   }
303*795d594fSAndroid Build Coastguard Worker 
304*795d594fSAndroid Build Coastguard Worker   JvmtiMonitor* monitor = DecodeMonitor(id);
305*795d594fSAndroid Build Coastguard Worker   art::Thread* self = art::Thread::Current();
306*795d594fSAndroid Build Coastguard Worker 
307*795d594fSAndroid Build Coastguard Worker   // What millis < 0 means is not defined in the spec. Real world agents seem to assume that it is a
308*795d594fSAndroid Build Coastguard Worker   // valid call though. We treat it as though it was 0 and wait indefinitely.
309*795d594fSAndroid Build Coastguard Worker   bool result = (millis > 0)
310*795d594fSAndroid Build Coastguard Worker       ? monitor->Wait(self, static_cast<uint64_t>(millis))
311*795d594fSAndroid Build Coastguard Worker       : monitor->Wait(self);
312*795d594fSAndroid Build Coastguard Worker 
313*795d594fSAndroid Build Coastguard Worker   if (!result) {
314*795d594fSAndroid Build Coastguard Worker     return ERR(NOT_MONITOR_OWNER);
315*795d594fSAndroid Build Coastguard Worker   }
316*795d594fSAndroid Build Coastguard Worker 
317*795d594fSAndroid Build Coastguard Worker   // TODO: Make sure that is really what we should be checking here.
318*795d594fSAndroid Build Coastguard Worker   if (self->IsInterrupted()) {
319*795d594fSAndroid Build Coastguard Worker     return ERR(INTERRUPT);
320*795d594fSAndroid Build Coastguard Worker   }
321*795d594fSAndroid Build Coastguard Worker 
322*795d594fSAndroid Build Coastguard Worker   return ERR(NONE);
323*795d594fSAndroid Build Coastguard Worker }
324*795d594fSAndroid Build Coastguard Worker 
RawMonitorNotify(jvmtiEnv * env,jrawMonitorID id)325*795d594fSAndroid Build Coastguard Worker jvmtiError MonitorUtil::RawMonitorNotify([[maybe_unused]] jvmtiEnv* env, jrawMonitorID id) {
326*795d594fSAndroid Build Coastguard Worker   if (id == nullptr) {
327*795d594fSAndroid Build Coastguard Worker     return ERR(INVALID_MONITOR);
328*795d594fSAndroid Build Coastguard Worker   }
329*795d594fSAndroid Build Coastguard Worker 
330*795d594fSAndroid Build Coastguard Worker   JvmtiMonitor* monitor = DecodeMonitor(id);
331*795d594fSAndroid Build Coastguard Worker   art::Thread* self = art::Thread::Current();
332*795d594fSAndroid Build Coastguard Worker 
333*795d594fSAndroid Build Coastguard Worker   if (!monitor->Notify(self)) {
334*795d594fSAndroid Build Coastguard Worker     return ERR(NOT_MONITOR_OWNER);
335*795d594fSAndroid Build Coastguard Worker   }
336*795d594fSAndroid Build Coastguard Worker 
337*795d594fSAndroid Build Coastguard Worker   return ERR(NONE);
338*795d594fSAndroid Build Coastguard Worker }
339*795d594fSAndroid Build Coastguard Worker 
RawMonitorNotifyAll(jvmtiEnv * env,jrawMonitorID id)340*795d594fSAndroid Build Coastguard Worker jvmtiError MonitorUtil::RawMonitorNotifyAll([[maybe_unused]] jvmtiEnv* env, jrawMonitorID id) {
341*795d594fSAndroid Build Coastguard Worker   if (id == nullptr) {
342*795d594fSAndroid Build Coastguard Worker     return ERR(INVALID_MONITOR);
343*795d594fSAndroid Build Coastguard Worker   }
344*795d594fSAndroid Build Coastguard Worker 
345*795d594fSAndroid Build Coastguard Worker   JvmtiMonitor* monitor = DecodeMonitor(id);
346*795d594fSAndroid Build Coastguard Worker   art::Thread* self = art::Thread::Current();
347*795d594fSAndroid Build Coastguard Worker 
348*795d594fSAndroid Build Coastguard Worker   if (!monitor->NotifyAll(self)) {
349*795d594fSAndroid Build Coastguard Worker     return ERR(NOT_MONITOR_OWNER);
350*795d594fSAndroid Build Coastguard Worker   }
351*795d594fSAndroid Build Coastguard Worker 
352*795d594fSAndroid Build Coastguard Worker   return ERR(NONE);
353*795d594fSAndroid Build Coastguard Worker }
354*795d594fSAndroid Build Coastguard Worker 
GetCurrentContendedMonitor(jvmtiEnv * env,jthread thread,jobject * monitor)355*795d594fSAndroid Build Coastguard Worker jvmtiError MonitorUtil::GetCurrentContendedMonitor([[maybe_unused]] jvmtiEnv* env,
356*795d594fSAndroid Build Coastguard Worker                                                    jthread thread,
357*795d594fSAndroid Build Coastguard Worker                                                    jobject* monitor) {
358*795d594fSAndroid Build Coastguard Worker   if (monitor == nullptr) {
359*795d594fSAndroid Build Coastguard Worker     return ERR(NULL_POINTER);
360*795d594fSAndroid Build Coastguard Worker   }
361*795d594fSAndroid Build Coastguard Worker   art::Thread* self = art::Thread::Current();
362*795d594fSAndroid Build Coastguard Worker   art::ScopedObjectAccess soa(self);
363*795d594fSAndroid Build Coastguard Worker   art::Locks::thread_list_lock_->ExclusiveLock(self);
364*795d594fSAndroid Build Coastguard Worker   art::Thread* target = nullptr;
365*795d594fSAndroid Build Coastguard Worker   jvmtiError err = ERR(INTERNAL);
366*795d594fSAndroid Build Coastguard Worker   if (!ThreadUtil::GetAliveNativeThread(thread, soa, &target, &err)) {
367*795d594fSAndroid Build Coastguard Worker     art::Locks::thread_list_lock_->ExclusiveUnlock(self);
368*795d594fSAndroid Build Coastguard Worker     return err;
369*795d594fSAndroid Build Coastguard Worker   }
370*795d594fSAndroid Build Coastguard Worker   struct GetContendedMonitorClosure : public art::Closure {
371*795d594fSAndroid Build Coastguard Worker    public:
372*795d594fSAndroid Build Coastguard Worker     GetContendedMonitorClosure() : out_(nullptr) {}
373*795d594fSAndroid Build Coastguard Worker 
374*795d594fSAndroid Build Coastguard Worker     void Run(art::Thread* target_thread) override REQUIRES_SHARED(art::Locks::mutator_lock_) {
375*795d594fSAndroid Build Coastguard Worker       art::ScopedAssertNoThreadSuspension sants("GetContendedMonitorClosure::Run");
376*795d594fSAndroid Build Coastguard Worker       switch (target_thread->GetState()) {
377*795d594fSAndroid Build Coastguard Worker         // These three we are actually currently waiting on a monitor and have sent the appropriate
378*795d594fSAndroid Build Coastguard Worker         // events (if anyone is listening).
379*795d594fSAndroid Build Coastguard Worker         case art::ThreadState::kBlocked:
380*795d594fSAndroid Build Coastguard Worker         case art::ThreadState::kTimedWaiting:
381*795d594fSAndroid Build Coastguard Worker         case art::ThreadState::kWaiting: {
382*795d594fSAndroid Build Coastguard Worker           out_ = art::GcRoot<art::mirror::Object>(art::Monitor::GetContendedMonitor(target_thread));
383*795d594fSAndroid Build Coastguard Worker           return;
384*795d594fSAndroid Build Coastguard Worker         }
385*795d594fSAndroid Build Coastguard Worker         case art::ThreadState::kTerminated:
386*795d594fSAndroid Build Coastguard Worker         case art::ThreadState::kRunnable:
387*795d594fSAndroid Build Coastguard Worker         case art::ThreadState::kSleeping:
388*795d594fSAndroid Build Coastguard Worker         case art::ThreadState::kWaitingForLockInflation:
389*795d594fSAndroid Build Coastguard Worker         case art::ThreadState::kWaitingForTaskProcessor:
390*795d594fSAndroid Build Coastguard Worker         case art::ThreadState::kWaitingForGcToComplete:
391*795d594fSAndroid Build Coastguard Worker         case art::ThreadState::kWaitingForCheckPointsToRun:
392*795d594fSAndroid Build Coastguard Worker         case art::ThreadState::kWaitingPerformingGc:
393*795d594fSAndroid Build Coastguard Worker         case art::ThreadState::kWaitingForDebuggerSend:
394*795d594fSAndroid Build Coastguard Worker         case art::ThreadState::kWaitingForDebuggerToAttach:
395*795d594fSAndroid Build Coastguard Worker         case art::ThreadState::kWaitingInMainDebuggerLoop:
396*795d594fSAndroid Build Coastguard Worker         case art::ThreadState::kWaitingForDebuggerSuspension:
397*795d594fSAndroid Build Coastguard Worker         case art::ThreadState::kWaitingForJniOnLoad:
398*795d594fSAndroid Build Coastguard Worker         case art::ThreadState::kWaitingForSignalCatcherOutput:
399*795d594fSAndroid Build Coastguard Worker         case art::ThreadState::kWaitingInMainSignalCatcherLoop:
400*795d594fSAndroid Build Coastguard Worker         case art::ThreadState::kWaitingForDeoptimization:
401*795d594fSAndroid Build Coastguard Worker         case art::ThreadState::kWaitingForMethodTracingStart:
402*795d594fSAndroid Build Coastguard Worker         case art::ThreadState::kWaitingForVisitObjects:
403*795d594fSAndroid Build Coastguard Worker         case art::ThreadState::kWaitingForGetObjectsAllocated:
404*795d594fSAndroid Build Coastguard Worker         case art::ThreadState::kWaitingWeakGcRootRead:
405*795d594fSAndroid Build Coastguard Worker         case art::ThreadState::kWaitingForGcThreadFlip:
406*795d594fSAndroid Build Coastguard Worker         case art::ThreadState::kNativeForAbort:
407*795d594fSAndroid Build Coastguard Worker         case art::ThreadState::kStarting:
408*795d594fSAndroid Build Coastguard Worker         case art::ThreadState::kNative:
409*795d594fSAndroid Build Coastguard Worker         case art::ThreadState::kSuspended: {
410*795d594fSAndroid Build Coastguard Worker           // We aren't currently (explicitly) waiting for a monitor so just return null.
411*795d594fSAndroid Build Coastguard Worker           return;
412*795d594fSAndroid Build Coastguard Worker         case art::ThreadState::kObsoleteRunnable:
413*795d594fSAndroid Build Coastguard Worker         case art::ThreadState::kInvalidState:
414*795d594fSAndroid Build Coastguard Worker           LOG(FATAL) << "UNREACHABLE";  // Obsolete or invalid value.
415*795d594fSAndroid Build Coastguard Worker           UNREACHABLE();
416*795d594fSAndroid Build Coastguard Worker         }
417*795d594fSAndroid Build Coastguard Worker       }
418*795d594fSAndroid Build Coastguard Worker     }
419*795d594fSAndroid Build Coastguard Worker 
420*795d594fSAndroid Build Coastguard Worker     jobject GetResult() REQUIRES_SHARED(art::Locks::mutator_lock_) {
421*795d594fSAndroid Build Coastguard Worker       return out_.IsNull()
422*795d594fSAndroid Build Coastguard Worker           ? nullptr
423*795d594fSAndroid Build Coastguard Worker           : art::Thread::Current()->GetJniEnv()->AddLocalReference<jobject>(out_.Read());
424*795d594fSAndroid Build Coastguard Worker     }
425*795d594fSAndroid Build Coastguard Worker 
426*795d594fSAndroid Build Coastguard Worker    private:
427*795d594fSAndroid Build Coastguard Worker     art::GcRoot<art::mirror::Object> out_;
428*795d594fSAndroid Build Coastguard Worker   };
429*795d594fSAndroid Build Coastguard Worker   art::ScopedAssertNoThreadSuspension sants("Performing GetCurrentContendedMonitor");
430*795d594fSAndroid Build Coastguard Worker   GetContendedMonitorClosure closure;
431*795d594fSAndroid Build Coastguard Worker   // RequestSynchronousCheckpoint releases the thread_list_lock_ as a part of its execution.  We
432*795d594fSAndroid Build Coastguard Worker   // need to avoid suspending as we wait for the checkpoint to occur since we are (potentially)
433*795d594fSAndroid Build Coastguard Worker   // transfering a GcRoot across threads.
434*795d594fSAndroid Build Coastguard Worker   if (!target->RequestSynchronousCheckpoint(&closure, art::ThreadState::kRunnable)) {
435*795d594fSAndroid Build Coastguard Worker     return ERR(THREAD_NOT_ALIVE);
436*795d594fSAndroid Build Coastguard Worker   }
437*795d594fSAndroid Build Coastguard Worker   *monitor = closure.GetResult();
438*795d594fSAndroid Build Coastguard Worker   return OK;
439*795d594fSAndroid Build Coastguard Worker }
440*795d594fSAndroid Build Coastguard Worker 
441*795d594fSAndroid Build Coastguard Worker }  // namespace openjdkjvmti
442