Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc-Andre Laperle2014-08-28 03:15:58 +0000
committerMarc-Andre Laperle2014-09-03 03:04:38 +0000
commit78072af745bb9f33a47c3df7e6f530efcd06e039 (patch)
treead735dea68ce75beac7e72280c5bb8c12ecfcb62 /lttng/org.eclipse.linuxtools.ctf.core/src/org
parent9ef8264611f587184da79d2d044a7cc6eb4846ae (diff)
downloadorg.eclipse.linuxtools-78072af745bb9f33a47c3df7e6f530efcd06e039.tar.gz
org.eclipse.linuxtools-78072af745bb9f33a47c3df7e6f530efcd06e039.tar.xz
org.eclipse.linuxtools-78072af745bb9f33a47c3df7e6f530efcd06e039.zip
ctf: Provide a utility for "safe" mapping of a ByteBuffer
This works around a bug on Windows which prevents deleting a file after it was mapped. See http://bugs.java.com/view_bug.do?bug_id=4715154 Running TraceSeekBenchmark, I noticed a 10% decreased in performance (3.8s vs 3.4s) on Windows. On Linux, the difference is negligible (2.41s vs 2.40). Change-Id: Ie590709df4149708a37257ee3bc3d3d017f31c21 Signed-off-by: Marc-Andre Laperle <marc-andre.laperle@ericsson.com> Reviewed-on: https://git.eclipse.org/r/32448 Tested-by: Hudson CI
Diffstat (limited to 'lttng/org.eclipse.linuxtools.ctf.core/src/org')
-rw-r--r--lttng/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/ctf/core/trace/CTFStreamInput.java5
-rw-r--r--lttng/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/ctf/core/trace/CTFStreamInputPacketReader.java4
-rw-r--r--lttng/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/ctf/core/trace/CTFTrace.java7
-rw-r--r--lttng/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/internal/ctf/core/SafeMappedByteBuffer.java60
4 files changed, 69 insertions, 7 deletions
diff --git a/lttng/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/ctf/core/trace/CTFStreamInput.java b/lttng/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/ctf/core/trace/CTFStreamInput.java
index 157b1049c0..db8c6371c6 100644
--- a/lttng/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/ctf/core/trace/CTFStreamInput.java
+++ b/lttng/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/ctf/core/trace/CTFStreamInput.java
@@ -14,7 +14,7 @@ package org.eclipse.linuxtools.ctf.core.trace;
import java.io.File;
import java.io.IOException;
-import java.nio.MappedByteBuffer;
+import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
import java.nio.file.StandardOpenOption;
@@ -32,6 +32,7 @@ import org.eclipse.linuxtools.ctf.core.event.types.IntegerDefinition;
import org.eclipse.linuxtools.ctf.core.event.types.StringDefinition;
import org.eclipse.linuxtools.ctf.core.event.types.StructDeclaration;
import org.eclipse.linuxtools.ctf.core.event.types.StructDefinition;
+import org.eclipse.linuxtools.internal.ctf.core.SafeMappedByteBuffer;
import org.eclipse.linuxtools.internal.ctf.core.event.types.ArrayDefinition;
import org.eclipse.linuxtools.internal.ctf.core.trace.StreamInputPacketIndex;
import org.eclipse.linuxtools.internal.ctf.core.trace.StreamInputPacketIndexEntry;
@@ -289,7 +290,7 @@ public class CTFStreamInput implements IDefinitionScope, AutoCloseable {
* Map the packet.
*/
try (FileChannel fc = FileChannel.open(fFile.toPath(), StandardOpenOption.READ)) {
- MappedByteBuffer map = fc.map(MapMode.READ_ONLY, packetOffsetBytes, mapSize);
+ ByteBuffer map = SafeMappedByteBuffer.map(fc, MapMode.READ_ONLY, packetOffsetBytes, mapSize);
if (map == null) {
throw new CTFReaderException("Failed to allocate mapped byte buffer"); //$NON-NLS-1$
}
diff --git a/lttng/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/ctf/core/trace/CTFStreamInputPacketReader.java b/lttng/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/ctf/core/trace/CTFStreamInputPacketReader.java
index 9509a9929d..29ef23f9ff 100644
--- a/lttng/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/ctf/core/trace/CTFStreamInputPacketReader.java
+++ b/lttng/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/ctf/core/trace/CTFStreamInputPacketReader.java
@@ -13,7 +13,6 @@ package org.eclipse.linuxtools.ctf.core.trace;
import java.io.IOException;
import java.nio.ByteBuffer;
-import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel.MapMode;
import org.eclipse.jdt.annotation.NonNull;
@@ -35,6 +34,7 @@ import org.eclipse.linuxtools.ctf.core.event.types.SimpleDatatypeDefinition;
import org.eclipse.linuxtools.ctf.core.event.types.StructDeclaration;
import org.eclipse.linuxtools.ctf.core.event.types.StructDefinition;
import org.eclipse.linuxtools.ctf.core.event.types.VariantDefinition;
+import org.eclipse.linuxtools.internal.ctf.core.SafeMappedByteBuffer;
import org.eclipse.linuxtools.internal.ctf.core.event.EventDeclaration;
import org.eclipse.linuxtools.internal.ctf.core.event.types.composite.EventHeaderDefinition;
import org.eclipse.linuxtools.internal.ctf.core.trace.StreamInputPacketIndexEntry;
@@ -221,7 +221,7 @@ public class CTFStreamInputPacketReader implements IDefinitionScope, AutoCloseab
@NonNull
private ByteBuffer getByteBufferAt(long position, long size) throws CTFReaderException, IOException {
- MappedByteBuffer map = fStreamInputReader.getFc().map(MapMode.READ_ONLY, position, size);
+ ByteBuffer map = SafeMappedByteBuffer.map(fStreamInputReader.getFc(), MapMode.READ_ONLY, position, size);
if (map == null) {
throw new CTFReaderException("Failed to allocate mapped byte buffer"); //$NON-NLS-1$
}
diff --git a/lttng/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/ctf/core/trace/CTFTrace.java b/lttng/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/ctf/core/trace/CTFTrace.java
index 0c2ee5a5cb..3414110a2c 100644
--- a/lttng/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/ctf/core/trace/CTFTrace.java
+++ b/lttng/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/ctf/core/trace/CTFTrace.java
@@ -19,8 +19,8 @@ import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.Serializable;
+import java.nio.ByteBuffer;
import java.nio.ByteOrder;
-import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
import java.util.Arrays;
@@ -44,6 +44,7 @@ import org.eclipse.linuxtools.ctf.core.event.types.IDefinition;
import org.eclipse.linuxtools.ctf.core.event.types.IntegerDefinition;
import org.eclipse.linuxtools.ctf.core.event.types.StructDeclaration;
import org.eclipse.linuxtools.ctf.core.event.types.StructDefinition;
+import org.eclipse.linuxtools.internal.ctf.core.SafeMappedByteBuffer;
import org.eclipse.linuxtools.internal.ctf.core.event.CTFCallsiteComparator;
import org.eclipse.linuxtools.internal.ctf.core.event.metadata.exceptions.ParseException;
import org.eclipse.linuxtools.internal.ctf.core.event.types.ArrayDefinition;
@@ -507,7 +508,7 @@ public class CTFTrace implements IDefinitionScope, AutoCloseable {
* if there is a file error
*/
private CTFStream openStreamInput(File streamFile) throws CTFReaderException {
- MappedByteBuffer byteBuffer;
+ ByteBuffer byteBuffer;
BitBuffer streamBitBuffer;
CTFStream stream;
@@ -519,7 +520,7 @@ public class CTFTrace implements IDefinitionScope, AutoCloseable {
try (FileInputStream fis = new FileInputStream(streamFile);
FileChannel fc = fis.getChannel()) {
/* Map one memory page of 4 kiB */
- byteBuffer = fc.map(MapMode.READ_ONLY, 0, (int) Math.min(fc.size(), 4096L));
+ byteBuffer = SafeMappedByteBuffer.map(fc, MapMode.READ_ONLY, 0, (int) Math.min(fc.size(), 4096L));
if (byteBuffer == null) {
throw new IllegalStateException("Failed to allocate memory"); //$NON-NLS-1$
}
diff --git a/lttng/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/internal/ctf/core/SafeMappedByteBuffer.java b/lttng/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/internal/ctf/core/SafeMappedByteBuffer.java
new file mode 100644
index 0000000000..8b06b2733b
--- /dev/null
+++ b/lttng/org.eclipse.linuxtools.ctf.core/src/org/eclipse/linuxtools/internal/ctf/core/SafeMappedByteBuffer.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Marc-Andre Laperle - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.internal.ctf.core;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+
+import org.eclipse.core.runtime.Platform;
+
+/**
+ * A common utility for mapping a ByteBuffer safely to work around a bug on
+ * Windows which prevents deleting a file after it was mapped. On Windows, the
+ * ByteBuffer will be allocated and the file will be read instead of being
+ * mapped.
+ *
+ * http://bugs.java.com/view_bug.do?bug_id=4715154
+ */
+public class SafeMappedByteBuffer {
+
+ private static final boolean IS_WIN32 = Platform.OS_WIN32.equals(Platform.getOS());
+
+ /**
+ * Maps a region of this channel's file directly into memory. On Windows,
+ * this will allocate a new ByteBuffer and read the file.
+ *
+ * @param fc
+ * the file channel
+ * @param mode
+ * the mapping mode
+ * @param position
+ * the position within the file
+ * @param size
+ * the size of the region to be mapped (or read)
+ * @return the mapped ByteBuffer
+ * @throws IOException
+ * on FileChannel operations failures
+ */
+ public static ByteBuffer map(FileChannel fc, FileChannel.MapMode mode, long position, long size) throws IOException {
+ ByteBuffer byteBuffer;
+ if (IS_WIN32) {
+ byteBuffer = ByteBuffer.allocate((int) size);
+ fc.read(byteBuffer, position);
+ } else {
+ byteBuffer = fc.map(mode, position, size);
+ }
+
+ return byteBuffer;
+ }
+}

Back to the top