src/hotspot/share/prims/jvmtiRawMonitor.cpp
author phh
Sat, 30 Nov 2019 14:33:05 -0800
changeset 59330 5b96c12f909d
parent 59252 623722a6aeb9
permissions -rw-r--r--
8234541: C1 emits an empty message when it inlines successfully Summary: Use "inline" as the message when successfull Reviewed-by: thartmann, mdoerr Contributed-by: navy.xliu@gmail.com
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
     1
/*
54469
8592226f5cd3 8221584: SIGSEGV in os::PlatformEvent::unpark() in JvmtiRawMonitor::raw_exit while posting method exit event
dholmes
parents: 51702
diff changeset
     2
 * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
     4
 *
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
     7
 * published by the Free Software Foundation.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
     8
 *
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    13
 * accompanied this code).
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    14
 *
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    18
 *
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    21
 * questions.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    22
 *
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    23
 */
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    24
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6975
diff changeset
    25
#include "precompiled.hpp"
49360
886acec3b4c6 8199275: Fix inclusions of allocation.inline.hpp
stefank
parents: 48488
diff changeset
    26
#include "memory/allocation.inline.hpp"
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6975
diff changeset
    27
#include "prims/jvmtiRawMonitor.hpp"
40655
9f644073d3a0 8157907: Incorrect inclusion of atomic.hpp instead of atomic.inline.hpp
dholmes
parents: 25351
diff changeset
    28
#include "runtime/atomic.hpp"
49449
ef5d5d343e2a 8199263: Split interfaceSupport.hpp to not require including .inline.hpp files
coleenp
parents: 49360
diff changeset
    29
#include "runtime/interfaceSupport.inline.hpp"
50429
83aec1d357d4 8204301: Make OrderAccess functions available to hpp rather than inline.hpp files
coleenp
parents: 49449
diff changeset
    30
#include "runtime/orderAccess.hpp"
24351
61b33cc6d3cf 8042195: Introduce umbrella header orderAccess.inline.hpp.
goetz
parents: 13963
diff changeset
    31
#include "runtime/thread.inline.hpp"
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    32
58488
165b193b30dd 8231289: Disentangle JvmtiRawMonitor from ObjectMonitor and clean it up
dholmes
parents: 58196
diff changeset
    33
JvmtiRawMonitor::QNode::QNode(Thread* thread) : _next(NULL), _prev(NULL),
165b193b30dd 8231289: Disentangle JvmtiRawMonitor from ObjectMonitor and clean it up
dholmes
parents: 58196
diff changeset
    34
                                                _event(thread->_ParkEvent),
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
    35
                                                _notified(0), _t_state(TS_RUN) {
58488
165b193b30dd 8231289: Disentangle JvmtiRawMonitor from ObjectMonitor and clean it up
dholmes
parents: 58196
diff changeset
    36
}
165b193b30dd 8231289: Disentangle JvmtiRawMonitor from ObjectMonitor and clean it up
dholmes
parents: 58196
diff changeset
    37
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
    38
GrowableArray<JvmtiRawMonitor*>* JvmtiPendingMonitors::_monitors =
58488
165b193b30dd 8231289: Disentangle JvmtiRawMonitor from ObjectMonitor and clean it up
dholmes
parents: 58196
diff changeset
    39
  new (ResourceObj::C_HEAP, mtInternal) GrowableArray<JvmtiRawMonitor*>(1, true);
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    40
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    41
void JvmtiPendingMonitors::transition_raw_monitors() {
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    42
  assert((Threads::number_of_threads()==1),
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
    43
         "Java thread has not been created yet or more than one java thread "
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
    44
         "is running. Raw monitor transition will not work");
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
    45
  JavaThread* current_java_thread = JavaThread::current();
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    46
  assert(current_java_thread->thread_state() == _thread_in_vm, "Must be in vm");
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
    47
  for (int i = 0; i < count(); i++) {
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
    48
    JvmtiRawMonitor* rmonitor = monitors()->at(i);
58488
165b193b30dd 8231289: Disentangle JvmtiRawMonitor from ObjectMonitor and clean it up
dholmes
parents: 58196
diff changeset
    49
    rmonitor->raw_enter(current_java_thread);
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    50
  }
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    51
  // pending monitors are converted to real monitor so delete them all.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    52
  dispose();
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    53
}
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    54
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    55
//
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    56
// class JvmtiRawMonitor
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    57
//
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    58
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
    59
