f44032969f
Reviewed-by: jpai, lancea
150 lines
5.5 KiB
Java
150 lines
5.5 KiB
Java
/*
|
|
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License version 2 only, as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* version 2 for more details (a copy is included in the LICENSE file that
|
|
* accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU General Public License version
|
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*
|
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
* or visit www.oracle.com if you need additional information or have any
|
|
* questions.
|
|
*/
|
|
|
|
/*
|
|
* @test
|
|
* @bug 8274548
|
|
* @summary Test gathering write of more than INT_MAX bytes
|
|
* @requires vm.bits == 64
|
|
* @library ..
|
|
* @library /test/lib
|
|
* @build jdk.test.lib.RandomFactory
|
|
* @run main/othervm/timeout=480 -Xmx4G LargeGatheringWrite
|
|
* @key randomness
|
|
*/
|
|
import java.io.IOException;
|
|
import java.nio.ByteBuffer;
|
|
import java.nio.channels.FileChannel;
|
|
import java.nio.file.Files;
|
|
import java.nio.file.Path;
|
|
import java.util.Arrays;
|
|
import java.util.Random;
|
|
|
|
import jdk.test.lib.RandomFactory;
|
|
|
|
import static java.nio.file.StandardOpenOption.CREATE;
|
|
import static java.nio.file.StandardOpenOption.READ;
|
|
import static java.nio.file.StandardOpenOption.WRITE;
|
|
|
|
public class LargeGatheringWrite {
|
|
private static final int GB = 1024*1024*1024;
|
|
|
|
private static final Random RND = RandomFactory.getRandom();
|
|
|
|
private static long t0;
|
|
|
|
private static void printTime(String msg) {
|
|
System.out.printf("TIMESTAMP: %-16s: %f seconds%n", msg,
|
|
(System.nanoTime() - t0)/1000000000.0);
|
|
}
|
|
|
|
public static void main(String[] args) throws IOException {
|
|
t0 = System.nanoTime();
|
|
printTime("start");
|
|
|
|
// Create direct and heap buffers
|
|
ByteBuffer direct = ByteBuffer.allocateDirect(GB);
|
|
ByteBuffer heap = ByteBuffer.allocate(GB);
|
|
|
|
// Load buffers with random values
|
|
assert heap.hasArray();
|
|
RND.nextBytes(heap.array());
|
|
direct.put(0, heap, 0, heap.capacity());
|
|
|
|
// Create an array of buffers derived from direct and heap
|
|
ByteBuffer[] bigBuffers = new ByteBuffer[] {
|
|
direct,
|
|
heap,
|
|
direct.slice(0, GB/2),
|
|
heap.slice(0, GB/2),
|
|
direct.slice(GB/2, GB/2),
|
|
heap.slice(GB/2, GB/2),
|
|
direct.slice(GB/4, GB/2),
|
|
heap.slice(GB/4, GB/2),
|
|
direct.slice(0, 1),
|
|
heap.slice(GB - 2, 1)
|
|
};
|
|
|
|
// Calculate the sum of all buffer capacities
|
|
long totalLength = 0L;
|
|
for(ByteBuffer buf : bigBuffers)
|
|
totalLength += buf.capacity();
|
|
|
|
// Write the data to a temporary file
|
|
Path tempFile = Files.createTempFile("LargeGatheringWrite", ".dat");
|
|
try {
|
|
printTime("before writing");
|
|
System.out.printf("Writing %d bytes of data...%n", totalLength);
|
|
try (FileChannel fcw = FileChannel.open(tempFile, CREATE, WRITE);) {
|
|
// Print size of individual writes and total number written
|
|
long bytesWritten = 0;
|
|
long n;
|
|
while ((n = fcw.write(bigBuffers)) > 0) {
|
|
System.out.printf("Wrote %d bytes\n", n);
|
|
bytesWritten += n;
|
|
}
|
|
System.out.printf("Total of %d bytes written\n", bytesWritten);
|
|
}
|
|
printTime("after writing");
|
|
|
|
// Verify the content written
|
|
try (FileChannel fcr = FileChannel.open(tempFile, READ);) {
|
|
byte[] bytes = null;
|
|
for (ByteBuffer buf : bigBuffers) {
|
|
printTime("before verifying");
|
|
|
|
// For each buffer read the corresponding number of bytes
|
|
buf.rewind();
|
|
int length = buf.remaining();
|
|
System.out.printf("Checking length %d%n", length);
|
|
if (bytes == null || bytes.length < length)
|
|
bytes = new byte[length];
|
|
ByteBuffer dst = ByteBuffer.wrap(bytes).slice(0, length);
|
|
if (dst.remaining() != length)
|
|
throw new RuntimeException("remaining");
|
|
long totalRead = 0;
|
|
while (totalRead < length) {
|
|
int bytesRead = fcr.read(dst);
|
|
if (bytesRead < 0)
|
|
throw new RuntimeException("premature EOF");
|
|
totalRead += bytesRead;
|
|
}
|
|
dst.rewind();
|
|
|
|
// Verify that the bytes read from the file match the buffer
|
|
int mismatch;
|
|
if ((mismatch = dst.mismatch(buf)) != -1) {
|
|
String msg = String.format("mismatch: %d%n", mismatch);
|
|
throw new RuntimeException(msg);
|
|
}
|
|
|
|
printTime("after verifying");
|
|
}
|
|
}
|
|
} finally {
|
|
Files.delete(tempFile);
|
|
}
|
|
printTime("end");
|
|
}
|
|
}
|