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