JvmtiRawMonitor::JvmtiRawMonitor(const char* name) : _owner(NULL),
58488
165b193b30dd 8231289: Disentangle JvmtiRawMonitor from ObjectMonitor and clean it up
dholmes
parents: 58196
diff changeset
    60
                                                     _recursions(0),
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
    61
                                                     _entry_list(NULL),
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
    62
                                                     _wait_set(NULL),
58488
165b193b30dd 8231289: Disentangle JvmtiRawMonitor from ObjectMonitor and clean it up
dholmes
parents: 58196
diff changeset
    63
                                                     _waiters(0),
165b193b30dd 8231289: Disentangle JvmtiRawMonitor from ObjectMonitor and clean it up
dholmes
parents: 58196
diff changeset
    64
                                                     _magic(JVMTI_RM_MAGIC),
165b193b30dd 8231289: Disentangle JvmtiRawMonitor from ObjectMonitor and clean it up
dholmes
parents: 58196
diff changeset
    65
                                                     _name(NULL) {
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    66
#ifdef ASSERT
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 7397
diff changeset
    67
  _name = strcpy(NEW_C_HEAP_ARRAY(char, strlen(name) + 1, mtInternal), name);
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    68
#endif
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    69
}
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    70
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    71
JvmtiRawMonitor::~JvmtiRawMonitor() {
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    72
#ifdef ASSERT
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    73
  FreeHeap(_name);
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    74
#endif
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    75
  _magic = 0;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    76
}
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    77
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    78
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    79
bool
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    80
JvmtiRawMonitor::is_valid() {
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    81
  int value = 0;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    82
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    83
  // This object might not be a JvmtiRawMonitor so we can't assume
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    84
  // the _magic field is properly aligned. Get the value in a safe
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    85
  // way and then check against JVMTI_RM_MAGIC.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    86
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    87
  switch (sizeof(_magic)) {
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    88
  case 2:
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    89
    value = Bytes::get_native_u2((address)&_magic);
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    90
    break;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    91
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    92
  case 4:
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    93
    value = Bytes::get_native_u4((address)&_magic);
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    94
    break;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    95
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    96
  case 8:
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    97
    value = Bytes::get_native_u8((address)&_magic);
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    98
    break;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
    99
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   100
  default:
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   101
    guarantee(false, "_magic field is an unexpected size");
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   102
  }
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   103
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   104
  return value == JVMTI_RM_MAGIC;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   105
}
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   106
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   107
// -------------------------------------------------------------------------
58488
165b193b30dd 8231289: Disentangle JvmtiRawMonitor from ObjectMonitor and clean it up
dholmes
parents: 58196
diff changeset
   108
// The JVMTI raw monitor subsystem is entirely distinct from normal
165b193b30dd 8231289: Disentangle JvmtiRawMonitor from ObjectMonitor and clean it up
dholmes
parents: 58196
diff changeset
   109
// java-synchronization or jni-synchronization.  JVMTI raw monitors are not
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   110
// associated with objects.  They can be implemented in any manner
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   111
// that makes sense.  The original implementors decided to piggy-back
58488
165b193b30dd 8231289: Disentangle JvmtiRawMonitor from ObjectMonitor and clean it up
dholmes
parents: 58196
diff changeset
   112
// the raw-monitor implementation on the existing Java ObjectMonitor mechanism.
165b193b30dd 8231289: Disentangle JvmtiRawMonitor from ObjectMonitor and clean it up
dholmes
parents: 58196
diff changeset
   113
// Now we just use a simplified form of that ObjectMonitor code.
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   114
//
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   115
// Note that we use the single RawMonitor_lock to protect queue operations for
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   116
// _all_ raw monitors.  This is a scalability impediment, but since raw monitor usage
58488
165b193b30dd 8231289: Disentangle JvmtiRawMonitor from ObjectMonitor and clean it up
dholmes
parents: 58196
diff changeset
   117
