Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/sun/nio/ch/TestMaxCachedBufferSize.java
41149 views
1
/*
2
* Copyright (c) 2016, 2021, 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
import java.io.IOException;
25
import java.lang.management.BufferPoolMXBean;
26
import java.lang.management.ManagementFactory;
27
import java.nio.ByteBuffer;
28
import java.nio.channels.FileChannel;
29
import java.nio.file.Path;
30
import java.nio.file.Paths;
31
import java.util.List;
32
import java.util.SplittableRandom;
33
import java.util.concurrent.CountDownLatch;
34
35
import static java.nio.file.StandardOpenOption.CREATE;
36
import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING;
37
import static java.nio.file.StandardOpenOption.WRITE;
38
39
import jdk.test.lib.RandomFactory;
40
41
/*
42
* @test
43
* @requires sun.arch.data.model == "64"
44
* @modules java.management
45
* @library /test/lib
46
* @build TestMaxCachedBufferSize
47
* @run main/othervm/timeout=150 TestMaxCachedBufferSize
48
* @run main/othervm/timeout=150 -Djdk.nio.maxCachedBufferSize=0 TestMaxCachedBufferSize
49
* @run main/othervm/timeout=150 -Djdk.nio.maxCachedBufferSize=2000 TestMaxCachedBufferSize
50
* @run main/othervm/timeout=150 -Djdk.nio.maxCachedBufferSize=100000 TestMaxCachedBufferSize
51
* @run main/othervm/timeout=150 -Djdk.nio.maxCachedBufferSize=10000000 TestMaxCachedBufferSize
52
* @summary Test the implementation of the jdk.nio.maxCachedBufferSize property
53
* (use -Dseed=X to set PRNG seed)
54
* @key randomness
55
*/
56
public class TestMaxCachedBufferSize {
57
private static final int DEFAULT_ITERS = 5 * 1000;
58
private static final int DEFAULT_THREAD_NUM = 4;
59
60
private static final int SMALL_BUFFER_MIN_SIZE = 4 * 1024;
61
private static final int SMALL_BUFFER_MAX_SIZE = 64 * 1024;
62
private static final int SMALL_BUFFER_DIFF_SIZE =
63
SMALL_BUFFER_MAX_SIZE - SMALL_BUFFER_MIN_SIZE;
64
65
private static final int LARGE_BUFFER_MIN_SIZE = 512 * 1024;
66
private static final int LARGE_BUFFER_MAX_SIZE = 4 * 1024 * 1024;
67
private static final int LARGE_BUFFER_DIFF_SIZE =
68
LARGE_BUFFER_MAX_SIZE - LARGE_BUFFER_MIN_SIZE;
69
70
private static final int LARGE_BUFFER_FREQUENCY = 100;
71
72
private static final String FILE_NAME_PREFIX = "nio-out-file-";
73
private static final int VERBOSE_PERIOD = DEFAULT_ITERS / 10;
74
75
private static final SplittableRandom SRAND = RandomFactory.getSplittableRandom();
76
77
private static int iters = DEFAULT_ITERS;
78
private static int threadNum = DEFAULT_THREAD_NUM;
79
80
private static BufferPoolMXBean getDirectPool() {
81
final List<BufferPoolMXBean> pools =
82
ManagementFactory.getPlatformMXBeans(BufferPoolMXBean.class);
83
for (BufferPoolMXBean pool : pools) {
84
if (pool.getName().equals("direct")) {
85
return pool;
86
}
87
}
88
throw new Error("could not find direct pool");
89
}
90
private static final BufferPoolMXBean directPool = getDirectPool();
91
private static long initialCount;
92
private static long initialCapacity;
93
94
// Each worker will do write operations on a file channel using
95
// buffers of various sizes. The buffer size is randomly chosen to
96
// be within a small or a large range. This way we can control
97
// which buffers can be cached (all, only the small ones, or none)
98
// by setting the jdk.nio.maxCachedBufferSize property.
99
private static class Worker implements Runnable {
100
private final int id;
101
private final CountDownLatch finishLatch, exitLatch;
102
private SplittableRandom random = SRAND.split();
103
private long smallBufferCount = 0;
104
private long largeBufferCount = 0;
105
106
private int getWriteSize() {
107
int minSize = 0;
108
int diff = 0;
109
if (random.nextInt() % LARGE_BUFFER_FREQUENCY != 0) {
110
// small buffer
111
minSize = SMALL_BUFFER_MIN_SIZE;
112
diff = SMALL_BUFFER_DIFF_SIZE;
113
smallBufferCount += 1;
114
} else {
115
// large buffer
116
minSize = LARGE_BUFFER_MIN_SIZE;
117
diff = LARGE_BUFFER_DIFF_SIZE;
118
largeBufferCount += 1;
119
}
120
return minSize + random.nextInt(diff);
121
}
122
123
private void loop() {
124
final String fileName = String.format("%s%d", FILE_NAME_PREFIX, id);
125
126
try {
127
for (int i = 0; i < iters; i += 1) {
128
final int writeSize = getWriteSize();
129
130
// This will allocate a HeapByteBuffer. It should not
131
// be a direct buffer, otherwise the write() method on
132
// the channel below will not create a temporary
133
// direct buffer for the write.
134
final ByteBuffer buffer = ByteBuffer.allocate(writeSize);
135
136
// Put some random data on it.
137
while (buffer.hasRemaining()) {
138
buffer.put((byte) random.nextInt());
139
}
140
buffer.rewind();
141
142
final Path file = Paths.get(fileName);
143
try (FileChannel outChannel = FileChannel.open(file, CREATE, TRUNCATE_EXISTING, WRITE)) {
144
// The write() method will create a temporary
145
// direct buffer for the write and attempt to cache
146
// it. It's important that buffer is not a
147
// direct buffer, otherwise the temporary buffer
148
// will not be created.
149
long res = outChannel.write(buffer);
150
}
151
152
if ((i + 1) % VERBOSE_PERIOD == 0) {
153
System.out.printf(
154
" Worker %3d | %8d Iters | Small %8d Large %8d | Direct %4d / %7dK\n",
155
id, i + 1, smallBufferCount, largeBufferCount,
156
directPool.getCount(), directPool.getTotalCapacity() / 1024);
157
}
158
}
159
} catch (IOException e) {
160
throw new Error("I/O error", e);
161
} finally {
162
finishLatch.countDown();
163
try {
164
exitLatch.await();
165
} catch (InterruptedException e) {
166
// ignore
167
}
168
}
169
}
170
171
@Override
172
public void run() {
173
loop();
174
}
175
176
public Worker(int id, CountDownLatch finishLatch, CountDownLatch exitLatch) {
177
this.id = id;
178
this.finishLatch = finishLatch;
179
this.exitLatch = exitLatch;
180
}
181
}
182
183
public static void checkDirectBuffers(long expectedCount, long expectedMax) {
184
final long directCount = directPool.getCount() - initialCount;
185
final long directTotalCapacity =
186
directPool.getTotalCapacity() - initialCapacity;
187
System.out.printf("Direct %d / %dK\n",
188
directCount, directTotalCapacity / 1024);
189
190
if (directCount > expectedCount) {
191
throw new Error(String.format(
192
"inconsistent direct buffer total count, expected = %d, found = %d",
193
expectedCount, directCount));
194
}
195
196
if (directTotalCapacity > expectedMax) {
197
throw new Error(String.format(
198
"inconsistent direct buffer total capacity, expected max = %d, found = %d",
199
expectedMax, directTotalCapacity));
200
}
201
}
202
203
public static void main(String[] args) {
204
initialCount = directPool.getCount();
205
initialCapacity = directPool.getTotalCapacity();
206
207
final String maxBufferSizeStr = System.getProperty("jdk.nio.maxCachedBufferSize");
208
final long maxBufferSize =
209
(maxBufferSizeStr != null) ? Long.valueOf(maxBufferSizeStr) : Long.MAX_VALUE;
210
211
// We assume that the max cannot be equal to a size of a
212
// buffer that can be allocated (makes sanity checking at the
213
// end easier).
214
if ((SMALL_BUFFER_MIN_SIZE <= maxBufferSize &&
215
maxBufferSize <= SMALL_BUFFER_MAX_SIZE) ||
216
(LARGE_BUFFER_MIN_SIZE <= maxBufferSize &&
217
maxBufferSize <= LARGE_BUFFER_MAX_SIZE)) {
218
throw new Error(String.format("max buffer size = %d not allowed",
219
maxBufferSize));
220
}
221
222
System.out.printf("Threads %d | Iterations %d | MaxBufferSize %d\n",
223
threadNum, iters, maxBufferSize);
224
System.out.println();
225
226
final CountDownLatch finishLatch = new CountDownLatch(threadNum);
227
final CountDownLatch exitLatch = new CountDownLatch(1);
228
final Thread[] threads = new Thread[threadNum];
229
for (int i = 0; i < threadNum; i += 1) {
230
threads[i] = new Thread(new Worker(i, finishLatch, exitLatch));
231
threads[i].start();
232
}
233
234
try {
235
try {
236
finishLatch.await();
237
} catch (InterruptedException e) {
238
throw new Error("finishLatch.await() interrupted!", e);
239
}
240
241
// There is an assumption here that, at this point, only the
242
// cached DirectByteBuffers should be active. Given we
243
// haven't used any other DirectByteBuffers in this test, this
244
// should hold.
245
//
246
// Also note that we can only do the sanity checking at the
247
// end and not during the run given that, at any time, there
248
// could be buffers currently in use by some of the workers
249
// that will not be cached.
250
251
System.out.println();
252
if (maxBufferSize < SMALL_BUFFER_MAX_SIZE) {
253
// The max buffer size is smaller than all buffers that
254
// were allocated. No buffers should have been cached.
255
checkDirectBuffers(0, 0);
256
} else if (maxBufferSize < LARGE_BUFFER_MIN_SIZE) {
257
// The max buffer size is larger than all small buffers
258
// but smaller than all large buffers that were
259
// allocated. Only small buffers could have been cached.
260
checkDirectBuffers(threadNum,
261
(long) threadNum * (long) SMALL_BUFFER_MAX_SIZE);
262
} else {
263
// The max buffer size is larger than all buffers that
264
// were allocated. All buffers could have been cached.
265
checkDirectBuffers(threadNum,
266
(long) threadNum * (long) LARGE_BUFFER_MAX_SIZE);
267
}
268
} finally {
269
exitLatch.countDown();
270
try {
271
for (int i = 0; i < threadNum; i += 1) {
272
threads[i].join();
273
}
274
} catch (InterruptedException e) {
275
// ignore
276
}
277
}
278
}
279
}
280
281