mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-20 11:04:34 +02:00
8224974: Implement JEP 352
Non-Volatile Mapped Byte Buffers Reviewed-by: alanb, kvn, bpb, gromero, darcy, shade, bulasevich, dchuyko
This commit is contained in:
parent
db359f11b5
commit
047b8bfeb7
53 changed files with 1400 additions and 69 deletions
|
@ -168,15 +168,16 @@ class Direct$Type$Buffer$RW$$BO$
|
|||
//
|
||||
protected Direct$Type$Buffer$RW$(int cap, long addr,
|
||||
FileDescriptor fd,
|
||||
Runnable unmapper)
|
||||
Runnable unmapper,
|
||||
boolean isSync)
|
||||
{
|
||||
#if[rw]
|
||||
super(-1, 0, cap, cap, fd);
|
||||
super(-1, 0, cap, cap, fd, isSync);
|
||||
address = addr;
|
||||
cleaner = Cleaner.create(this, unmapper);
|
||||
att = null;
|
||||
#else[rw]
|
||||
super(cap, addr, fd, unmapper);
|
||||
super(cap, addr, fd, unmapper, isSync);
|
||||
this.isReadOnly = true;
|
||||
#end[rw]
|
||||
}
|
||||
|
|
|
@ -78,18 +78,33 @@ public abstract class MappedByteBuffer
|
|||
// operations if valid; null if the buffer is not mapped.
|
||||
private final FileDescriptor fd;
|
||||
|
||||
// A flag true if this buffer is mapped against non-volatile
|
||||
// memory using one of the extended FileChannel.MapMode modes,
|
||||
// MapMode.READ_ONLY_SYNC or MapMode.READ_WRITE_SYNC and false if
|
||||
// it is mapped using any of the other modes. This flag only
|
||||
// determines the behavior of force operations.
|
||||
private final boolean isSync;
|
||||
|
||||
// This should only be invoked by the DirectByteBuffer constructors
|
||||
//
|
||||
MappedByteBuffer(int mark, int pos, int lim, int cap, // package-private
|
||||
FileDescriptor fd)
|
||||
{
|
||||
FileDescriptor fd, boolean isSync) {
|
||||
super(mark, pos, lim, cap);
|
||||
this.fd = fd;
|
||||
this.isSync = isSync;
|
||||
}
|
||||
|
||||
MappedByteBuffer(int mark, int pos, int lim, int cap, // package-private
|
||||
boolean isSync) {
|
||||
super(mark, pos, lim, cap);
|
||||
this.fd = null;
|
||||
this.isSync = isSync;
|
||||
}
|
||||
|
||||
MappedByteBuffer(int mark, int pos, int lim, int cap) { // package-private
|
||||
super(mark, pos, lim, cap);
|
||||
this.fd = null;
|
||||
this.isSync = false;
|
||||
}
|
||||
|
||||
// Returns the distance (in bytes) of the buffer start from the
|
||||
|
@ -146,6 +161,23 @@ public abstract class MappedByteBuffer
|
|||
return address & ~(pageSize - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells whether this buffer was mapped against a non-volatile
|
||||
* memory device by passing one of the sync map modes {@link
|
||||
* jdk.nio.mapmode.ExtendedMapMode#READ_ONLY_SYNC
|
||||
* ExtendedMapModeMapMode#READ_ONLY_SYNC} or {@link
|
||||
* jdk.nio.mapmode.ExtendedMapMode#READ_ONLY_SYNC
|
||||
* ExtendedMapMode#READ_WRITE_SYNC} in the call to {@link
|
||||
* java.nio.channels.FileChannel#map FileChannel.map} or was
|
||||
* mapped by passing one of the other map modes.
|
||||
*
|
||||
* @return true if the file was mapped using one of the sync map
|
||||
* modes, otherwise false.
|
||||
*/
|
||||
private boolean isSync() {
|
||||
return isSync;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells whether or not this buffer's content is resident in physical
|
||||
* memory.
|
||||
|
@ -168,6 +200,10 @@ public abstract class MappedByteBuffer
|
|||
if (fd == null) {
|
||||
return true;
|
||||
}
|
||||
// a sync mapped buffer is always loaded
|
||||
if (isSync()) {
|
||||
return true;
|
||||
}
|
||||
if ((address == 0) || (capacity() == 0))
|
||||
return true;
|
||||
long offset = mappingOffset();
|
||||
|
@ -192,6 +228,10 @@ public abstract class MappedByteBuffer
|
|||
if (fd == null) {
|
||||
return this;
|
||||
}
|
||||
// no need to load a sync mapped buffer
|
||||
if (isSync()) {
|
||||
return this;
|
||||
}
|
||||
if ((address == 0) || (capacity() == 0))
|
||||
return this;
|
||||
long offset = mappingOffset();
|
||||
|
@ -247,6 +287,9 @@ public abstract class MappedByteBuffer
|
|||
if (fd == null) {
|
||||
return this;
|
||||
}
|
||||
if (isSync) {
|
||||
return force(0, limit());
|
||||
}
|
||||
if ((address != 0) && (capacity() != 0)) {
|
||||
long offset = mappingOffset();
|
||||
force0(fd, mappingAddress(offset), mappingLength(offset));
|
||||
|
@ -303,8 +346,14 @@ public abstract class MappedByteBuffer
|
|||
if ((address != 0) && (limit() != 0)) {
|
||||
// check inputs
|
||||
Objects.checkFromIndexSize(index, length, limit());
|
||||
long offset = mappingOffset(index);
|
||||
force0(fd, mappingAddress(offset, index), mappingLength(offset, length));
|
||||
if (isSync) {
|
||||
// simply force writeback of associated cache lines
|
||||
Unsafe.getUnsafe().writebackMemory(address + index, length);
|
||||
} else {
|
||||
// force writeback via file descriptor
|
||||
long offset = mappingOffset(index);
|
||||
force0(fd, mappingAddress(offset, index), mappingLength(offset, length));
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (c) 2019, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package jdk.internal.misc;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.nio.channels.FileChannel.MapMode;
|
||||
|
||||
/**
|
||||
* JDK-specific map modes implemented in java.base.
|
||||
*/
|
||||
public class ExtendedMapMode {
|
||||
|
||||
static final MethodHandle MAP_MODE_CONSTRUCTOR;
|
||||
|
||||
static {
|
||||
try {
|
||||
var lookup = MethodHandles.privateLookupIn(MapMode.class, MethodHandles.lookup());
|
||||
var methodType = MethodType.methodType(void.class, String.class);
|
||||
MAP_MODE_CONSTRUCTOR = lookup.findConstructor(MapMode.class, methodType);
|
||||
} catch (Exception e) {
|
||||
throw new InternalError(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static final MapMode READ_ONLY_SYNC = newMapMode("READ_ONLY_SYNC");
|
||||
|
||||
public static final MapMode READ_WRITE_SYNC = newMapMode("READ_WRITE_SYNC");
|
||||
|
||||
private static MapMode newMapMode(String name) {
|
||||
try {
|
||||
return (MapMode) MAP_MODE_CONSTRUCTOR.invoke(name);
|
||||
} catch (Throwable e) {
|
||||
throw new InternalError(e);
|
||||
}
|
||||
}
|
||||
|
||||
private ExtendedMapMode() { }
|
||||
}
|
|
@ -921,6 +921,101 @@ public final class Unsafe {
|
|||
checkPointer(null, address);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure writeback of a specified virtual memory address range
|
||||
* from cache to physical memory. All bytes in the address range
|
||||
* are guaranteed to have been written back to physical memory on
|
||||
* return from this call i.e. subsequently executed store
|
||||
* instructions are guaranteed not to be visible before the
|
||||
* writeback is completed.
|
||||
*
|
||||
* @param address
|
||||
* the lowest byte address that must be guaranteed written
|
||||
* back to memory. bytes at lower addresses may also be
|
||||
* written back.
|
||||
*
|
||||
* @param length
|
||||
* the length in bytes of the region starting at address
|
||||
* that must be guaranteed written back to memory.
|
||||
*
|
||||
* @throws RuntimeException if memory writeback is not supported
|
||||
* on the current hardware of if the arguments are invalid.
|
||||
* (<em>Note:</em> after optimization, invalid inputs may
|
||||
* go undetected, which will lead to unpredictable
|
||||
* behavior)
|
||||
*
|
||||
* @since 14
|
||||
*/
|
||||
|
||||
public void writebackMemory(long address, long length) {
|
||||
checkWritebackEnabled();
|
||||
checkWritebackMemory(address, length);
|
||||
|
||||
// perform any required pre-writeback barrier
|
||||
writebackPreSync0();
|
||||
|
||||
// write back one cache line at a time
|
||||
long line = dataCacheLineAlignDown(address);
|
||||
long end = address + length;
|
||||
while (line < end) {
|
||||
writeback0(line);
|
||||
line += dataCacheLineFlushSize();
|
||||
}
|
||||
|
||||
// perform any required post-writeback barrier
|
||||
writebackPostSync0();
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the arguments to writebackMemory
|
||||
*
|
||||
* @throws RuntimeException if the arguments are invalid
|
||||
* (<em>Note:</em> after optimization, invalid inputs may
|
||||
* go undetected, which will lead to unpredictable
|
||||
* behavior)
|
||||
*/
|
||||
private void checkWritebackMemory(long address, long length) {
|
||||
checkNativeAddress(address);
|
||||
checkSize(length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that the current hardware supports memory writeback.
|
||||
* (<em>Note:</em> this is a belt and braces check. Clients are
|
||||
* expected to test whether writeback is enabled by calling
|
||||
* ({@link isWritebackEnabled #isWritebackEnabled} and avoid
|
||||
* calling method {@link writeback #writeback} if it is disabled).
|
||||
*
|
||||
*
|
||||
* @throws RuntimeException if memory writeback is not supported
|
||||
*/
|
||||
private void checkWritebackEnabled() {
|
||||
if (!isWritebackEnabled()) {
|
||||
throw new RuntimeException("writebackMemory not enabled!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* force writeback of an individual cache line.
|
||||
*
|
||||
* @param address
|
||||
* the start address of the cache line to be written back
|
||||
*/
|
||||
@HotSpotIntrinsicCandidate
|
||||
private native void writeback0(long address);
|
||||
|
||||
/**
|
||||
* Serialize writeback operations relative to preceding memory writes.
|
||||
*/
|
||||
@HotSpotIntrinsicCandidate
|
||||
private native void writebackPreSync0();
|
||||
|
||||
/**
|
||||
* Serialize writeback operations relative to following memory writes.
|
||||
*/
|
||||
@HotSpotIntrinsicCandidate
|
||||
private native void writebackPostSync0();
|
||||
|
||||
/// random queries
|
||||
|
||||
/**
|
||||
|
@ -1175,6 +1270,27 @@ public final class Unsafe {
|
|||
*/
|
||||
public int pageSize() { return PAGE_SIZE; }
|
||||
|
||||
/**
|
||||
* Reports the size in bytes of a data cache line written back by
|
||||
* the hardware cache line flush operation available to the JVM or
|
||||
* 0 if data cache line flushing is not enabled.
|
||||
*/
|
||||
public int dataCacheLineFlushSize() { return DATA_CACHE_LINE_FLUSH_SIZE; }
|
||||
|
||||
/**
|
||||
* Rounds down address to a data cache line boundary as
|
||||
* determined by {@link #dataCacheLineFlushSize}
|
||||
* @return the rounded down address
|
||||
*/
|
||||
public long dataCacheLineAlignDown(long address) {
|
||||
return (address & ~(DATA_CACHE_LINE_FLUSH_SIZE - 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if data cache line writeback
|
||||
*/
|
||||
public static boolean isWritebackEnabled() { return DATA_CACHE_LINE_FLUSH_SIZE != 0; }
|
||||
|
||||
/// random trusted operations from JNI:
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, Red Hat Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
|
@ -94,10 +95,28 @@ final class UnsafeConstants {
|
|||
|
||||
static final boolean UNALIGNED_ACCESS;
|
||||
|
||||
/**
|
||||
* The size of an L1 data cache line which will be either a power
|
||||
* of two or zero.
|
||||
*
|
||||
* <p>A non-zero value indicates that writeback to memory is
|
||||
* enabled for the current processor. The value defines the
|
||||
* natural alignment and size of any data cache line committed to
|
||||
* memory by a single writeback operation. If data cache line
|
||||
* writeback is not enabled for the current hardware the field
|
||||
* will have value 0.
|
||||
*
|
||||
* @implNote
|
||||
* The actual value for this field is injected by the JVM.
|
||||
*/
|
||||
|
||||
static final int DATA_CACHE_LINE_FLUSH_SIZE;
|
||||
|
||||
static {
|
||||
ADDRESS_SIZE0 = 0;
|
||||
PAGE_SIZE = 0;
|
||||
BIG_ENDIAN = false;
|
||||
UNALIGNED_ACCESS = false;
|
||||
DATA_CACHE_LINE_FLUSH_SIZE = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -192,6 +192,7 @@ module java.base {
|
|||
jdk.compiler,
|
||||
jdk.jfr,
|
||||
jdk.jshell,
|
||||
jdk.nio.mapmode,
|
||||
jdk.scripting.nashorn,
|
||||
jdk.scripting.nashorn.shell,
|
||||
jdk.unsupported,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2019, 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
|
||||
|
@ -46,6 +46,8 @@ import java.nio.channels.WritableByteChannel;
|
|||
import jdk.internal.access.JavaIOFileDescriptorAccess;
|
||||
import jdk.internal.access.JavaNioAccess;
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
import jdk.internal.misc.ExtendedMapMode;
|
||||
import jdk.internal.misc.Unsafe;
|
||||
import jdk.internal.ref.Cleaner;
|
||||
import jdk.internal.ref.CleanerFactory;
|
||||
|
||||
|
@ -860,20 +862,15 @@ public class FileChannelImpl
|
|||
|
||||
// -- Memory-mapped buffers --
|
||||
|
||||
private static class Unmapper
|
||||
private static abstract class Unmapper
|
||||
implements Runnable
|
||||
{
|
||||
// may be required to close file
|
||||
private static final NativeDispatcher nd = new FileDispatcherImpl();
|
||||
|
||||
// keep track of mapped buffer usage
|
||||
static volatile int count;
|
||||
static volatile long totalSize;
|
||||
static volatile long totalCapacity;
|
||||
|
||||
private volatile long address;
|
||||
private final long size;
|
||||
private final int cap;
|
||||
protected final long size;
|
||||
protected final int cap;
|
||||
private final FileDescriptor fd;
|
||||
|
||||
private Unmapper(long address, long size, int cap,
|
||||
|
@ -884,12 +881,6 @@ public class FileChannelImpl
|
|||
this.size = size;
|
||||
this.cap = cap;
|
||||
this.fd = fd;
|
||||
|
||||
synchronized (Unmapper.class) {
|
||||
count++;
|
||||
totalSize += size;
|
||||
totalCapacity += cap;
|
||||
}
|
||||
}
|
||||
|
||||
public void run() {
|
||||
|
@ -907,7 +898,63 @@ public class FileChannelImpl
|
|||
}
|
||||
}
|
||||
|
||||
synchronized (Unmapper.class) {
|
||||
decrementStats();
|
||||
}
|
||||
protected abstract void incrementStats();
|
||||
protected abstract void decrementStats();
|
||||
}
|
||||
|
||||
private static class DefaultUnmapper extends Unmapper {
|
||||
|
||||
// keep track of non-sync mapped buffer usage
|
||||
static volatile int count;
|
||||
static volatile long totalSize;
|
||||
static volatile long totalCapacity;
|
||||
|
||||
public DefaultUnmapper(long address, long size, int cap,
|
||||
FileDescriptor fd) {
|
||||
super(address, size, cap, fd);
|
||||
incrementStats();
|
||||
}
|
||||
|
||||
protected void incrementStats() {
|
||||
synchronized (DefaultUnmapper.class) {
|
||||
count++;
|
||||
totalSize += size;
|
||||
totalCapacity += cap;
|
||||
}
|
||||
}
|
||||
protected void decrementStats() {
|
||||
synchronized (DefaultUnmapper.class) {
|
||||
count--;
|
||||
totalSize -= size;
|
||||
totalCapacity -= cap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class SyncUnmapper extends Unmapper {
|
||||
|
||||
// keep track of mapped buffer usage
|
||||
static volatile int count;
|
||||
static volatile long totalSize;
|
||||
static volatile long totalCapacity;
|
||||
|
||||
public SyncUnmapper(long address, long size, int cap,
|
||||
FileDescriptor fd) {
|
||||
super(address, size, cap, fd);
|
||||
incrementStats();
|
||||
}
|
||||
|
||||
protected void incrementStats() {
|
||||
synchronized (SyncUnmapper.class) {
|
||||
count++;
|
||||
totalSize += size;
|
||||
totalCapacity += cap;
|
||||
}
|
||||
}
|
||||
protected void decrementStats() {
|
||||
synchronized (SyncUnmapper.class) {
|
||||
count--;
|
||||
totalSize -= size;
|
||||
totalCapacity -= cap;
|
||||
|
@ -941,18 +988,30 @@ public class FileChannelImpl
|
|||
throw new IllegalArgumentException("Size exceeds Integer.MAX_VALUE");
|
||||
|
||||
int imode;
|
||||
boolean isSync = false;
|
||||
if (mode == MapMode.READ_ONLY)
|
||||
imode = MAP_RO;
|
||||
else if (mode == MapMode.READ_WRITE)
|
||||
imode = MAP_RW;
|
||||
else if (mode == MapMode.PRIVATE)
|
||||
imode = MAP_PV;
|
||||
else
|
||||
else if (mode == ExtendedMapMode.READ_ONLY_SYNC) {
|
||||
imode = MAP_RO;
|
||||
isSync = true;
|
||||
} else if (mode == ExtendedMapMode.READ_WRITE_SYNC) {
|
||||
imode = MAP_RW;
|
||||
isSync = true;
|
||||
} else {
|
||||
throw new UnsupportedOperationException();
|
||||
if ((mode != MapMode.READ_ONLY) && !writable)
|
||||
}
|
||||
if ((mode != MapMode.READ_ONLY) && mode != ExtendedMapMode.READ_ONLY_SYNC && !writable)
|
||||
throw new NonWritableChannelException();
|
||||
if (!readable)
|
||||
throw new NonReadableChannelException();
|
||||
// reject SYNC request if writeback is not enabled for this platform
|
||||
if (isSync && !Unsafe.isWritebackEnabled()) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
long addr = -1;
|
||||
int ti = -1;
|
||||
|
@ -990,9 +1049,9 @@ public class FileChannelImpl
|
|||
// a valid file descriptor is not required
|
||||
FileDescriptor dummy = new FileDescriptor();
|
||||
if ((!writable) || (imode == MAP_RO))
|
||||
return Util.newMappedByteBufferR(0, 0, dummy, null);
|
||||
return Util.newMappedByteBufferR(0, 0, dummy, null, isSync);
|
||||
else
|
||||
return Util.newMappedByteBuffer(0, 0, dummy, null);
|
||||
return Util.newMappedByteBuffer(0, 0, dummy, null, isSync);
|
||||
}
|
||||
|
||||
pagePosition = (int)(position % allocationGranularity);
|
||||
|
@ -1000,7 +1059,7 @@ public class FileChannelImpl
|
|||
mapSize = size + pagePosition;
|
||||
try {
|
||||
// If map0 did not throw an exception, the address is valid
|
||||
addr = map0(imode, mapPosition, mapSize);
|
||||
addr = map0(imode, mapPosition, mapSize, isSync);
|
||||
} catch (OutOfMemoryError x) {
|
||||
// An OutOfMemoryError may indicate that we've exhausted
|
||||
// memory so force gc and re-attempt map
|
||||
|
@ -1011,7 +1070,7 @@ public class FileChannelImpl
|
|||
Thread.currentThread().interrupt();
|
||||
}
|
||||
try {
|
||||
addr = map0(imode, mapPosition, mapSize);
|
||||
addr = map0(imode, mapPosition, mapSize, isSync);
|
||||
} catch (OutOfMemoryError y) {
|
||||
// After a second OOME, fail
|
||||
throw new IOException("Map failed", y);
|
||||
|
@ -1032,17 +1091,21 @@ public class FileChannelImpl
|
|||
assert (IOStatus.checkAll(addr));
|
||||
assert (addr % allocationGranularity == 0);
|
||||
int isize = (int)size;
|
||||
Unmapper um = new Unmapper(addr, mapSize, isize, mfd);
|
||||
Unmapper um = (isSync
|
||||
? new SyncUnmapper(addr, mapSize, isize, mfd)
|
||||
: new DefaultUnmapper(addr, mapSize, isize, mfd));
|
||||
if ((!writable) || (imode == MAP_RO)) {
|
||||
return Util.newMappedByteBufferR(isize,
|
||||
addr + pagePosition,
|
||||
mfd,
|
||||
um);
|
||||
um,
|
||||
isSync);
|
||||
} else {
|
||||
return Util.newMappedByteBuffer(isize,
|
||||
addr + pagePosition,
|
||||
mfd,
|
||||
um);
|
||||
um,
|
||||
isSync);
|
||||
}
|
||||
} finally {
|
||||
threads.remove(ti);
|
||||
|
@ -1062,15 +1125,40 @@ public class FileChannelImpl
|
|||
}
|
||||
@Override
|
||||
public long getCount() {
|
||||
return Unmapper.count;
|
||||
return DefaultUnmapper.count;
|
||||
}
|
||||
@Override
|
||||
public long getTotalCapacity() {
|
||||
return Unmapper.totalCapacity;
|
||||
return DefaultUnmapper.totalCapacity;
|
||||
}
|
||||
@Override
|
||||
public long getMemoryUsed() {
|
||||
return Unmapper.totalSize;
|
||||
return DefaultUnmapper.totalSize;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked by sun.management.ManagementFactoryHelper to create the management
|
||||
* interface for sync mapped buffers.
|
||||
*/
|
||||
public static JavaNioAccess.BufferPool getSyncMappedBufferPool() {
|
||||
return new JavaNioAccess.BufferPool() {
|
||||
@Override
|
||||
public String getName() {
|
||||
return "mapped - 'non-volatile memory'";
|
||||
}
|
||||
@Override
|
||||
public long getCount() {
|
||||
return SyncUnmapper.count;
|
||||
}
|
||||
@Override
|
||||
public long getTotalCapacity() {
|
||||
return SyncUnmapper.totalCapacity;
|
||||
}
|
||||
@Override
|
||||
public long getMemoryUsed() {
|
||||
return SyncUnmapper.totalSize;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -1196,7 +1284,7 @@ public class FileChannelImpl
|
|||
// -- Native methods --
|
||||
|
||||
// Creates a new mapping
|
||||
private native long map0(int prot, long position, long length)
|
||||
private native long map0(int prot, long position, long length, boolean isSync)
|
||||
throws IOException;
|
||||
|
||||
// Removes an existing mapping
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2019, 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
|
||||
|
@ -415,7 +415,8 @@ public class Util {
|
|||
new Class<?>[] { int.class,
|
||||
long.class,
|
||||
FileDescriptor.class,
|
||||
Runnable.class });
|
||||
Runnable.class,
|
||||
boolean.class });
|
||||
ctor.setAccessible(true);
|
||||
directByteBufferConstructor = ctor;
|
||||
} catch (ClassNotFoundException |
|
||||
|
@ -430,7 +431,8 @@ public class Util {
|
|||
|
||||
static MappedByteBuffer newMappedByteBuffer(int size, long addr,
|
||||
FileDescriptor fd,
|
||||
Runnable unmapper)
|
||||
Runnable unmapper,
|
||||
boolean isSync)
|
||||
{
|
||||
MappedByteBuffer dbb;
|
||||
if (directByteBufferConstructor == null)
|
||||
|
@ -440,7 +442,8 @@ public class Util {
|
|||
new Object[] { size,
|
||||
addr,
|
||||
fd,
|
||||
unmapper });
|
||||
unmapper,
|
||||
isSync});
|
||||
} catch (InstantiationException |
|
||||
IllegalAccessException |
|
||||
InvocationTargetException e) {
|
||||
|
@ -460,7 +463,8 @@ public class Util {
|
|||
new Class<?>[] { int.class,
|
||||
long.class,
|
||||
FileDescriptor.class,
|
||||
Runnable.class });
|
||||
Runnable.class,
|
||||
boolean.class });
|
||||
ctor.setAccessible(true);
|
||||
directByteBufferRConstructor = ctor;
|
||||
} catch (ClassNotFoundException |
|
||||
|
@ -475,7 +479,8 @@ public class Util {
|
|||
|
||||
static MappedByteBuffer newMappedByteBufferR(int size, long addr,
|
||||
FileDescriptor fd,
|
||||
Runnable unmapper)
|
||||
Runnable unmapper,
|
||||
boolean isSync)
|
||||
{
|
||||
MappedByteBuffer dbb;
|
||||
if (directByteBufferRConstructor == null)
|
||||
|
@ -485,7 +490,8 @@ public class Util {
|
|||
new Object[] { size,
|
||||
addr,
|
||||
fd,
|
||||
unmapper });
|
||||
unmapper,
|
||||
isSync});
|
||||
} catch (InstantiationException |
|
||||
IllegalAccessException |
|
||||
InvocationTargetException e) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue