31 #include "runtime/vm_operations.hpp" |
31 #include "runtime/vm_operations.hpp" |
32 #include "unittest.hpp" |
32 #include "unittest.hpp" |
33 |
33 |
34 class VM_StopSafepoint : public VM_Operation { |
34 class VM_StopSafepoint : public VM_Operation { |
35 public: |
35 public: |
|
36 Semaphore* _running; |
36 Semaphore* _test_complete; |
37 Semaphore* _test_complete; |
37 VM_StopSafepoint(Semaphore* wait_for) : _test_complete(wait_for) {} |
38 VM_StopSafepoint(Semaphore* running, Semaphore* wait_for) : |
|
39 _running(running), _test_complete(wait_for) {} |
38 VMOp_Type type() const { return VMOp_None; } |
40 VMOp_Type type() const { return VMOp_None; } |
39 Mode evaluation_mode() const { return _no_safepoint; } |
41 Mode evaluation_mode() const { return _no_safepoint; } |
40 bool is_cheap_allocated() const { return false; } |
42 bool is_cheap_allocated() const { return false; } |
41 void doit() { _test_complete->wait(); } |
43 void doit() { _running->signal(); _test_complete->wait(); } |
42 }; |
44 }; |
43 |
45 |
44 // This class and thread keep the non-safepoint op running while we do our testing. |
46 // This class and thread keep the non-safepoint op running while we do our testing. |
45 class VMThreadBlocker : public JavaThread { |
47 class VMThreadBlocker : public JavaThread { |
46 public: |
48 public: |
47 Semaphore* _unblock; |
49 Semaphore _ready; |
48 Semaphore* _done; |
50 Semaphore _unblock; |
49 VMThreadBlocker(Semaphore* ub, Semaphore* done) : _unblock(ub), _done(done) { |
51 VMThreadBlocker() {} |
50 } |
|
51 virtual ~VMThreadBlocker() {} |
52 virtual ~VMThreadBlocker() {} |
52 void run() { |
53 void run() { |
53 this->set_thread_state(_thread_in_vm); |
54 this->set_thread_state(_thread_in_vm); |
54 { |
55 { |
55 MutexLocker ml(Threads_lock); |
56 MutexLocker ml(Threads_lock); |
56 Threads::add(this); |
57 Threads::add(this); |
57 } |
58 } |
58 VM_StopSafepoint ss(_unblock); |
59 VM_StopSafepoint ss(&_ready, &_unblock); |
59 VMThread::execute(&ss); |
60 VMThread::execute(&ss); |
60 _done->signal(); |
|
61 Threads::remove(this); |
61 Threads::remove(this); |
62 this->smr_delete(); |
62 this->smr_delete(); |
63 } |
63 } |
64 void doit() { |
64 void doit() { |
65 if (os::create_thread(this, os::os_thread)) { |
65 if (os::create_thread(this, os::os_thread)) { |
66 os::start_thread(this); |
66 os::start_thread(this); |
67 } else { |
67 } else { |
68 ASSERT_TRUE(false); |
68 ASSERT_TRUE(false); |
69 } |
69 } |
|
70 } |
|
71 void ready() { |
|
72 _ready.wait(); |
|
73 } |
|
74 void release() { |
|
75 _unblock.signal(); |
70 } |
76 } |
71 }; |
77 }; |
72 |
78 |
73 // For testing in a real JavaThread. |
79 // For testing in a real JavaThread. |
74 class JavaTestThread : public JavaThread { |
80 class JavaTestThread : public JavaThread { |
128 } |
134 } |
129 }; |
135 }; |
130 |
136 |
131 template <typename TESTFUNC> |
137 template <typename TESTFUNC> |
132 static void nomt_test_doer(TESTFUNC &f) { |
138 static void nomt_test_doer(TESTFUNC &f) { |
133 Semaphore post, block_done, vmt_done; |
139 Semaphore post; |
134 VMThreadBlocker* blocker = new VMThreadBlocker(&block_done, &vmt_done); |
140 |
|
141 VMThreadBlocker* blocker = new VMThreadBlocker(); |
135 blocker->doit(); |
142 blocker->doit(); |
|
143 blocker->ready(); |
|
144 |
136 SingleTestThread<TESTFUNC>* stt = new SingleTestThread<TESTFUNC>(&post, f); |
145 SingleTestThread<TESTFUNC>* stt = new SingleTestThread<TESTFUNC>(&post, f); |
137 stt->doit(); |
146 stt->doit(); |
138 post.wait(); |
147 post.wait(); |
139 block_done.signal(); |
148 |
140 vmt_done.wait(); |
149 blocker->release(); |
141 } |
150 } |
142 |
151 |
143 template <typename RUNNER> |
152 template <typename RUNNER> |
144 static void mt_test_doer() { |
153 static void mt_test_doer() { |
145 Semaphore post, block_done, vmt_done; |
154 Semaphore post; |
146 VMThreadBlocker* blocker = new VMThreadBlocker(&block_done, &vmt_done); |
155 |
|
156 VMThreadBlocker* blocker = new VMThreadBlocker(); |
147 blocker->doit(); |
157 blocker->doit(); |
|
158 blocker->ready(); |
|
159 |
148 RUNNER* runner = new RUNNER(&post); |
160 RUNNER* runner = new RUNNER(&post); |
149 runner->doit(); |
161 runner->doit(); |
150 post.wait(); |
162 post.wait(); |
151 block_done.signal(); |
163 |
152 vmt_done.wait(); |
164 blocker->release(); |
153 } |
165 } |
154 |
166 |
155 #endif // include guard |
167 #endif // include guard |