Path: blob/master/test/hotspot/gtest/runtime/test_threads.cpp
41145 views
/*1* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"25#include "memory/allocation.hpp"26#include "runtime/interfaceSupport.inline.hpp"27#include "runtime/mutexLocker.hpp"28#include "runtime/thread.hpp"29#include "runtime/vmOperations.hpp"30#include "runtime/vmThread.hpp"31#include "utilities/globalDefinitions.hpp"32#include "utilities/ostream.hpp"33#include "unittest.hpp"3435struct Threads::Test : public AllStatic {36class VM_TestClaimOverflow;37class CountThreads;38class CheckClaims;39};4041class Threads::Test::CountThreads : public ThreadClosure {42uintx _claim_token;43uint _java_threads_count;44uint _non_java_threads_count;45bool _need_claim;4647public:48CountThreads(uintx claim_token, bool need_claim) :49_claim_token(claim_token),50_java_threads_count(0),51_non_java_threads_count(0),52_need_claim(need_claim)53{}5455virtual void do_thread(Thread* t) {56if (!_need_claim || t->claim_threads_do(true, _claim_token)) {57if (t->is_Java_thread()) {58++_java_threads_count;59} else {60++_non_java_threads_count;61}62}63}6465uint java_threads_count() const { return _java_threads_count; }66uint non_java_threads_count() const { return _non_java_threads_count; }67uint count() const { return _java_threads_count + _non_java_threads_count; }68};6970class Threads::Test::CheckClaims : public ThreadClosure {71uintx _claim_token;72uint _java_threads_claimed;73uint _java_threads_unclaimed;74uint _non_java_threads_claimed;75uint _non_java_threads_unclaimed;7677public:78CheckClaims(uintx claim_token) :79_claim_token(claim_token),80_java_threads_claimed(0),81_java_threads_unclaimed(0),82_non_java_threads_claimed(0),83_non_java_threads_unclaimed(0)84{}8586virtual void do_thread(Thread* t) {87uintx thread_token = t->threads_do_token();88if (thread_token == _claim_token) {89if (t->is_Java_thread()) {90++_java_threads_claimed;91} else {92++_non_java_threads_claimed;93}94} else {95if (t->is_Java_thread()) {96++_java_threads_unclaimed;97} else {98++_non_java_threads_unclaimed;99}100}101}102103uint java_threads_claimed() const { return _java_threads_claimed; }104uint java_threads_unclaimed() const { return _java_threads_unclaimed; }105106uint non_java_threads_claimed() const { return _non_java_threads_claimed; }107uint non_java_threads_unclaimed() const { return _non_java_threads_unclaimed; }108109uint claimed() const {110return _java_threads_claimed + _non_java_threads_claimed;111}112113uint unclaimed() const {114return _java_threads_unclaimed + _non_java_threads_unclaimed;115}116};117118class Threads::Test::VM_TestClaimOverflow : public VM_GTestExecuteAtSafepoint {119public:120void doit() {121// Prevent changes to the NJT list while we're conducting our test.122MutexLocker ml(NonJavaThreadsList_lock, Mutex::_no_safepoint_check_flag);123124_thread_claim_token = max_uintx - 1;125126ASSERT_EQ(max_uintx - 1, thread_claim_token());127CountThreads count1(thread_claim_token(), true);128threads_do(&count1);129tty->print_cr("Testing claim overflow with %u threads", count1.count());130// At least the main thread and the VM thread.131ASSERT_LE(2u, count1.count());132ASSERT_LE(1u, count1.java_threads_count());133ASSERT_LE(1u, count1.non_java_threads_count());134135ASSERT_EQ(max_uintx - 1, thread_claim_token());136CheckClaims check1(thread_claim_token());137threads_do(&check1);138ASSERT_EQ(count1.count(), check1.claimed());139ASSERT_EQ(count1.java_threads_count(), check1.java_threads_claimed());140ASSERT_EQ(0u, check1.java_threads_unclaimed());141ASSERT_EQ(count1.non_java_threads_count(), check1.non_java_threads_claimed());142ASSERT_EQ(0u, check1.non_java_threads_unclaimed());143144change_thread_claim_token(); // No overflow yet.145ASSERT_EQ(max_uintx, thread_claim_token());146147CountThreads count2(thread_claim_token(), false); // Claimed by PPTD below148possibly_parallel_threads_do(true, &count2);149ASSERT_EQ(count1.java_threads_count(), count2.java_threads_count());150ASSERT_EQ(1u, count2.non_java_threads_count()); // Only VM thread151152CheckClaims check2(thread_claim_token());153threads_do(&check2);154ASSERT_EQ(count2.java_threads_count(), check2.java_threads_claimed());155ASSERT_EQ(0u, check2.java_threads_unclaimed());156ASSERT_EQ(1u, check2.non_java_threads_claimed()); // Only VM thread157ASSERT_EQ(count1.non_java_threads_count(),158check2.non_java_threads_claimed() +159check2.non_java_threads_unclaimed());160161change_thread_claim_token(); // Expect overflow.162ASSERT_EQ(uintx(1), thread_claim_token());163164// Verify all threads have claim value of 0 after change overflow.165CheckClaims check3(0);166threads_do(&check3);167ASSERT_EQ(count1.count(), check3.claimed());168ASSERT_EQ(0u, check3.unclaimed());169}170};171172// Test overflow handling in Threads::change_thread_claim_token().173TEST_VM(ThreadsTest, claim_overflow) {174Threads::Test::VM_TestClaimOverflow op;175ThreadInVMfromNative invm(JavaThread::current());176VMThread::execute(&op);177}178179TEST_VM(ThreadsTest, fast_jni_in_vm) {180JavaThread* current = JavaThread::current();181JNIEnv* env = current->jni_environment();182MACOS_AARCH64_ONLY(ThreadWXEnable wx(WXWrite, current));183184// DirectByteBuffer is an easy way to trigger GetIntField,185// see JDK-8262896186jlong capacity = 0x10000;187jobject buffer = env->NewDirectByteBuffer(NULL, (jlong)capacity);188ASSERT_NE((void*)NULL, buffer);189ASSERT_EQ(capacity, env->GetDirectBufferCapacity(buffer));190}191192193