jdk

Форк
0
/
test_threads.cpp 
191 строка · 6.4 Кб
1
/*
2
 * Copyright (c) 2019, 2024, 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.hpp"
27
#include "runtime/interfaceSupport.inline.hpp"
28
#include "runtime/javaThread.hpp"
29
#include "runtime/mutexLocker.hpp"
30
#include "runtime/threads.hpp"
31
#include "runtime/vmOperations.hpp"
32
#include "runtime/vmThread.hpp"
33
#include "utilities/globalDefinitions.hpp"
34
#include "utilities/ostream.hpp"
35
#include "unittest.hpp"
36

37
struct Threads::Test : public AllStatic {
38
  class VM_TestClaimOverflow;
39
  class CountThreads;
40
  class CheckClaims;
41
};
42

43
class Threads::Test::CountThreads : public ThreadClosure {
44
  uintx _claim_token;
45
  uint _java_threads_count;
46
  uint _non_java_threads_count;
47
  bool _need_claim;
48

49
public:
50
  CountThreads(uintx claim_token, bool need_claim) :
51
    _claim_token(claim_token),
52
    _java_threads_count(0),
53
    _non_java_threads_count(0),
54
    _need_claim(need_claim)
55
  {}
56

57
  virtual void do_thread(Thread* t) {
58
    if (!_need_claim || t->claim_threads_do(true, _claim_token)) {
59
      if (t->is_Java_thread()) {
60
        ++_java_threads_count;
61
      } else {
62
        ++_non_java_threads_count;
63
      }
64
    }
65
  }
66

67
  uint java_threads_count() const { return _java_threads_count; }
68
  uint non_java_threads_count() const { return _non_java_threads_count; }
69
  uint count() const { return _java_threads_count + _non_java_threads_count; }
70
};
71

72
class Threads::Test::CheckClaims : public ThreadClosure {
73
  uintx _claim_token;
74
  uint _java_threads_claimed;
75
  uint _java_threads_unclaimed;
76
  uint _non_java_threads_claimed;
77
  uint _non_java_threads_unclaimed;
78

79
public:
80
  CheckClaims(uintx claim_token) :
81
    _claim_token(claim_token),
82
    _java_threads_claimed(0),
83
    _java_threads_unclaimed(0),
84
    _non_java_threads_claimed(0),
85
    _non_java_threads_unclaimed(0)
86
  {}
87

88
  virtual void do_thread(Thread* t) {
89
    uintx thread_token = t->threads_do_token();
90
    if (thread_token == _claim_token) {
91
      if (t->is_Java_thread()) {
92
        ++_java_threads_claimed;
93
      } else {
94
        ++_non_java_threads_claimed;
95
      }
96
    } else {
97
      if (t->is_Java_thread()) {
98
        ++_java_threads_unclaimed;
99
      } else {
100
        ++_non_java_threads_unclaimed;
101
      }
102
    }
103
  }
104

105
  uint java_threads_claimed() const { return _java_threads_claimed; }
106
  uint java_threads_unclaimed() const { return _java_threads_unclaimed; }
107

108
  uint non_java_threads_claimed() const { return _non_java_threads_claimed; }
109
  uint non_java_threads_unclaimed() const { return _non_java_threads_unclaimed; }
110

111
  uint claimed() const {
112
    return _java_threads_claimed + _non_java_threads_claimed;
113
  }
114

115
  uint unclaimed() const {
116
    return _java_threads_unclaimed + _non_java_threads_unclaimed;
117
  }
118
};
119

120
class Threads::Test::VM_TestClaimOverflow : public VM_GTestExecuteAtSafepoint {
121
public:
122
  void doit() {
123
    // Prevent changes to the NJT list while we're conducting our test.
124
    MutexLocker ml(NonJavaThreadsList_lock, Mutex::_no_safepoint_check_flag);
125

126
    _thread_claim_token = max_uintx - 1;
127

128
    ASSERT_EQ(max_uintx - 1, thread_claim_token());
129
    CountThreads count1(thread_claim_token(), true);
130
    threads_do(&count1);
131
    tty->print_cr("Testing claim overflow with %u threads", count1.count());
132
    // At least the main thread and the VM thread.
133
    ASSERT_LE(2u, count1.count());
134
    ASSERT_LE(1u, count1.java_threads_count());
135
    ASSERT_LE(1u, count1.non_java_threads_count());
136

137
    ASSERT_EQ(max_uintx - 1, thread_claim_token());
138
    CheckClaims check1(thread_claim_token());
139
    threads_do(&check1);
140
    ASSERT_EQ(count1.count(), check1.claimed());
141
    ASSERT_EQ(count1.java_threads_count(), check1.java_threads_claimed());
142
    ASSERT_EQ(0u, check1.java_threads_unclaimed());
143
    ASSERT_EQ(count1.non_java_threads_count(), check1.non_java_threads_claimed());
144
    ASSERT_EQ(0u, check1.non_java_threads_unclaimed());
145

146
    change_thread_claim_token(); // No overflow yet.
147
    ASSERT_EQ(max_uintx, thread_claim_token());
148

149
    CountThreads count2(thread_claim_token(), false); // Claimed by PPTD below
150
    possibly_parallel_threads_do(true /* is_par */, &count2);
151
    ASSERT_EQ(count1.java_threads_count(), count2.java_threads_count());
152
    ASSERT_EQ(count1.non_java_threads_count(), count2.non_java_threads_count());
153

154
    CheckClaims check2(thread_claim_token());
155
    threads_do(&check2);
156
    ASSERT_EQ(count2.java_threads_count(), check2.java_threads_claimed());
157
    ASSERT_EQ(0u, check2.java_threads_unclaimed());
158
    ASSERT_EQ(0u, check2.non_java_threads_unclaimed());
159
    ASSERT_EQ(count1.non_java_threads_count(),
160
              check2.non_java_threads_claimed());
161

162
    change_thread_claim_token(); // Expect overflow.
163
    ASSERT_EQ(uintx(1), thread_claim_token());
164

165
    // Verify all threads have claim value of 0 after change overflow.
166
    CheckClaims check3(0);
167
    threads_do(&check3);
168
    ASSERT_EQ(count1.count(), check3.claimed());
169
    ASSERT_EQ(0u, check3.unclaimed());
170
  }
171
};
172

173
// Test overflow handling in Threads::change_thread_claim_token().
174
TEST_VM(ThreadsTest, claim_overflow) {
175
  Threads::Test::VM_TestClaimOverflow op;
176
  ThreadInVMfromNative invm(JavaThread::current());
177
  VMThread::execute(&op);
178
}
179

180
TEST_VM(ThreadsTest, fast_jni_in_vm) {
181
  JavaThread* current = JavaThread::current();
182
  JNIEnv* env = current->jni_environment();
183
  MACOS_AARCH64_ONLY(ThreadWXEnable wx(WXWrite, current));
184

185
  // DirectByteBuffer is an easy way to trigger GetIntField,
186
  // see JDK-8262896
187
  jlong capacity = 0x10000;
188
  jobject buffer = env->NewDirectByteBuffer(nullptr, (jlong)capacity);
189
  ASSERT_NE((void*)nullptr, buffer);
190
  ASSERT_EQ(capacity, env->GetDirectBufferCapacity(buffer));
191
}
192

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

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

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

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