Skip to content

Commit 770e2aa

Browse files
author
David Holmes
committed
8215948: [TESTBUG] gtest pseudo-JavaThreads could be more regular JavaThreads
Reviewed-by: coleenp, pchilanomate
1 parent 9cac94d commit 770e2aa

File tree

2 files changed

+70
-65
lines changed

2 files changed

+70
-65
lines changed

test/hotspot/gtest/threadHelper.inline.hpp

Lines changed: 51 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,29 @@
2626

2727
#include "runtime/mutex.hpp"
2828
#include "runtime/semaphore.hpp"
29+
#include "runtime/interfaceSupport.inline.hpp"
2930
#include "runtime/thread.inline.hpp"
3031
#include "runtime/vmThread.hpp"
3132
#include "runtime/vmOperations.hpp"
3233
#include "unittest.hpp"
3334

35+
static void startTestThread(JavaThread* thread, const char* name) {
36+
EXCEPTION_MARK;
37+
HandleMark hm(THREAD);
38+
Handle thread_oop;
39+
40+
// This code can be called from the main thread, which is _thread_in_native,
41+
// or by an existing JavaTestThread, which is _thread_in_vm.
42+
if (THREAD->thread_state() == _thread_in_native) {
43+
ThreadInVMfromNative tivfn(THREAD);
44+
thread_oop = JavaThread::create_system_thread_object(name, false /* not visible */, CHECK);
45+
JavaThread::start_internal_daemon(THREAD, thread, thread_oop, NoPriority);
46+
} else {
47+
thread_oop = JavaThread::create_system_thread_object(name, false /* not visible */, CHECK);
48+
JavaThread::start_internal_daemon(THREAD, thread, thread_oop, NoPriority);
49+
}
50+
}
51+
3452
class VM_StopSafepoint : public VM_Operation {
3553
public:
3654
Semaphore* _running;
@@ -44,38 +62,29 @@ class VM_StopSafepoint : public VM_Operation {
4462

4563
// This class and thread keep the non-safepoint op running while we do our testing.
4664
class VMThreadBlocker : public JavaThread {
47-
public:
4865
Semaphore _ready;
4966
Semaphore _unblock;
50-
VMThreadBlocker() {}
51-
virtual ~VMThreadBlocker() {}
52-
const char* get_thread_name_string(char* buf, int buflen) const {
53-
return "VMThreadBlocker";
54-
}
55-
void run() {
56-
this->set_thread_state(_thread_in_vm);
57-
{
58-
MutexLocker ml(Threads_lock);
59-
Threads::add(this);
60-
}
61-
VM_StopSafepoint ss(&_ready, &_unblock);
67+
68+
static void blocker_thread_entry(JavaThread* thread, TRAPS) {
69+
VMThreadBlocker* t = static_cast<VMThreadBlocker*>(thread);
70+
VM_StopSafepoint ss(&t->_ready, &t->_unblock);
6271
VMThread::execute(&ss);
6372
}
6473

65-
// Override as JavaThread::post_run() calls JavaThread::exit which
66-
// expects a valid thread object oop.
67-
virtual void post_run() {
68-
Threads::remove(this, false);
69-
this->smr_delete();
70-
}
74+
VMThreadBlocker() : JavaThread(&blocker_thread_entry) {};
7175

72-
void doit() {
73-
if (os::create_thread(this, os::os_thread)) {
74-
os::start_thread(this);
75-
} else {
76-
ASSERT_TRUE(false);
77-
}
76+
virtual ~VMThreadBlocker() {}
77+
78+
public:
79+
// Convenience method for client code
80+
static VMThreadBlocker* start() {
81+
const char* name = "VMThreadBlocker";
82+
VMThreadBlocker* thread = new VMThreadBlocker();
83+
JavaThread::vm_exit_on_osthread_failure(thread);
84+
startTestThread(thread, name);
85+
return thread;
7886
}
87+
7988
void ready() {
8089
_ready.wait();
8190
}
@@ -86,52 +95,34 @@ class VMThreadBlocker : public JavaThread {
8695

8796
// For testing in a real JavaThread.
8897
class JavaTestThread : public JavaThread {
89-
public:
9098
Semaphore* _post;
99+
100+
protected:
91101
JavaTestThread(Semaphore* post)
92-
: _post(post) {
102+
: JavaThread(&test_thread_entry), _post(post) {
103+
JavaThread::vm_exit_on_osthread_failure(this);
93104
}
94105
virtual ~JavaTestThread() {}
95106

96-
const char* get_thread_name_string(char* buf, int buflen) const {
97-
return "JavaTestThread";
98-
}
99-
100-
void pre_run() {
101-
this->set_thread_state(_thread_in_vm);
102-
{
103-
MutexLocker ml(Threads_lock);
104-
Threads::add(this);
105-
}
107+
public:
108+
// simplified starting for callers and subclasses
109+
void doit() {
110+
startTestThread(this, "JavaTestThread");
106111
}
107112

108113
virtual void main_run() = 0;
109114

110-
void run() {
111-
main_run();
112-
}
113-
114-
// Override as JavaThread::post_run() calls JavaThread::exit which
115-
// expects a valid thread object oop. And we need to call signal.
116-
void post_run() {
117-
Threads::remove(this, false);
118-
_post->signal();
119-
this->smr_delete();
120-
}
121-
122-
void doit() {
123-
if (os::create_thread(this, os::os_thread)) {
124-
os::start_thread(this);
125-
} else {
126-
ASSERT_TRUE(false);
127-
}
115+
static void test_thread_entry(JavaThread* thread, TRAPS) {
116+
JavaTestThread* t = static_cast<JavaTestThread*>(thread);
117+
t->main_run();
118+
t->_post->signal();
128119
}
129120
};
130121

131122
template <typename FUNC>
132123
class SingleTestThread : public JavaTestThread {
133-
public:
134124
FUNC& _f;
125+
public:
135126
SingleTestThread(Semaphore* post, FUNC& f)
136127
: JavaTestThread(post), _f(f) {
137128
}
@@ -147,8 +138,8 @@ template <typename TESTFUNC>
147138
static void nomt_test_doer(TESTFUNC &f) {
148139
Semaphore post;
149140

150-
VMThreadBlocker* blocker = new VMThreadBlocker();
151-
blocker->doit();
141+
VMThreadBlocker* blocker = VMThreadBlocker::start();
142+
152143
blocker->ready();
153144

154145
SingleTestThread<TESTFUNC>* stt = new SingleTestThread<TESTFUNC>(&post, f);
@@ -162,8 +153,8 @@ template <typename RUNNER>
162153
static void mt_test_doer() {
163154
Semaphore post;
164155

165-
VMThreadBlocker* blocker = new VMThreadBlocker();
166-
blocker->doit();
156+
VMThreadBlocker* blocker = VMThreadBlocker::start();
157+
167158
blocker->ready();
168159

169160
RUNNER* runner = new RUNNER(&post);

test/hotspot/gtest/utilities/test_concurrentHashtable.cpp

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1065,15 +1065,23 @@ TEST_VM(ConcurrentHashTable, concurrent_get_insert_bulk_delete) {
10651065

10661066
class MT_BD_Thread : public JavaTestThread {
10671067
TestTable::BulkDeleteTask* _bd;
1068+
Semaphore run;
1069+
10681070
public:
1069-
MT_BD_Thread(Semaphore* post, TestTable::BulkDeleteTask* bd)
1070-
: JavaTestThread(post), _bd(bd){}
1071+
MT_BD_Thread(Semaphore* post)
1072+
: JavaTestThread(post) {}
10711073
virtual ~MT_BD_Thread() {}
10721074
void main_run() {
1075+
run.wait();
10731076
MyDel del;
10741077
while(_bd->do_task(this, *this, del));
10751078
}
10761079

1080+
void set_bd_task(TestTable::BulkDeleteTask* bd) {
1081+
_bd = bd;
1082+
run.signal();
1083+
}
1084+
10771085
bool operator()(uintptr_t* val) {
10781086
return true;
10791087
}
@@ -1098,15 +1106,21 @@ class Driver_BD_Thread : public JavaTestThread {
10981106
TestLookup tl(v);
10991107
EXPECT_TRUE(cht->insert(this, tl, v)) << "Inserting an unique value should work.";
11001108
}
1101-
TestTable::BulkDeleteTask bdt(cht, true /* mt */ );
1102-
EXPECT_TRUE(bdt.prepare(this)) << "Uncontended prepare must work.";
11031109

1110+
// Must create and start threads before acquiring mutex inside BulkDeleteTask.
11041111
MT_BD_Thread* tt[4];
11051112
for (int i = 0; i < 4; i++) {
1106-
tt[i] = new MT_BD_Thread(&done, &bdt);
1113+
tt[i] = new MT_BD_Thread(&done);
11071114
tt[i]->doit();
11081115
}
11091116

1117+
TestTable::BulkDeleteTask bdt(cht, true /* mt */ );
1118+
EXPECT_TRUE(bdt.prepare(this)) << "Uncontended prepare must work.";
1119+
1120+
for (int i = 0; i < 4; i++) {
1121+
tt[i]->set_bd_task(&bdt);
1122+
}
1123+
11101124
for (uintptr_t v = 1; v < 99999; v++ ) {
11111125
TestLookup tl(v);
11121126
cht_get_copy(cht, this, tl);

0 commit comments

Comments
 (0)