Skip to content

Commit a4f2078

Browse files
committed
8294437: java/nio/channels/FileChannel tests slow on Windows
Reviewed-by: alanb, bpb
1 parent c6e3daa commit a4f2078

File tree

6 files changed

+357
-282
lines changed

6 files changed

+357
-282
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* Copyright (c) 2022, 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.nio.channels.FileChannel;
26+
import java.nio.file.Files;
27+
import java.nio.file.Path;
28+
29+
import static java.nio.file.StandardOpenOption.*;
30+
31+
/**
32+
* Common library for various test file utility functions.
33+
*/
34+
public final class FileChannelUtils {
35+
36+
public static Path createSparseTempFile(String prefix, String suffix) throws IOException {
37+
Path file = Files.createTempFile(prefix, suffix);
38+
Files.delete(file); // need CREATE_NEW to make the file sparse
39+
40+
FileChannel fc = FileChannel.open(file, CREATE_NEW, SPARSE, WRITE);
41+
fc.close();
42+
return file;
43+
}
44+
}

test/jdk/java/nio/channels/FileChannel/LargeMapTest.java

+31-23
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,18 @@
2121
* questions.
2222
*/
2323

24+
import jdk.test.lib.RandomFactory;
25+
2426
import java.lang.foreign.MemorySegment;
2527
import java.lang.foreign.MemorySession;
2628

27-
import java.io.File;
2829
import java.io.IOException;
2930
import java.nio.ByteBuffer;
3031
import java.nio.channels.FileChannel;
3132
import java.nio.file.Path;
33+
import java.util.Random;
34+
import java.util.concurrent.TimeUnit;
35+
3236
import static java.nio.file.StandardOpenOption.*;
3337

