jdk

Форк
0
/
test_mutex.cpp 
334 строки · 13.3 Кб
1
/*
2
 * Copyright (c) 2020, 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
#include "precompiled.hpp"
25
#include "runtime/interfaceSupport.inline.hpp"
26
#include "runtime/mutex.hpp"
27
#include "runtime/mutexLocker.hpp"
28
#include "runtime/thread.hpp"
29
#include "utilities/formatBuffer.hpp"
30
#include "threadHelper.inline.hpp"
31
#include "unittest.hpp"
32

33
const int iterations = 10;
34
static Mutex* m[iterations];
35
static int i = 0;
36

37
static void create_mutex(Thread* thr) {
38
  m[i] = new Mutex(Mutex::nosafepoint, FormatBuffer<128>("MyLock#%u_lock", i));
39
  i++;
40
}
41

42
TEST_VM(MutexName, mutex_name) {
43
  // Create mutexes in threads, where the names are created on the thread
44
  // stacks and then check that their names are correct.
45
  for (int i = 0; i < iterations; i++) {
46
    nomt_test_doer(create_mutex);
47
  }
48
  for (int i = 0; i < iterations; i++) {
49
    FormatBuffer<128> f("MyLock#%u_lock", i);
50
    ASSERT_STREQ(m[i]->name(), f.buffer()) << "Wrong name!";
51
  }
52
}
53

54
#ifdef ASSERT
55

56
const Mutex::Rank rankA = Mutex::safepoint-5;
57
const Mutex::Rank rankAplusOne = Mutex::safepoint-4;
58
const Mutex::Rank rankAplusTwo = Mutex::safepoint-3;
59

60
TEST_OTHER_VM(MutexRank, mutex_lock_rank_in_order) {
61
  JavaThread* THREAD = JavaThread::current();
62
  ThreadInVMfromNative invm(THREAD);
63

64
  Mutex* mutex_rankA = new Mutex(rankA, "mutex_rankA");
65
  Mutex* mutex_rankA_plus_one = new Mutex(rankAplusOne, "mutex_rankA_plus_one");
66

67
  mutex_rankA_plus_one->lock();
68
  mutex_rankA->lock();
69
  mutex_rankA->unlock();
70
  mutex_rankA_plus_one->unlock();
71
}
72

73
TEST_VM_ASSERT_MSG(MutexRank, mutex_lock_rank_out_of_orderA,
74
                   ".* Attempting to acquire lock mutex_rankA_plus_one/safepoint-4 out of order with lock mutex_rankA/safepoint-5 -- possible deadlock") {
75
  JavaThread* THREAD = JavaThread::current();
76
  ThreadInVMfromNative invm(THREAD);
77

78
  Mutex* mutex_rankA = new Mutex(rankA, "mutex_rankA");
79
  Mutex* mutex_rankA_plus_one = new Mutex(rankAplusOne, "mutex_rankA_plus_one");
80

81
  mutex_rankA->lock();
82
  mutex_rankA_plus_one->lock();
83
  mutex_rankA_plus_one->unlock();
84
  mutex_rankA->unlock();
85
}
86

87
TEST_VM_ASSERT_MSG(MutexRank, mutex_lock_rank_out_of_orderB,
88
                   ".* Attempting to acquire lock mutex_rankB/.* out of order with lock mutex_rankA/.* -- possible deadlock") {
89
  JavaThread* THREAD = JavaThread::current();
90
  ThreadInVMfromNative invm(THREAD);
91

92
  Mutex* mutex_rankA = new Mutex(rankA, "mutex_rankA");
93
  Mutex* mutex_rankB = new Mutex(rankA, "mutex_rankB");
94

95
  mutex_rankA->lock();
96
  mutex_rankB->lock();
97
  mutex_rankB->unlock();
98
  mutex_rankA->unlock();
99
}
100

101
TEST_OTHER_VM(MutexRank, mutex_trylock_rank_out_of_orderA) {
102
  JavaThread* THREAD = JavaThread::current();
103
  ThreadInVMfromNative invm(THREAD);
104

105
  Mutex* mutex_rankA = new Mutex(rankA, "mutex_rankA");
106
  Mutex* mutex_rankA_plus_one = new Mutex(rankAplusOne, "mutex_rankA_plus_one");
107
  Mutex* mutex_rankA_plus_two = new Mutex(rankAplusTwo, "mutex_rankA_plus_two");
108

109
  mutex_rankA_plus_one->lock();
110
  mutex_rankA_plus_two->try_lock_without_rank_check();
111
  mutex_rankA->lock();
112
  mutex_rankA->unlock();
113
  mutex_rankA_plus_two->unlock();
114
  mutex_rankA_plus_one->unlock();
115
}
116

117
TEST_VM_ASSERT_MSG(MutexRank, mutex_trylock_rank_out_of_orderB,
118
                   ".* Attempting to acquire lock mutex_rankA_plus_one/.* out of order with lock mutex_rankA/.* -- possible deadlock") {
119
  JavaThread* THREAD = JavaThread::current();
120
  ThreadInVMfromNative invm(THREAD);
121

122
  Mutex* mutex_rankA = new Mutex(rankA, "mutex_rankA");
123
  Mutex* mutex_rankA_plus_one = new Mutex(rankAplusOne, "mutex_rankA_plus_one");
124

125
  mutex_rankA->lock();
126
  mutex_rankA_plus_one->try_lock_without_rank_check();
127
  mutex_rankA_plus_one->unlock();
128
  mutex_rankA_plus_one->try_lock();
129
  mutex_rankA_plus_one->unlock();
130
  mutex_rankA->unlock();
131
}
132

133
TEST_VM_ASSERT_MSG(MutexRank, mutex_lock_event_nosafepoint,
134
                   ".* Attempting to acquire lock mutex_rank_nosafepoint/nosafepoint out of order with lock mutex_rank_event/event "
135
                   "-- possible deadlock") {
136
  JavaThread* THREAD = JavaThread::current();
137
  ThreadInVMfromNative invm(THREAD);
138

139
  Mutex* mutex_rank_event = new Mutex(Mutex::event, "mutex_rank_event");
140
  Mutex* mutex_rank_safepoint = new Mutex(Mutex::nosafepoint, "mutex_rank_nosafepoint");
141

142
  mutex_rank_event->lock_without_safepoint_check();
143
  mutex_rank_safepoint->lock_without_safepoint_check();
144
  mutex_rank_safepoint->unlock();
145
  mutex_rank_event->unlock();
146
}
147

148
TEST_VM_ASSERT_MSG(MutexRank, mutex_lock_tty_nosafepoint,
149
                   ".* Attempting to acquire lock mutex_rank_nosafepoint/nosafepoint out of order with lock mutex_rank_tty/tty "
150
                   "-- possible deadlock") {
151
  JavaThread* THREAD = JavaThread::current();
152
  ThreadInVMfromNative invm(THREAD);
153

154
  Mutex* mutex_rank_tty = new Mutex(Mutex::tty, "mutex_rank_tty");
155
  Mutex* mutex_rank_nosafepoint = new Mutex(Mutex::nosafepoint, "mutex_rank_nosafepoint");
156

157
  mutex_rank_tty->lock_without_safepoint_check();
158
  mutex_rank_nosafepoint->lock_without_safepoint_check();
159
  mutex_rank_nosafepoint->unlock();
160
  mutex_rank_tty->unlock();
161
}
162

163
TEST_OTHER_VM(MutexRank, monitor_wait_rank_in_order) {
164
  JavaThread* THREAD = JavaThread::current();
165
  ThreadInVMfromNative invm(THREAD);
166

167
  Monitor* monitor_rankA = new Monitor(rankA, "monitor_rankA");
168
  Monitor* monitor_rankA_plus_one = new Monitor(rankAplusOne, "monitor_rankA_plus_one");
169

170
  monitor_rankA_plus_one->lock();
171
  monitor_rankA->lock();
172
  monitor_rankA->wait(1);
173
  monitor_rankA->unlock();
174
  monitor_rankA_plus_one->unlock();
175
}
176

177
TEST_VM_ASSERT_MSG(MutexRank, monitor_wait_rank_out_of_order,
178
                   ".* Attempting to wait on monitor monitor_rankA_plus_one/.* while holding lock monitor_rankA/.* "
179
                   "-- possible deadlock. Should wait on the least ranked monitor from all owned locks.") {
180
  JavaThread* THREAD = JavaThread::current();
181
  ThreadInVMfromNative invm(THREAD);
182

183
  Monitor* monitor_rankA = new Monitor(rankA, "monitor_rankA");
184
  Monitor* monitor_rankA_plus_one = new Monitor(rankAplusOne, "monitor_rankA_plus_one");
185

186
  monitor_rankA_plus_one->lock();
187
  monitor_rankA->lock();
188
  monitor_rankA_plus_one->wait(1);
189
  monitor_rankA_plus_one->unlock();
190
  monitor_rankA->unlock();
191
}
192

193
TEST_VM_ASSERT_MSG(MutexRank, monitor_wait_rank_out_of_order_trylock,
194
                   ".* Attempting to wait on monitor monitor_rankA_plus_one/.* while holding lock monitor_rankA/.* "
195
                   "-- possible deadlock. Should wait on the least ranked monitor from all owned locks.") {
196
  JavaThread* THREAD = JavaThread::current();
197
  ThreadInVMfromNative invm(THREAD);
198

199
  Monitor* monitor_rankA = new Monitor(rankA, "monitor_rankA");
200
  Monitor* monitor_rankA_plus_one = new Monitor(rankAplusOne, "monitor_rankA_plus_one");
201

202
  monitor_rankA->lock();
203
  monitor_rankA_plus_one->try_lock_without_rank_check();
204
  monitor_rankA_plus_one->wait();
205
  monitor_rankA_plus_one->unlock();
206
  monitor_rankA->unlock();
207
}
208

209
TEST_VM_ASSERT_MSG(MutexRank, monitor_wait_rank_nosafepoint,
210
                   ".* Attempting to wait on monitor monitor_rank_nosafepoint_minus_one/.* while holding lock monitor_rank_nosafepoint/.*"
211
                   "-- possible deadlock. Should not block\\(wait\\) while holding a lock of rank nosafepoint or below.") {
212
  JavaThread* THREAD = JavaThread::current();
213
  ThreadInVMfromNative invm(THREAD);
214

215
  Monitor* monitor_rank_nosafepoint = new Monitor(Mutex::nosafepoint, "monitor_rank_nosafepoint");
216
  Monitor* monitor_rank_nosafepoint_minus_one = new Monitor(Mutex::nosafepoint - 1,
217
                                                            "monitor_rank_nosafepoint_minus_one");
218

219
  monitor_rank_nosafepoint->lock_without_safepoint_check();
220
  monitor_rank_nosafepoint_minus_one->lock_without_safepoint_check();
221
  monitor_rank_nosafepoint_minus_one->wait_without_safepoint_check(1);
222
  monitor_rank_nosafepoint_minus_one->unlock();
223
  monitor_rank_nosafepoint->unlock();
224
}
225

226
// NonJavaThreads can't wait while holding tty lock or below.
227
class VM_MutexWaitTTY : public VM_GTestExecuteAtSafepoint {
228
 public:
229
  void doit() {
230
    Monitor* monitor_rank_tty = new Monitor(Mutex::tty, "monitor_rank_tty");
231
    Monitor* monitor_rank_event = new Monitor(Mutex::event, "monitor_rank_event");
232

233
    monitor_rank_tty->lock_without_safepoint_check();
234
    monitor_rank_event->lock_without_safepoint_check();
235
    monitor_rank_event->wait_without_safepoint_check(1);
236
    monitor_rank_event->unlock();
237
    monitor_rank_tty->unlock();
238
  }
239
};
240

241
TEST_VM_ASSERT_MSG(MutexRank, monitor_wait_event_tty,
242
                   ".* Attempting to wait on monitor monitor_rank_event/event while holding lock monitor_rank_tty/tty "
243
                   "-- possible deadlock. Should not block\\(wait\\) while holding a lock of rank tty or below.") {
244
  VM_MutexWaitTTY op;
245
  ThreadInVMfromNative invm(JavaThread::current());
246
  VMThread::execute(&op);
247
}
248

249
TEST_VM_ASSERT_MSG(MutexRank, monitor_wait_tty_nosafepoint,
250
                   ".* Attempting to wait on monitor monitor_rank_tty/.* while holding lock monitor_rank_nosafepoint/.* "
251
                   "-- possible deadlock. Should not block\\(wait\\) while holding a lock of rank nosafepoint or below.") {
252
  JavaThread* THREAD = JavaThread::current();
253
  ThreadInVMfromNative invm(THREAD);
254

255
  Monitor* monitor_rank_nosafepoint = new Monitor(Mutex::nosafepoint, "monitor_rank_nosafepoint");
256
  Monitor* monitor_rank_tty = new Monitor(Mutex::tty, "monitor_rank_tty");
257

258
  monitor_rank_nosafepoint->lock_without_safepoint_check();
259
  monitor_rank_tty->lock_without_safepoint_check();
260
  monitor_rank_tty->wait_without_safepoint_check(1);
261
  monitor_rank_tty->unlock();
262
  monitor_rank_nosafepoint->unlock();
263
}
264

265
TEST_VM_ASSERT_MSG(MutexRank, monitor_nosafepoint_vm_block,
266
                   ".*Locks that don't check for safepoint should always allow the vm to block: monitor_rank_nosafepoint") {
267
  JavaThread* THREAD = JavaThread::current();
268
  ThreadInVMfromNative invm(THREAD);
269

270
  Monitor* monitor_rank_nosafepoint = new Monitor(Mutex::nosafepoint, "monitor_rank_nosafepoint", false);
271
  monitor_rank_nosafepoint->lock_without_safepoint_check();
272
  monitor_rank_nosafepoint->unlock();
273
}
274

275
TEST_VM_ASSERT_MSG(MutexRank, monitor_negative_rank,
276
                   ".*Bad lock rank") {
277
  JavaThread* THREAD = JavaThread::current();
278
  ThreadInVMfromNative invm(THREAD);
279

280
  Monitor* monitor_rank_broken = new Monitor(Mutex::safepoint-100, "monitor_rank_broken");
281
  monitor_rank_broken->lock_without_safepoint_check();
282
  monitor_rank_broken->unlock();
283
}
284

285
TEST_VM_ASSERT_MSG(MutexRank, monitor_overlapping_oopstorage_rank,
286
                   ".*Rank oopstorage-4 overlaps with tty-1") {
287
  JavaThread* THREAD = JavaThread::current();
288
  ThreadInVMfromNative invm(THREAD);
289

290
  Monitor* monitor_rank_broken = new Monitor(Mutex::oopstorage-4, "monitor_rank_broken");
291
}
292

293
TEST_VM_ASSERT_MSG(MutexRank, monitor_overlapping_safepoint_rank,
294
                   ".*Rank safepoint-40 overlaps with service-5") {
295
  JavaThread* THREAD = JavaThread::current();
296
  ThreadInVMfromNative invm(THREAD);
297

298
  Monitor* monitor_rank_broken = new Monitor(Mutex::safepoint-40, "monitor_rank_broken");
299
}
300

301
TEST_VM_ASSERT_MSG(MutexRank, monitor_overlapping_safepoint_rank2,
302
                   ".*Rank safepoint-1-39 overlaps with service-5") {
303
  JavaThread* THREAD = JavaThread::current();
304
  ThreadInVMfromNative invm(THREAD);
305

306
  Monitor* monitor_rank_ok = new Monitor(Mutex::safepoint-1, "monitor_rank_ok");
307
  Monitor* monitor_rank_broken = new Monitor(monitor_rank_ok->rank()-39, "monitor_rank_broken");
308
}
309

310
// Test mismatched safepoint check flag on lock declaration vs. lock acquisition.
311
TEST_VM_ASSERT_MSG(MutexSafepoint, always_check,
312
    ".*This lock should always have a safepoint check for Java threads: SFPT_Test_lock") {
313
  MutexLocker ml(new Mutex(Mutex::safepoint, "SFPT_Test_lock"),
314
                 Mutex::_no_safepoint_check_flag);
315
}
316

317
TEST_VM_ASSERT_MSG(MutexSafepoint, never_check,
318
    ".*This lock should not be taken with a safepoint check: SFPT_Test_lock") {
319
  MutexLocker ml(new Mutex(Mutex::nosafepoint, "SFPT_Test_lock"),
320
                 Mutex::_safepoint_check_flag);
321
}
322

323
TEST_VM_ASSERT_MSG(MutexSafepoint, possible_safepoint_lock,
324
    ".* Possible safepoint reached by thread that does not allow it") {
325
  JavaThread* thread = JavaThread::current();
326
  ThreadInVMfromNative in_native(thread);
327
  MutexLocker ml(new Mutex(Mutex::nosafepoint, "SpecialTest_lock"),
328
                   Mutex::_no_safepoint_check_flag);
329
  thread->print_thread_state_on(tty);
330
  // If the lock above succeeds, try to safepoint to test the NSV implied with this nosafepoint lock.
331
  ThreadBlockInVM tbivm(thread);
332
  thread->print_thread_state_on(tty);
333
}
334
#endif // ASSERT
335

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.