// is fairly rare, this is not of concern.  The RawMonitor_lock can not
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   118
// be held indefinitely.  The critical sections must be short and bounded.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   119
//
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   120
// -------------------------------------------------------------------------
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   121
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   122
void JvmtiRawMonitor::simple_enter(Thread* self) {
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   123
  for (;;) {
59252
623722a6aeb9 8234740: Harmonize parameter order in Atomic - cmpxchg
stefank
parents: 59247
diff changeset
   124
    if (Atomic::replace_if_null(&_owner, self)) {
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   125
      return;
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   126
    }
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   127
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   128
    QNode node(self);
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   129
    self->_ParkEvent->reset();     // strictly optional
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   130
    node._t_state = QNode::TS_ENTER;
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   131
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   132
    RawMonitor_lock->lock_without_safepoint_check();
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   133
    node._next = _entry_list;
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   134
    _entry_list = &node;
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   135
    OrderAccess::fence();
59252
623722a6aeb9 8234740: Harmonize parameter order in Atomic - cmpxchg
stefank
parents: 59247
diff changeset
   136
    if (_owner == NULL && Atomic::replace_if_null(&_owner, self)) {
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   137
      _entry_list = node._next;
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   138
      RawMonitor_lock->unlock();
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   139
      return;
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   140
    }
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   141
    RawMonitor_lock->unlock();
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   142
    while (node._t_state == QNode::TS_ENTER) {
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   143
      self->_ParkEvent->park();
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   144
    }
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   145
  }
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   146
}
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   147
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   148
void JvmtiRawMonitor::simple_exit(Thread* self) {
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   149
  guarantee(_owner == self, "invariant");
59247
56bf71d64d51 8234562: Move OrderAccess::release_store*/load_acquire to Atomic
stefank
parents: 59105
diff changeset
   150
  Atomic::release_store(&_owner, (Thread*)NULL);
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   151
  OrderAccess::fence();
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   152
  if (_entry_list == NULL) {
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   153
    return;
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   154
  }
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   155
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   156
  RawMonitor_lock->lock_without_safepoint_check();
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   157
  QNode* w = _entry_list;
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   158
  if (w != NULL) {
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   159
    _entry_list = w->_next;
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   160
  }
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   161
  RawMonitor_lock->unlock();
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   162
  if (w != NULL) {
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   163
    guarantee(w ->_t_state == QNode::TS_ENTER, "invariant");
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   164
    // Once we set _t_state to TS_RUN the waiting thread can complete
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   165
    // simple_enter and 'w' is pointing into random stack space. So we have
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   166
    // to ensure we extract the ParkEvent (which is in type-stable memory)
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   167
    // before we set the state, and then don't access 'w'.
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   168
    ParkEvent* ev = w->_event;
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   169
    OrderAccess::loadstore();
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   170
    w->_t_state = QNode::TS_RUN;
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   171
    OrderAccess::fence();
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   172
    ev->unpark();
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   173
  }
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   174
  return;
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   175
}
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   176
59105
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   177
inline void JvmtiRawMonitor::enqueue_waiter(QNode& node) {
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   178
  node._notified = 0;
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   179
  node._t_state = QNode::TS_WAIT;
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   180
  RawMonitor_lock->lock_without_safepoint_check();
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   181
  node._next = _wait_set;
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   182
  _wait_set = &node;
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   183
  RawMonitor_lock->unlock();
59105
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   184
}
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   185
59105
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   186
inline void JvmtiRawMonitor::dequeue_waiter(QNode& node) {
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   187
  // If thread still resides on the waitset then unlink it.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   188
  // Double-checked locking -- the usage is safe in this context
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   189
  // as _t_state is volatile and the lock-unlock operators are
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   190
  // serializing (barrier-equivalent).
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   191
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   192
  if (node._t_state == QNode::TS_WAIT) {
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   193
    RawMonitor_lock->lock_without_safepoint_check();
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   194
    if (node._t_state == QNode::TS_WAIT) {
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   195
      // Simple O(n) unlink, but performance isn't critical here.
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   196
      QNode* p;
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   197
      QNode* q = NULL;
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   198
      for (p = _wait_set; p != &node; p = p->_next) {
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   199
        q = p;
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   200
      }
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   201
      guarantee(p == &node, "invariant");
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   202
      if (q == NULL) {
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   203
        guarantee (p == _wait_set, "invariant");
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   204
        _wait_set = p->_next;
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   205
      } else {
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   206
        guarantee(p == q->_next, "invariant");
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   207
        q->_next = p->_next;
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   208
      }
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   209
      node._t_state = QNode::TS_RUN;
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   210
    }
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   211
    RawMonitor_lock->unlock();
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   212
  }
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   213
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   214
  guarantee(node._t_state == QNode::TS_RUN, "invariant");
59105
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   215
}
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   216
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   217
// simple_wait is not quite so simple as we have to deal with the interaction
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   218
// with the Thread interrupt state, which resides in the java.lang.Thread object.
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   219
// That state must only be accessed while _thread_in_vm and requires proper thread-state
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   220
// transitions. However, we cannot perform such transitions whilst we hold the RawMonitor,
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   221
// else we can deadlock with the VMThread (which may also use RawMonitors as part of
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   222
// executing various callbacks).
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   223
// Returns M_OK usually, but M_INTERRUPTED if the thread is a JavaThread and was
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   224
// interrupted.
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   225
int JvmtiRawMonitor::simple_wait(Thread* self, jlong millis) {
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   226
  guarantee(_owner == self  , "invariant");
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   227
  guarantee(_recursions == 0, "invariant");
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   228
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   229
  QNode node(self);
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   230
  enqueue_waiter(node);
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   231
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   232
  simple_exit(self);
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   233
  guarantee(_owner != self, "invariant");
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   234
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   235
  int ret = M_OK;
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   236
  if (self->is_Java_thread()) {
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   237
    JavaThread* jt = (JavaThread*) self;
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   238
    // Transition to VM so we can check interrupt state
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   239
    ThreadInVMfromNative tivm(jt);
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   240
    if (jt->is_interrupted(true)) {
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   241
        ret = M_INTERRUPTED;
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   242
    } else {
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   243
      ThreadBlockInVM tbivm(jt);
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   244
      jt->set_suspend_equivalent();
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   245
      if (millis <= 0) {
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   246
        self->_ParkEvent->park();
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   247
      } else {
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   248
        self->_ParkEvent->park(millis);
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   249
      }
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   250
      // Return to VM before post-check of interrupt state
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   251
    }
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   252
    if (jt->is_interrupted(true)) {
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   253
      ret = M_INTERRUPTED;
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   254
    }
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   255
  } else {
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   256
    if (millis <= 0) {
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   257
      self->_ParkEvent->park();
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   258
    } else {
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   259
      self->_ParkEvent->park(millis);
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   260
    }
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   261
  }
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   262
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   263
  dequeue_waiter(node);
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   264
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   265
  simple_enter(self);
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   266
  guarantee(_owner == self, "invariant");
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   267
  guarantee(_recursions == 0, "invariant");
59105
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   268
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   269
  return ret;
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   270
}
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   271
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   272
void JvmtiRawMonitor::simple_notify(Thread* self, bool all) {
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   273
  guarantee(_owner == self, "invariant");
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   274
  if (_wait_set == NULL) {
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   275
    return;
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   276
  }
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   277
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   278
  // We have two options:
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   279
  // A. Transfer the threads from the _wait_set to the _entry_list
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   280
  // B. Remove the thread from the _wait_set and unpark() it.
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   281
  //
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   282
  // We use (B), which is crude and results in lots of futile
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   283
  // context switching.  In particular (B) induces lots of contention.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   284
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   285
  ParkEvent* ev = NULL;       // consider using a small auto array ...
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   286
  RawMonitor_lock->lock_without_safepoint_check();
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   287
  for (;;) {
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   288
    QNode* w = _wait_set;
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   289
    if (w == NULL) break;
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   290
    _wait_set = w->_next;
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   291
    if (ev != NULL) {
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   292
      ev->unpark();
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   293
      ev = NULL;
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   294
    }
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   295
    ev = w->_event;
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   296
    OrderAccess::loadstore();
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   297
    w->_t_state = QNode::TS_RUN;
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   298
    OrderAccess::storeload();
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   299
    if (!all) {
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   300
      break;
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   301
    }
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   302
  }
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   303
  RawMonitor_lock->unlock();
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   304
  if (ev != NULL) {
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   305
    ev->unpark();
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   306
  }
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   307
  return;
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   308
}
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   309
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   310
// Any JavaThread will enter here with state _thread_blocked
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   311
void JvmtiRawMonitor::raw_enter(Thread* self) {
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   312
  void* contended;
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   313
  JavaThread* jt = NULL;
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   314
  // don't enter raw monitor if thread is being externally suspended, it will
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   315
  // surprise the suspender if a "suspended" thread can still enter monitor
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   316
  if (self->is_Java_thread()) {
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   317
    jt = (JavaThread*)self;
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   318
    jt->SR_lock()->lock_without_safepoint_check();
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   319
    while (jt->is_external_suspend()) {
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   320
      jt->SR_lock()->unlock();
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   321
      jt->java_suspend_self();
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   322
      jt->SR_lock()->lock_without_safepoint_check();
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   323
    }
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   324
    // guarded by SR_lock to avoid racing with new external suspend requests.
59252
623722a6aeb9 8234740: Harmonize parameter order in Atomic - cmpxchg
stefank
parents: 59247
diff changeset
   325
    contended = Atomic::cmpxchg(&_owner, (Thread*)NULL, jt);
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   326
    jt->SR_lock()->unlock();
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   327
  } else {
59252
623722a6aeb9 8234740: Harmonize parameter order in Atomic - cmpxchg
stefank
parents: 59247
diff changeset
   328
    contended = Atomic::cmpxchg(&_owner, (Thread*)NULL, self);
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   329
  }
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   330
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   331
  if (contended == self) {
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   332
    _recursions++;
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   333
    return;
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   334
  }
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   335
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   336
  if (contended == NULL) {
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   337
    guarantee(_owner == self, "invariant");
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   338
    guarantee(_recursions == 0, "invariant");
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   339
    return;
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   340
  }
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   341
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   342
  self->set_current_pending_raw_monitor(this);
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   343
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   344
  if (!self->is_Java_thread()) {
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   345
    simple_enter(self);
58488
165b193b30dd 8231289: Disentangle JvmtiRawMonitor from ObjectMonitor and clean it up
dholmes
parents: 58196
diff changeset
   346
  } else {
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   347
    guarantee(jt->thread_state() == _thread_blocked, "invariant");
58488
165b193b30dd 8231289: Disentangle JvmtiRawMonitor from ObjectMonitor and clean it up
dholmes
parents: 58196
diff changeset
   348
    for (;;) {
165b193b30dd 8231289: Disentangle JvmtiRawMonitor from ObjectMonitor and clean it up
dholmes
parents: 58196
diff changeset
   349
      jt->set_suspend_equivalent();
165b193b30dd 8231289: Disentangle JvmtiRawMonitor from ObjectMonitor and clean it up
dholmes
parents: 58196
diff changeset
   350
      // cleared by handle_special_suspend_equivalent_condition() or
165b193b30dd 8231289: Disentangle JvmtiRawMonitor from ObjectMonitor and clean it up
dholmes
parents: 58196
diff changeset
   351
      // java_suspend_self()
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   352
      simple_enter(jt);
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   353
58488
165b193b30dd 8231289: Disentangle JvmtiRawMonitor from ObjectMonitor and clean it up
dholmes
parents: 58196
diff changeset
   354
      // were we externally suspended while we were waiting?
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   355
      if (!jt->handle_special_suspend_equivalent_condition()) {
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   356
        break;
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   357
      }
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   358
58488
165b193b30dd 8231289: Disentangle JvmtiRawMonitor from ObjectMonitor and clean it up
dholmes
parents: 58196
diff changeset
   359
      // This thread was externally suspended
165b193b30dd 8231289: Disentangle JvmtiRawMonitor from ObjectMonitor and clean it up
dholmes
parents: 58196
diff changeset
   360
      // We have reentered the contended monitor, but while we were
165b193b30dd 8231289: Disentangle JvmtiRawMonitor from ObjectMonitor and clean it up
dholmes
parents: 58196
diff changeset
   361
      // waiting another thread suspended us. We don't want to reenter
165b193b30dd 8231289: Disentangle JvmtiRawMonitor from ObjectMonitor and clean it up
dholmes
parents: 58196
diff changeset
   362
      // the monitor while suspended because that would surprise the
165b193b30dd 8231289: Disentangle JvmtiRawMonitor from ObjectMonitor and clean it up
dholmes
parents: 58196
diff changeset
   363
      // thread that suspended us.
165b193b30dd 8231289: Disentangle JvmtiRawMonitor from ObjectMonitor and clean it up
dholmes
parents: 58196
diff changeset
   364
      //
165b193b30dd 8231289: Disentangle JvmtiRawMonitor from ObjectMonitor and clean it up
dholmes
parents: 58196
diff changeset
   365
      // Drop the lock
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   366
      simple_exit(jt);
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   367
58488
165b193b30dd 8231289: Disentangle JvmtiRawMonitor from ObjectMonitor and clean it up
dholmes
parents: 58196
diff changeset
   368
      jt->java_suspend_self();
165b193b30dd 8231289: Disentangle JvmtiRawMonitor from ObjectMonitor and clean it up
dholmes
parents: 58196
diff changeset
   369
    }
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   370
  }
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   371
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   372
  self->set_current_pending_raw_monitor(NULL);
58488
165b193b30dd 8231289: Disentangle JvmtiRawMonitor from ObjectMonitor and clean it up
dholmes
parents: 58196
diff changeset
   373
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   374
  guarantee(_owner == self, "invariant");
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   375
  guarantee(_recursions == 0, "invariant");
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   376
}
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   377
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   378
int JvmtiRawMonitor::raw_exit(Thread* self) {
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   379
  if (self != _owner) {
58488
165b193b30dd 8231289: Disentangle JvmtiRawMonitor from ObjectMonitor and clean it up
dholmes
parents: 58196
diff changeset
   380
    return M_ILLEGAL_MONITOR_STATE;
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   381
  }
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   382
  if (_recursions > 0) {
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   383
    _recursions--;
58488
165b193b30dd 8231289: Disentangle JvmtiRawMonitor from ObjectMonitor and clean it up
dholmes
parents: 58196
diff changeset
   384
  } else {
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   385
    simple_exit(self);
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   386
  }
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   387
58488
165b193b30dd 8231289: Disentangle JvmtiRawMonitor from ObjectMonitor and clean it up
dholmes
parents: 58196
diff changeset
   388
  return M_OK;
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   389
}
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   390
59105
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   391
int JvmtiRawMonitor::raw_wait(jlong millis, Thread* self) {
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   392
  if (self != _owner) {
58488
165b193b30dd 8231289: Disentangle JvmtiRawMonitor from ObjectMonitor and clean it up
dholmes
parents: 58196
diff changeset
   393
    return M_ILLEGAL_MONITOR_STATE;
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   394
  }
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   395
59105
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   396
  int ret = M_OK;
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   397
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   398
  // To avoid spurious wakeups we reset the parkevent. This is strictly optional.
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   399
  // The caller must be able to tolerate spurious returns from raw_wait().
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   400
  self->_ParkEvent->reset();
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   401
  OrderAccess::fence();
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   402
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   403
  intptr_t save = _recursions;
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   404
  _recursions = 0;
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   405
  _waiters++;
59105
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   406
  ret = simple_wait(self, millis);
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   407
  _recursions = save;
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   408
  _waiters--;
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   409
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   410
  guarantee(self == _owner, "invariant");
59105
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   411
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   412
  if (self->is_Java_thread()) {
59105
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   413
    JavaThread* jt = (JavaThread*)self;
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   414
    for (;;) {
59105
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   415
      jt->set_suspend_equivalent();
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   416
      if (!jt->handle_special_suspend_equivalent_condition()) {
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   417
        break;
59105
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   418
      } else {
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   419
        // We've been suspended whilst waiting and so we have to
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   420
        // relinquish the raw monitor until we are resumed. Of course
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   421
        // after reacquiring we have to re-check for suspension again.
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   422
        // Suspension requires we are _thread_blocked, and we also have to
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   423
        // recheck for being interrupted.
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   424
        simple_exit(jt);
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   425
        {
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   426
          ThreadInVMfromNative tivm(jt);
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   427
          {
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   428
            ThreadBlockInVM tbivm(jt);
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   429
            jt->java_suspend_self();
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   430
          }
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   431
          if (jt->is_interrupted(true)) {
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   432
            ret = M_INTERRUPTED;
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   433
          }
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   434
        }
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   435
        simple_enter(jt);
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   436
      }
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   437
    }
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   438
    guarantee(jt == _owner, "invariant");
59105
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   439
  } else {
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   440
    assert(ret != M_INTERRUPTED, "Only JavaThreads can be interrupted");
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   441
  }
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   442
59105
76ae9aa0e794 8233549: Thread interrupted state must only be accessed when not in a safepoint-safe state
dholmes
parents: 58509
diff changeset
   443
  return ret;
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   444
}
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   445
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   446
int JvmtiRawMonitor::raw_notify(Thread* self) {
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   447
  if (self != _owner) {
58488
165b193b30dd 8231289: Disentangle JvmtiRawMonitor from ObjectMonitor and clean it up
dholmes
parents: 58196
diff changeset
   448
    return M_ILLEGAL_MONITOR_STATE;
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   449
  }
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   450
  simple_notify(self, false);
58488
165b193b30dd 8231289: Disentangle JvmtiRawMonitor from ObjectMonitor and clean it up
dholmes
parents: 58196
diff changeset
   451
  return M_OK;
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents:
diff changeset
   452
}
58509
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   453
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   454
int JvmtiRawMonitor::raw_notifyAll(Thread* self) {
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   455
  if (self != _owner) {
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   456
    return M_ILLEGAL_MONITOR_STATE;
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   457
  }
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   458
  simple_notify(self, true);
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   459
  return M_OK;
7b41c88f8432 8231737: Cleanup JvmtiRawMonitor code
dholmes
parents: 58488
diff changeset
   460
}