3438
/*
@@ -38,42 +42,46 @@
3842
* @summary Ensure that memory mapping beyond 32-bit range does not cause an
3943
* EXCEPTION_ACCESS_VIOLATION.
4044
* @requires vm.bits == 64
41-
* @run main/othervm/timeout=240 LargeMapTest
45+
* @library /test/lib
46+
* @build jdk.test.lib.RandomFactory FileChannelUtils
47+
* @run main/othervm LargeMapTest
48+
* @key randomness
4249
*/
4350
public class LargeMapTest {
44-
private static final String FILE = "test.dat";
45-
private static final long LENGTH = 8000000000L;
46-
private static final long OFFSET = 3704800000L;
47-
private static final int BUFSIZ = 100000;
51+
private static final long LENGTH = (1L << 32) + 512;
52+
private static final int EXTRA = 1024;
53+
private static final long BASE = LENGTH - EXTRA;
54+
private static final Random GEN = RandomFactory.getRandom();
4855

4956
public static void main(String[] args) throws IOException {
5057
System.out.println(System.getProperty("sun.arch.data.model"));
5158
System.out.println(System.getProperty("os.arch"));
5259
System.out.println(System.getProperty("java.version"));
5360

54-
Path p = Path.of(FILE);
61+
System.out.println(" Writing large file...");
62+
long t0 = System.nanoTime();
63+
Path p = FileChannelUtils.createSparseTempFile("test", ".dat");
5564
p.toFile().deleteOnExit();
56-
try (FileChannel fc = FileChannel.open(p, CREATE, WRITE)) {
57-
fc.position(LENGTH - 1);
58-
fc.write(ByteBuffer.wrap(new byte[] {27}));
65+
ByteBuffer bb;
66+
try (FileChannel fc = FileChannel.open(p, WRITE)) {
67+
fc.position(BASE);
68+
byte[] b = new byte[EXTRA];
69+
GEN.nextBytes(b);
70+
bb = ByteBuffer.wrap(b);
71+
fc.write(bb);
72+
long t1 = System.nanoTime();
73+
System.out.printf(" Wrote large file in %d ns (%d ms) %n",
74+
t1 - t0, TimeUnit.NANOSECONDS.toMillis(t1 - t0));
5975
}
76+
bb.rewind();
6077

61-
long offset = OFFSET;
62-
ByteBuffer bb = ByteBuffer.allocateDirect(BUFSIZ);
63-
64-
try (FileChannel fc = FileChannel.open(p, READ, WRITE);) {
65-
MemorySegment mbb = MemorySegment.ofBuffer(bb);
78+
try (FileChannel fc = FileChannel.open(p, READ, WRITE)) {
6679
MemorySegment mappedMemorySegment =
6780
fc.map(FileChannel.MapMode.READ_WRITE, 0, p.toFile().length(),
6881
MemorySession.openImplicit());
69-
70-
final int interval = BUFSIZ*1000;
71-
while (offset < LENGTH) {
72-
if (offset % interval == 0)
73-
System.out.println("offset: " + offset);
74-
MemorySegment target = mappedMemorySegment.asSlice(offset, BUFSIZ);
75-
offset = offset + BUFSIZ;
76-
target.copyFrom(mbb);
82+
MemorySegment target = mappedMemorySegment.asSlice(BASE, EXTRA);
83+
if (!target.asByteBuffer().equals(bb)) {
84+
throw new RuntimeException("Expected buffers to be equal");
7785
}
7886
}
7987
}

test/jdk/java/nio/channels/FileChannel/MapTest.java

+63-43
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -36,6 +36,7 @@
3636
import static java.nio.file.StandardOpenOption.*;
3737
import static java.nio.charset.StandardCharsets.*;
3838
import java.util.Random;
39+
import java.util.concurrent.TimeUnit;
3940

4041

4142
/**
@@ -56,21 +57,42 @@ public class MapTest {
5657
public static void main(String[] args) throws Exception {
5758
blah = File.createTempFile("blah", null);
5859
blah.deleteOnExit();
60+
long t0 = System.nanoTime();
5961
initTestFile(blah);
62+
long t1 = System.nanoTime();
63+
out.printf("Test file %s initialized in %d ns (%d ms) %n",
64+
blah, t1 - t0, TimeUnit.NANOSECONDS.toMillis(t1 - t0));
65+
t0 = t1;
6066
try {
61-
out.println("Test file " + blah + " initialized");
6267
testZero();
63-
out.println("Zero size: OK");
68+
t1 = System.nanoTime();
69+
out.printf("Zero size: done in %d ns (%d ms) %n",
70+
t1 - t0, TimeUnit.NANOSECONDS.toMillis(t1 - t0));
71+
t0 = t1;
6472
testRead();
65-
out.println("Read: OK");
73+
t1 = System.nanoTime();
74+
out.printf("Read: done in %d ns (%d ms) %n",
75+
t1 - t0, TimeUnit.NANOSECONDS.toMillis(t1 - t0));
76+
t0 = t1;
6677
testWrite();
67-
out.println("Write: OK");
78+
t1 = System.nanoTime();
79+
out.printf("Write: done in %d ns (%d ms) %n",
80+
t1 - t0, TimeUnit.NANOSECONDS.toMillis(t1 - t0));
81+
t0 = t1;
6882
testHighOffset();
69-
out.println("High offset: OK");
83+
t1 = System.nanoTime();
84+
out.printf("High offset: done in %d ns (%d ms) %n",
85+
t1 - t0, TimeUnit.NANOSECONDS.toMillis(t1 - t0));
86+
t0 = t1;
7087
testForce();
71-
out.println("Force: OK");
88+
t1 = System.nanoTime();
89+
out.printf("Force: done in %d ns (%d ms) %n",
90+
t1 - t0, TimeUnit.NANOSECONDS.toMillis(t1 - t0));
91+
t0 = t1;
7292
testExceptions();
73-
out.println("Exceptions: OK");
93+
t1 = System.nanoTime();
94+
out.printf("Exceptions: done in %d ns (%d ms) %n",
95+
t1 - t0, TimeUnit.NANOSECONDS.toMillis(t1 - t0));
7496
} finally {
7597
blah.delete();
7698
}
@@ -195,44 +217,42 @@ private static void testHighOffset() throws Exception {
195217
* the data exercising various valid and invalid writeback ranges.
196218
*/
197219
private static void testForce() throws Exception {
198-
for (int x=0; x<50; x++) {
199-
try (RandomAccessFile raf = new RandomAccessFile(blah, "rw")) {
200-
FileChannel fc = raf.getChannel();
201-
final int BLOCK_SIZE = 64;
202-
final int BLOCK_COUNT = (4096 * 2)/ BLOCK_SIZE;
203-
int offset = 0;
204-
MappedByteBuffer b = fc.map(MapMode.READ_WRITE,
205-
0, BLOCK_SIZE * (BLOCK_COUNT + 1));
206-
207-
for (int blocks = 0; blocks < BLOCK_COUNT; blocks++) {
208-
for (int i = 0; i < BLOCK_SIZE; i++) {
209-
b.put(offset + i, (byte)('0' + i));
210-
}
211-
b.force(offset, BLOCK_SIZE);
212-
offset += BLOCK_SIZE;
220+
try (RandomAccessFile raf = new RandomAccessFile(blah, "rw")) {
221+
FileChannel fc = raf.getChannel();
222+
final int BLOCK_SIZE = 64;
223+
final int BLOCK_COUNT = (4096 * 2)/ BLOCK_SIZE;
224+
int offset = 0;
225+
MappedByteBuffer b = fc.map(MapMode.READ_WRITE,
226+
0, BLOCK_SIZE * (BLOCK_COUNT + 1));
227+
228+
for (int blocks = 0; blocks < BLOCK_COUNT; blocks++) {
229+
for (int i = 0; i < BLOCK_SIZE; i++) {
230+
b.put(offset + i, (byte)('0' + i));
213231
}
232+
b.force(offset, BLOCK_SIZE);
233+
offset += BLOCK_SIZE;
234+
}
214235

215-
Exception exc = null;
216-
try {
217-
// start and end are out of range
218-
b.force(offset + BLOCK_SIZE, BLOCK_SIZE);
219-
} catch (IndexOutOfBoundsException e) {
220-
exc = e;
221-
}
222-
if (exc == null) {
223-
throw new RuntimeException("expected Exception for force beyond buffer extent");
224-
}
236+
Exception exc = null;
237+
try {
238+
// start and end are out of range
239+
b.force(offset + BLOCK_SIZE, BLOCK_SIZE);
240+
} catch (IndexOutOfBoundsException e) {
241+
exc = e;
242+
}
243+
if (exc == null) {
244+
throw new RuntimeException("expected Exception for force beyond buffer extent");
245+
}
225246

226-
exc = null;
227-
try {
228-
// start is in range but end is out of range
229-
b.force(offset, 2 * BLOCK_SIZE);
230-
} catch (IndexOutOfBoundsException e) {
231-
exc = e;
232-
}
233-
if (exc == null) {
234-
throw new RuntimeException("expected Exception for force beyond write limit");
235-
}
247+
exc = null;
248+
try {
249+
// start is in range but end is out of range
250+
b.force(offset, 2 * BLOCK_SIZE);
251+
} catch (IndexOutOfBoundsException e) {
252+
exc = e;
253+
}
254+
if (exc == null) {
255+
throw new RuntimeException("expected Exception for force beyond write limit");
236256
}
237257
}
238258
}

0 commit comments

Comments
 (0)