1 /*
  2  * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  *
 23  */
 24 
 25 #include "precompiled.hpp"
 26 #include "memory/allocation.inline.hpp"
 27 #include "prims/jvmtiRawMonitor.hpp"
 28 #include "runtime/atomic.hpp"
 29 #include "runtime/interfaceSupport.inline.hpp"
 30 #include "runtime/orderAccess.hpp"
 31 #include "runtime/thread.inline.hpp"
 32 
 33 JvmtiRawMonitor::QNode::QNode(Thread* thread) : _next(NULL), _prev(NULL),
 34                                                 _event(thread->_ParkEvent),
 35                                                 _notified(0), _t_state(TS_RUN) {
 36 }
 37 
 38 GrowableArray<JvmtiRawMonitor*>* JvmtiPendingMonitors::_monitors =
 39   new (ResourceObj::C_HEAP, mtServiceability) GrowableArray<JvmtiRawMonitor*>(1, mtServiceability);
 40 
 41 void JvmtiPendingMonitors::transition_raw_monitors() {
 42   assert((Threads::number_of_threads()==1),
 43          "Java thread has not been created yet or more than one java thread "
 44          "is running. Raw monitor transition will not work");
 45   JavaThread* current_java_thread = JavaThread::current();
 46   {
 47     ThreadToNativeFromVM ttnfvm(current_java_thread);
 48     for (int i = 0; i < count(); i++) {
 49       JvmtiRawMonitor* rmonitor = monitors()->at(i);
 50       rmonitor->raw_enter(current_java_thread);
 51     }
 52   }
 53   // pending monitors are converted to real monitor so delete them all.
 54   dispose();
 55 }
 56 
 57 //
 58 // class JvmtiRawMonitor
 59 //
 60 
 61 JvmtiRawMonitor::JvmtiRawMonitor(const char* name) : _owner(NULL),
 62                                                      _recursions(0),
 63                                                      _entry_list(NULL),
 64                                                      _wait_set(NULL),
 65                                                      _magic(JVMTI_RM_MAGIC),
 66                                                      _name(NULL) {
 67 #ifdef ASSERT
 68   _name = strcpy(NEW_C_HEAP_ARRAY(char, strlen(name) + 1, mtInternal), name);
 69 #endif
 70 }
 71 
 72 JvmtiRawMonitor::~JvmtiRawMonitor() {
 73 #ifdef ASSERT
 74   FreeHeap(_name);
 75 #endif
 76   _magic = 0;
 77 }
 78 
 79 
 80 bool
 81 JvmtiRawMonitor::is_valid() {
 82   int value = 0;
 83 
 84   // This object might not be a JvmtiRawMonitor so we can't assume
 85   // the _magic field is properly aligned. Get the value in a safe
 86   // way and then check against JVMTI_RM_MAGIC.
 87 
 88   switch (sizeof(_magic)) {
 89   case 2:
 90     value = Bytes::get_native_u2((address)&_magic);
 91     break;
 92 
 93   case 4:
 94     value = Bytes::get_native_u4((address)&_magic);
 95     break;
 96 
 97   case 8:
 98     value = Bytes::get_native_u8((address)&_magic);
 99     break;
100 
101   default:
102     guarantee(false, "_magic field is an unexpected size");
103   }
104 
105   return value == JVMTI_RM_MAGIC;
106 }
107 
108 // -------------------------------------------------------------------------
109 // The JVMTI raw monitor subsystem is entirely distinct from normal
110 // java-synchronization or jni-synchronization.  JVMTI raw monitors are not
111 // associated with objects.  They can be implemented in any manner
112 // that makes sense.  The original implementors decided to piggy-back
113 // the raw-monitor implementation on the existing Java ObjectMonitor mechanism.
114 // Now we just use a simplified form of that ObjectMonitor code.
115 //
116 // Note that we use the single RawMonitor_lock to protect queue operations for
117 // _all_ raw monitors.  This is a scalability impediment, but since raw monitor usage
118 // is fairly rare, this is not of concern.  The RawMonitor_lock can not
119 // be held indefinitely.  The critical sections must be short and bounded.
120 //
121 // -------------------------------------------------------------------------
122 
123 void JvmtiRawMonitor::simple_enter(Thread* self) {
124   for (;;) {
125     if (Atomic::replace_if_null(&_owner, self)) {



126       return;
127     }
128 
129     QNode node(self);
130     self->_ParkEvent->reset();     // strictly optional
131     node._t_state = QNode::TS_ENTER;
132 
133     RawMonitor_lock->lock_without_safepoint_check();
134     node._next = _entry_list;
135     _entry_list = &node;
136     OrderAccess::fence();
137     if (_owner == NULL && Atomic::replace_if_null(&_owner, self)) {
138       _entry_list = node._next;
139       RawMonitor_lock->unlock();



140       return;
141     }
142     RawMonitor_lock->unlock();
143     while (node._t_state == QNode::TS_ENTER) {
144       self->_ParkEvent->park();
145     }
146   }
147 }
148 
149 void JvmtiRawMonitor::simple_exit(Thread* self) {
150   guarantee(_owner == self, "invariant");
151   Atomic::release_store(&_owner, (Thread*)NULL);
152   OrderAccess::fence();



153   if (_entry_list == NULL) {
154     return;
155   }
156 
157   RawMonitor_lock->lock_without_safepoint_check();
158   QNode* w = _entry_list;
159   if (w != NULL) {
160     _entry_list = w->_next;
161   }
162   RawMonitor_lock->unlock();
163   if (w != NULL) {
164     guarantee(w ->_t_state == QNode::TS_ENTER, "invariant");
165     // Once we set _t_state to TS_RUN the waiting thread can complete
166     // simple_enter and 'w' is pointing into random stack space. So we have
167     // to ensure we extract the ParkEvent (which is in type-stable memory)
168     // before we set the state, and then don't access 'w'.
169     ParkEvent* ev = w->_event;
170     OrderAccess::loadstore();
171     w->_t_state = QNode::TS_RUN;
172     OrderAccess::fence();
173     ev->unpark();
174   }
175   return;
176 }
177 
178 inline void JvmtiRawMonitor::enqueue_waiter(QNode& node) {
179   node._notified = 0;
180   node._t_state = QNode::TS_WAIT;
181   RawMonitor_lock->lock_without_safepoint_check();
182   node._next = _wait_set;
183   _wait_set = &node;
184   RawMonitor_lock->unlock();
185 }
186 
187 inline void JvmtiRawMonitor::dequeue_waiter(QNode& node) {
188   // If thread still resides on the waitset then unlink it.
189   // Double-checked locking -- the usage is safe in this context
190   // as _t_state is volatile and the lock-unlock operators are
191   // serializing (barrier-equivalent).
192 
193   if (node._t_state == QNode::TS_WAIT) {
194     RawMonitor_lock->lock_without_safepoint_check();
195     if (node._t_state == QNode::TS_WAIT) {
196       // Simple O(n) unlink, but performance isn't critical here.
197       QNode* p;
198       QNode* q = NULL;
199       for (p = _wait_set; p != &node; p = p->_next) {
200         q = p;
201       }
202       guarantee(p == &node, "invariant");
203       if (q == NULL) {
204         guarantee (p == _wait_set, "invariant");
205         _wait_set = p->_next;
206       } else {
207         guarantee(p == q->_next, "invariant");
208         q->_next = p->_next;
209       }
210       node._t_state = QNode::TS_RUN;
211     }
212     RawMonitor_lock->unlock();
213   }
214 
215   guarantee(node._t_state == QNode::TS_RUN, "invariant");
216 }
217 
218 // simple_wait is not quite so simple as we have to deal with the interaction
219 // with the Thread interrupt state, which resides in the java.lang.Thread object.
220 // That state must only be accessed while _thread_in_vm and requires proper thread-state
221 // transitions.
222 // Returns M_OK usually, but M_INTERRUPTED if the thread is a JavaThread and was
223 // interrupted.
224 // Note:
225 //  - simple_wait never reenters the monitor.
226 //  - A JavaThread must be in native.
227 int JvmtiRawMonitor::simple_wait(Thread* self, jlong millis) {
228   guarantee(_owner == self  , "invariant");
229   guarantee(_recursions == 0, "invariant");
230 
231   QNode node(self);
232   enqueue_waiter(node);
233 
234   simple_exit(self);
235   guarantee(_owner != self, "invariant");
236 
237   int ret = M_OK;
238   if (self->is_Java_thread()) {
239     JavaThread* jt = JavaThread::cast(self);
240     guarantee(jt->thread_state() == _thread_in_native, "invariant");
241     {
242       // This transition must be after we exited the monitor.
243       ThreadInVMfromNative tivmfn(jt);
244       if (jt->is_interrupted(true)) {
245         ret = M_INTERRUPTED;
246       } else {
247         ThreadBlockInVM tbivm(jt);
248         if (millis <= 0) {
249           self->_ParkEvent->park();
250         } else {
251           self->_ParkEvent->park(millis);
252         }
253         // Return to VM before post-check of interrupt state
254       }
255       if (jt->is_interrupted(true)) {
256         ret = M_INTERRUPTED;
257       }
258     }
259   } else {
260     if (millis <= 0) {
261       self->_ParkEvent->park();
262     } else {
263       self->_ParkEvent->park(millis);
264     }
265   }
266 
267   dequeue_waiter(node);
268 
269   return ret;
270 }
271 
272 void JvmtiRawMonitor::simple_notify(Thread* self, bool all) {
273   guarantee(_owner == self, "invariant");
274   if (_wait_set == NULL) {
275     return;
276   }
277 
278   // We have two options:
279   // A. Transfer the threads from the _wait_set to the _entry_list
280   // B. Remove the thread from the _wait_set and unpark() it.
281   //
282   // We use (B), which is crude and results in lots of futile
283   // context switching.  In particular (B) induces lots of contention.
284 
285   ParkEvent* ev = NULL;       // consider using a small auto array ...
286   RawMonitor_lock->lock_without_safepoint_check();
287   for (;;) {
288     QNode* w = _wait_set;
289     if (w == NULL) break;
290     _wait_set = w->_next;
291     if (ev != NULL) {
292       ev->unpark();
293       ev = NULL;
294     }
295     ev = w->_event;
296     OrderAccess::loadstore();
297     w->_t_state = QNode::TS_RUN;
298     OrderAccess::storeload();
299     if (!all) {
300       break;
301     }
302   }
303   RawMonitor_lock->unlock();
304   if (ev != NULL) {
305     ev->unpark();
306   }
307   return;
308 }
309 
310 void JvmtiRawMonitor::ExitOnSuspend::operator()(JavaThread* current) {
311   // We must exit the monitor in case of a safepoint.
312   _rm->simple_exit(current);
313   _rm_exited = true;
314 }
315 
316 // JavaThreads will enter here with state _thread_in_native.
317 void JvmtiRawMonitor::raw_enter(Thread* self) {
318   // TODO Atomic::load on _owner field
319   if (_owner == self) {
320     _recursions++;
321     return;
322   }
323 
324   self->set_current_pending_raw_monitor(this);
325 
326   if (!self->is_Java_thread()) {
327     simple_enter(self);
328   } else {
329     JavaThread* jt = JavaThread::cast(self);
330     guarantee(jt->thread_state() == _thread_in_native, "invariant");
331     ThreadInVMfromNative tivmfn(jt);
332     for (;;) {
333       ExitOnSuspend eos(this);
334       {
335         ThreadBlockInVMPreprocess<ExitOnSuspend> tbivmp(jt, eos, true /* allow_suspend */);
336         simple_enter(jt);
337       }
338       if (!eos.monitor_exited()) {
339         break;
340       }
341     }
342   }
343 
344   self->set_current_pending_raw_monitor(NULL);
345 
346   guarantee(_owner == self, "invariant");
347   guarantee(_recursions == 0, "invariant");
348 }
349 
350 int JvmtiRawMonitor::raw_exit(Thread* self) {
351   if (self != _owner) {
352     return M_ILLEGAL_MONITOR_STATE;
353   }
354   if (_recursions > 0) {
355     _recursions--;
356   } else {
357     simple_exit(self);
358   }
359 
360   return M_OK;
361 }
362 
363 int JvmtiRawMonitor::raw_wait(jlong millis, Thread* self) {
364   if (self != _owner) {
365     return M_ILLEGAL_MONITOR_STATE;
366   }
367 
368   int ret = M_OK;
369 
370   // To avoid spurious wakeups we reset the parkevent. This is strictly optional.
371   // The caller must be able to tolerate spurious returns from raw_wait().
372   self->_ParkEvent->reset();
373   OrderAccess::fence();
374 
375   intptr_t save = _recursions;
376   _recursions = 0;
377   ret = simple_wait(self, millis);
378 
379   // Now we need to re-enter the monitor. For JavaThreads
380   // we need to manage suspend requests.
381   if (self->is_Java_thread()) { // JavaThread re-enter
382     JavaThread* jt = JavaThread::cast(self);
383     ThreadInVMfromNative tivmfn(jt);
384     for (;;) {
385       ExitOnSuspend eos(this);
386       {
387         ThreadBlockInVMPreprocess<ExitOnSuspend> tbivmp(jt, eos, true /* allow_suspend */);
388         simple_enter(jt);
389       }
390       if (!eos.monitor_exited()) {
391         break;
392       }
393     }
394     if (jt->is_interrupted(true)) {
395       ret = M_INTERRUPTED;
396     }
397   } else { // Non-JavaThread re-enter
398     assert(ret != M_INTERRUPTED, "Only JavaThreads can be interrupted");
399     simple_enter(self);
400   }
401 
402   _recursions = save;
403 
404   guarantee(self == _owner, "invariant");
405   return ret;
406 }
407 
408 int JvmtiRawMonitor::raw_notify(Thread* self) {
409   if (self != _owner) {
410     return M_ILLEGAL_MONITOR_STATE;
411   }
412   simple_notify(self, false);
413   return M_OK;
414 }
415 
416 int JvmtiRawMonitor::raw_notifyAll(Thread* self) {
417   if (self != _owner) {
418     return M_ILLEGAL_MONITOR_STATE;
419   }
420   simple_notify(self, true);
421   return M_OK;
422 }
--- EOF ---