Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/hotspot/gtest/utilities/test_globalCounter_nested.cpp
41144 views
1
/*
2
* Copyright (c) 2018, 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
#include "precompiled.hpp"
25
#include "runtime/atomic.hpp"
26
#include "runtime/os.hpp"
27
#include "utilities/globalCounter.hpp"
28
#include "utilities/globalCounter.inline.hpp"
29
#include "utilities/spinYield.hpp"
30
#include "threadHelper.inline.hpp"
31
32
enum NestedTestState {
33
START,
34
START_WAIT,
35
OUTER_ENTERED,
36
INNER_ENTERED,
37
INNER_EXITED,
38
OUTER_EXITED,
39
SYNCHRONIZING,
40
SYNCHRONIZED
41
};
42
43
class RCUNestedThread : public JavaTestThread {
44
volatile NestedTestState _state;
45
volatile bool _proceed;
46
47
protected:
48
RCUNestedThread(Semaphore* post) :
49
JavaTestThread(post),
50
_state(START),
51
_proceed(false)
52
{}
53
54
~RCUNestedThread() {}
55
56
void set_state(NestedTestState new_state) {
57
Atomic::release_store(&_state, new_state);
58
}
59
60
void wait_with_state(NestedTestState new_state) {
61
SpinYield spinner;
62
Atomic::release_store(&_state, new_state);
63
while (!Atomic::load_acquire(&_proceed)) {
64
spinner.wait();
65
}
66
Atomic::release_store(&_proceed, false);
67
}
68
69
public:
70
NestedTestState state() const {
71
return Atomic::load_acquire(&_state);
72
}
73
74
void wait_for_state(NestedTestState goal) {
75
SpinYield spinner;
76
while (state() != goal) {
77
spinner.wait();
78
}
79
}
80
81
void proceed() {
82
Atomic::release_store(&_proceed, true);
83
}
84
};
85
86
class RCUNestedReaderThread : public RCUNestedThread {
87
public:
88
RCUNestedReaderThread(Semaphore* post) :
89
RCUNestedThread(post)
90
{}
91
92
virtual void main_run();
93
};
94
95
void RCUNestedReaderThread::main_run() {
96
wait_with_state(START_WAIT);
97
{
98
GlobalCounter::CriticalSection outer(Thread::current());
99
wait_with_state(OUTER_ENTERED);
100
{
101
GlobalCounter::CriticalSection inner(Thread::current());
102
wait_with_state(INNER_ENTERED);
103
}
104
wait_with_state(INNER_EXITED);
105
}
106
wait_with_state(OUTER_EXITED);
107
}
108
109
110
class RCUNestedWriterThread : public RCUNestedThread {
111
public:
112
RCUNestedWriterThread(Semaphore* post) :
113
RCUNestedThread(post)
114
{}
115
116
virtual void main_run();
117
};
118
119
void RCUNestedWriterThread::main_run() {
120
wait_with_state(START_WAIT);
121
set_state(SYNCHRONIZING);
122
GlobalCounter::write_synchronize();
123
wait_with_state(SYNCHRONIZED);
124
}
125
126
TEST_VM(GlobalCounter, nested_critical_section) {
127
Semaphore post;
128
RCUNestedReaderThread* reader = new RCUNestedReaderThread(&post);
129
RCUNestedWriterThread* outer = new RCUNestedWriterThread(&post);
130
RCUNestedWriterThread* inner = new RCUNestedWriterThread(&post);
131
132
reader->doit();
133
outer->doit();
134
inner->doit();
135
136
reader->wait_for_state(START_WAIT);
137
outer->wait_for_state(START_WAIT);
138
inner->wait_for_state(START_WAIT);
139
EXPECT_EQ(START_WAIT, reader->state());
140
EXPECT_EQ(START_WAIT, outer->state());
141
EXPECT_EQ(START_WAIT, inner->state());
142
143
reader->proceed();
144
reader->wait_for_state(OUTER_ENTERED);
145
EXPECT_EQ(OUTER_ENTERED, reader->state());
146
EXPECT_EQ(START_WAIT, outer->state());
147
EXPECT_EQ(START_WAIT, inner->state());
148
149
outer->proceed();
150
outer->wait_for_state(SYNCHRONIZING);
151
EXPECT_EQ(OUTER_ENTERED, reader->state());
152
EXPECT_EQ(SYNCHRONIZING, outer->state());
153
EXPECT_EQ(START_WAIT, inner->state());
154
155
os::naked_short_sleep(100); // Give outer time in synchronization.
156
EXPECT_EQ(OUTER_ENTERED, reader->state());
157
EXPECT_EQ(SYNCHRONIZING, outer->state());
158
EXPECT_EQ(START_WAIT, inner->state());
159
160
reader->proceed();
161
reader->wait_for_state(INNER_ENTERED);
162
EXPECT_EQ(INNER_ENTERED, reader->state());
163
EXPECT_EQ(SYNCHRONIZING, outer->state());
164
EXPECT_EQ(START_WAIT, inner->state());
165
166
inner->proceed();
167
inner->wait_for_state(SYNCHRONIZING);
168
EXPECT_EQ(INNER_ENTERED, reader->state());
169
EXPECT_EQ(SYNCHRONIZING, outer->state());
170
EXPECT_EQ(SYNCHRONIZING, inner->state());
171
172
os::naked_short_sleep(100); // Give writers time in synchronization.
173
EXPECT_EQ(INNER_ENTERED, reader->state());
174
EXPECT_EQ(SYNCHRONIZING, outer->state());
175
EXPECT_EQ(SYNCHRONIZING, inner->state());
176
177
reader->proceed();
178
reader->wait_for_state(INNER_EXITED);
179
// inner does *not* complete synchronization here.
180
EXPECT_EQ(INNER_EXITED, reader->state());
181
EXPECT_EQ(SYNCHRONIZING, outer->state());
182
EXPECT_EQ(SYNCHRONIZING, inner->state());
183
184
os::naked_short_sleep(100); // Give writers more time in synchronization.
185
EXPECT_EQ(INNER_EXITED, reader->state());
186
EXPECT_EQ(SYNCHRONIZING, outer->state());
187
EXPECT_EQ(SYNCHRONIZING, inner->state());
188
189
reader->proceed();
190
reader->wait_for_state(OUTER_EXITED);
191
// Both inner and outer can synchronize now.
192
outer->wait_for_state(SYNCHRONIZED);
193
inner->wait_for_state(SYNCHRONIZED);
194
EXPECT_EQ(OUTER_EXITED, reader->state());
195
EXPECT_EQ(SYNCHRONIZED, outer->state());
196
EXPECT_EQ(SYNCHRONIZED, inner->state());
197
198
// Wait for reader, outer, and inner to complete.
199
reader->proceed();
200
outer->proceed();
201
inner->proceed();
202
for (uint i = 0; i < 3; ++i) {
203
post.wait();
204
}
205
}
206
207