26
26
27
27
#include " runtime/mutex.hpp"
28
28
#include " runtime/semaphore.hpp"
29
+ #include " runtime/interfaceSupport.inline.hpp"
29
30
#include " runtime/thread.inline.hpp"
30
31
#include " runtime/vmThread.hpp"
31
32
#include " runtime/vmOperations.hpp"
32
33
#include " unittest.hpp"
33
34
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
+
34
52
class VM_StopSafepoint : public VM_Operation {
35
53
public:
36
54
Semaphore* _running;
@@ -44,38 +62,29 @@ class VM_StopSafepoint : public VM_Operation {
44
62
45
63
// This class and thread keep the non-safepoint op running while we do our testing.
46
64
class VMThreadBlocker : public JavaThread {
47
- public:
48
65
Semaphore _ready;
49
66
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 );
62
71
VMThread::execute (&ss);
63
72
}
64
73
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) {};
71
75
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;
78
86
}
87
+
79
88
void ready () {
80
89
_ready.wait ();
81
90
}
@@ -86,52 +95,34 @@ class VMThreadBlocker : public JavaThread {
86
95
87
96
// For testing in a real JavaThread.
88
97
class JavaTestThread : public JavaThread {
89
- public:
90
98
Semaphore* _post;
99
+
100
+ protected:
91
101
JavaTestThread (Semaphore* post)
92
- : _post(post) {
102
+ : JavaThread(&test_thread_entry), _post(post) {
103
+ JavaThread::vm_exit_on_osthread_failure (this );
93
104
}
94
105
virtual ~JavaTestThread () {}
95
106
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" );
106
111
}
107
112
108
113
virtual void main_run () = 0;
109
114
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 ();
128
119
}
129
120
};
130
121
131
122
template <typename FUNC>
132
123
class SingleTestThread : public JavaTestThread {
133
- public:
134
124
FUNC& _f;
125
+ public:
135
126
SingleTestThread (Semaphore* post, FUNC& f)
136
127
: JavaTestThread(post), _f(f) {
137
128
}
@@ -147,8 +138,8 @@ template <typename TESTFUNC>
147
138
static void nomt_test_doer (TESTFUNC &f) {
148
139
Semaphore post;
149
140
150
- VMThreadBlocker* blocker = new VMThreadBlocker ();
151
- blocker-> doit ();
141
+ VMThreadBlocker* blocker = VMThreadBlocker::start ();
142
+
152
143
blocker->ready ();
153
144
154
145
SingleTestThread<TESTFUNC>* stt = new SingleTestThread<TESTFUNC>(&post, f);
@@ -162,8 +153,8 @@ template <typename RUNNER>
162
153
static void mt_test_doer () {
163
154
Semaphore post;
164
155
165
- VMThreadBlocker* blocker = new VMThreadBlocker ();
166
- blocker-> doit ();
156
+ VMThreadBlocker* blocker = VMThreadBlocker::start ();
157
+
167
158
blocker->ready ();
168
159
169
160
RUNNER* runner = new RUNNER (&post);
0 commit comments