diff --git a/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core.tests/src/org/eclipse/tracecompass/incubator/ftrace/core/tests/binary/buffer/BinaryFTraceByteBufferTest.java b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core.tests/src/org/eclipse/tracecompass/incubator/ftrace/core/tests/binary/buffer/BinaryFTraceByteBufferTest.java index 46676e0b5..5d358178b 100644 --- a/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core.tests/src/org/eclipse/tracecompass/incubator/ftrace/core/tests/binary/buffer/BinaryFTraceByteBufferTest.java +++ b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core.tests/src/org/eclipse/tracecompass/incubator/ftrace/core/tests/binary/buffer/BinaryFTraceByteBufferTest.java @@ -45,38 +45,37 @@ public void testOffsetCounter() throws IOException { String traceLocation = FTraceUtils.getTraceAbsolutePath(FtraceTestTrace.TEST_2_6_MULTIPLE_CPUS); long currentOffset = 0; - try (BinaryFTraceByteBuffer buffer = new BinaryFTraceByteBuffer(traceLocation)) { - // Read the magic values - buffer.getNextBytes(BinaryFTraceHeaderElementSize.MAGIC_VALUE); - currentOffset += BinaryFTraceHeaderElementSize.MAGIC_VALUE; - assertEquals(buffer.getCurrentOffset(), currentOffset); + BinaryFTraceByteBuffer buffer = new BinaryFTraceByteBuffer(traceLocation); + // Read the magic values + buffer.getNextBytes(BinaryFTraceHeaderElementSize.MAGIC_VALUE); + currentOffset += BinaryFTraceHeaderElementSize.MAGIC_VALUE; + assertEquals(buffer.getCurrentOffset(), currentOffset); - String tracingString = buffer.getNextBytesAsString(BinaryFTraceHeaderElementSize.TRACING_STRING); - currentOffset += BinaryFTraceHeaderElementSize.TRACING_STRING; - assertEquals(tracingString, TRACING); - assertEquals(buffer.getCurrentOffset(), currentOffset); + String tracingString = buffer.getNextBytesAsString(BinaryFTraceHeaderElementSize.TRACING_STRING); + currentOffset += BinaryFTraceHeaderElementSize.TRACING_STRING; + assertEquals(tracingString, TRACING); + assertEquals(buffer.getCurrentOffset(), currentOffset); - String versionString = buffer.getNextString(); - currentOffset += (BinaryFTraceHeaderElementSize.FTRACE_VERSION + BinaryFTraceHeaderElementSize.STRING_TERMINATOR); - assertEquals(versionString, VERSION); - assertEquals(buffer.getCurrentOffset(), currentOffset); + String versionString = buffer.getNextString(); + currentOffset += (BinaryFTraceHeaderElementSize.FTRACE_VERSION + BinaryFTraceHeaderElementSize.STRING_TERMINATOR); + assertEquals(versionString, VERSION); + assertEquals(buffer.getCurrentOffset(), currentOffset); - // Read various data types and validate offset changes - buffer.getNextShort(); - currentOffset += BinaryFTraceDataType.SHORT.getSize(); - assertEquals(buffer.getCurrentOffset(), currentOffset); + // Read various data types and validate offset changes + buffer.getNextShort(); + currentOffset += BinaryFTraceDataType.SHORT.getSize(); + assertEquals(buffer.getCurrentOffset(), currentOffset); - buffer.getNextInt(); - currentOffset += BinaryFTraceDataType.INT.getSize(); - assertEquals(buffer.getCurrentOffset(), currentOffset); + buffer.getNextInt(); + currentOffset += BinaryFTraceDataType.INT.getSize(); + assertEquals(buffer.getCurrentOffset(), currentOffset); - buffer.getNextLong(); - currentOffset += BinaryFTraceDataType.LONG.getSize(); - assertEquals(buffer.getCurrentOffset(), currentOffset); + buffer.getNextLong(); + currentOffset += BinaryFTraceDataType.LONG.getSize(); + assertEquals(buffer.getCurrentOffset(), currentOffset); - buffer.movePointerToOffset(RANDOM_OFFSET); - currentOffset = RANDOM_OFFSET; - assertEquals(buffer.getCurrentOffset(), currentOffset); - } + buffer.movePointerToOffset(RANDOM_OFFSET); + currentOffset = RANDOM_OFFSET; + assertEquals(buffer.getCurrentOffset(), currentOffset); } } diff --git a/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/binary/header/BinaryFTraceHeaderInfo.java b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/binary/header/BinaryFTraceHeaderInfo.java index 741d774ac..3c292ac2a 100644 --- a/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/binary/header/BinaryFTraceHeaderInfo.java +++ b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/binary/header/BinaryFTraceHeaderInfo.java @@ -17,6 +17,9 @@ import java.util.Map; import java.util.Optional; +import org.eclipse.tracecompass.incubator.internal.ftrace.core.binary.parser.BinaryFTraceByteBuffer; +import org.eclipse.tracecompass.incubator.internal.ftrace.core.binary.parser.BinaryFTraceFileMapping; + /** * A representation of all header information required for parsing the events in * the FTrace file. @@ -46,12 +49,15 @@ public class BinaryFTraceHeaderInfo { private List cpus; + private BinaryFTraceFileMapping fTraceMapping; + /** * Constructor * * @param builder The builder used to construct the trace header + * @param traceMapping the file memory mapping used to read data from the file */ - private BinaryFTraceHeaderInfo(BinaryFTraceHeaderInfoBuilder builder) { + private BinaryFTraceHeaderInfo(BinaryFTraceHeaderInfoBuilder builder, BinaryFTraceFileMapping traceMapping) { fFilePath = builder.fBuilderFilePath; fVersion = builder.fBuilderVersion; fEndianess = builder.fBuilderEndianess; // Because Java by default is @@ -72,25 +78,26 @@ private BinaryFTraceHeaderInfo(BinaryFTraceHeaderInfoBuilder builder) { fOptions = builder.fBuilderOptions; fEventCommonFields = builder.fBuilderEventCommonFields; cpus = builder.fBuilderCpus; + fTraceMapping = traceMapping; + fTraceMapping.order(fEndianess); } /** - * Get the file path to the trace file. + * Get the trace contents as a ByteBuffer. * - * @return The file path of the trace file. + * @return the trace contents as a ByteBuffer */ - public String getFilePath() { - return fFilePath; + public BinaryFTraceByteBuffer getMappedBuffer() { + return new BinaryFTraceByteBuffer(fTraceMapping); } /** - * Set the file path to the trace file. + * Get the file path to the trace file. * - * @param filePath - * The file path of the trace file. + * @return The file path of the trace file. */ - public void setFilePath(String filePath) { - this.fFilePath = filePath; + public String getFilePath() { + return fFilePath; } /** @@ -612,11 +619,12 @@ public BinaryFTraceHeaderInfoBuilder cpus(List builderCpus) * Build an immutable {@link BinaryFTraceHeaderInfo} using the current * state of the builder. * + * @param traceMapping the memory mapped file buffer to be used for reading data * @return A {@link BinaryFTraceHeaderInfo} object. */ - public BinaryFTraceHeaderInfo build() { + public BinaryFTraceHeaderInfo build(BinaryFTraceFileMapping traceMapping) { fBuilderEventCommonFields = getCommonFields(); - return new BinaryFTraceHeaderInfo(this); + return new BinaryFTraceHeaderInfo(this, traceMapping); } private Map getCommonFields() { diff --git a/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/binary/iterator/BinaryFTraceCPUPageIterator.java b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/binary/iterator/BinaryFTraceCPUPageIterator.java index 1623b66bb..2c0c97a26 100644 --- a/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/binary/iterator/BinaryFTraceCPUPageIterator.java +++ b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/binary/iterator/BinaryFTraceCPUPageIterator.java @@ -64,10 +64,8 @@ public class BinaryFTraceCPUPageIterator implements Closeable { * The CPU data page to read * @param fileHeader * The FTrace header information object - * @throws IOException - * When there is an error without opening/reading from the file */ - public BinaryFTraceCPUPageIterator(@NonNull BinaryFTraceCPUDataPage page, @NonNull BinaryFTraceHeaderInfo fileHeader) throws IOException { + public BinaryFTraceCPUPageIterator(@NonNull BinaryFTraceCPUDataPage page, @NonNull BinaryFTraceHeaderInfo fileHeader) { // Initialize buffer data fFileHeader = fileHeader; this.fPage = page; @@ -103,11 +101,7 @@ public long getCurrentTimeStamp() { */ @Override public void close() throws IOException { - BinaryFTraceByteBuffer buffer = fBuffer; - if (buffer != null) { - buffer.close(); - fBuffer = null; - } + fBuffer = null; } /** @@ -152,10 +146,8 @@ public BinaryFTraceResponse readNextEvent() { /** * Read the time stamp of the next event only (without reading the actual * event) - * - * @throws IOException */ - private void readNextEventTimeStamp() throws IOException { + private void readNextEventTimeStamp() { boolean readSuccess = readNextEventHeader(); /** @@ -205,9 +197,8 @@ private void readNextEventTimeStamp() throws IOException { * increment the offset * * @return true if the event is read sucessfully - * @throws IOException */ - private boolean readNextEventHeader() throws IOException { + private boolean readNextEventHeader() { if (!hasNext()) { return false; } @@ -232,11 +223,8 @@ private boolean readNextEventHeader() throws IOException { * * @return -1 if the there is no next event, else return the event type * length. - * @throws IOException - * if there is an error reading the next event, likely because - * of buffer overflow caused a logical error during reading. */ - private int peekNextEventType() throws IOException { + private int peekNextEventType() { if (!hasNext()) { return -1; } @@ -254,13 +242,8 @@ private int peekNextEventType() throws IOException { /** * Update the time stamp based on the state of the current event header and * increment the offset if needed - * - * @throws IOException - * IOException if there is an error reading the next event, - * likely because of buffer overflow caused a logical error - * during reading. */ - private void updateTimeStamp() throws IOException { + private void updateTimeStamp() { if (fCurrentTypeLen <= fFileHeader.getHeaderEventInfo().getDataMaxTypeLen()) { fCurrentTimeStamp += fCurrentTimeDelta; } else { @@ -289,11 +272,8 @@ private void skip(int bytesToSkip) { * Get the pay load size of the event according to its type length * * @return The size of the payload of the event - * @throws IOException - * if there is an error reading the next event, likely because - * of buffer overflow caused a logical error during reading. */ - private int getCurrentEventPayloadSize() throws IOException { + private int getCurrentEventPayloadSize() { int payloadSize = 0; if (fCurrentTypeLen == fFileHeader.getHeaderEventInfo().getCustomLengthEventTypeLen()) { @@ -326,39 +306,34 @@ public BinaryFTraceCPUDataPage getPage() { * Lazily read the next event using the event definition information. * * @return A BinaryFTraceEvent at the current event definition. - * @throws IOException - * if there is an error reading the next event, likely because - * of buffer overflow caused a logical error during reading. */ - public @Nullable BinaryFTraceEvent getCurrentEvent() throws IOException { + public @Nullable BinaryFTraceEvent getCurrentEvent() { // Make a local copy to prevent multithreading null check BinaryFTraceEventDefinition eventDef = fEventDef; if (eventDef != null) { // We use a new buffer to read the current event - try (BinaryFTraceByteBuffer tempBuffer = new BinaryFTraceByteBuffer(fFileHeader.getFilePath());) { - tempBuffer.setByteOrder(fFileHeader.getEndianess()); - tempBuffer.movePointerToOffset(eventDef.getPayloadOffset()); - - byte[] data = tempBuffer.getNextBytes(eventDef.getPayloadSize()); - BinaryFTraceEventFormat eventFormat = fDataParser.getEventFormat(data); - if (eventFormat == null) { - return null; - } + BinaryFTraceByteBuffer tempBuffer = fFileHeader.getMappedBuffer(); + tempBuffer.movePointerToOffset(eventDef.getPayloadOffset()); - Map properties; - if (eventDef.getPayloadSize() > 0) { - properties = fDataParser.parseEventData(eventFormat, data); - } else { - properties = new HashMap<>(); - } + byte[] data = tempBuffer.getNextBytes(eventDef.getPayloadSize()); + BinaryFTraceEventFormat eventFormat = fDataParser.getEventFormat(data); + if (eventFormat == null) { + return null; + } - BinaryFTraceEvent event = new BinaryFTraceEvent(fCurrentTimeStamp, - properties, - eventFormat.getEventName(), - fPage.getCpu()); - return event; + Map properties; + if (eventDef.getPayloadSize() > 0) { + properties = fDataParser.parseEventData(eventFormat, data); + } else { + properties = new HashMap<>(); } + + BinaryFTraceEvent event = new BinaryFTraceEvent(fCurrentTimeStamp, + properties, + eventFormat.getEventName(), + fPage.getCpu()); + return event; } return null; @@ -370,11 +345,8 @@ public BinaryFTraceCPUDataPage getPage() { * @param timeStampToSeekTo * The timestamp to seek to * @return true if the seek was successful - * @throws IOException - * if there is an error reading the next event, likely because - * that the iterator has reached the end. */ - public boolean seek(long timeStampToSeekTo) throws IOException { + public boolean seek(long timeStampToSeekTo) { // Reset the iterator initializeIterator(); @@ -403,12 +375,8 @@ public boolean seek(long timeStampToSeekTo) throws IOException { * Check if there are more stuff to read in this iterator * * @return true if there are more events to read in this page - * - * @throws IOException - * if there is an error reading the next event, likely because - * that the iterator has reached the end. */ - public boolean hasNext() throws IOException { + public boolean hasNext() { boolean ret = true; BinaryFTraceByteBuffer buffer = fBuffer; @@ -454,7 +422,7 @@ public boolean hasNext() throws IOException { return ret; } - private void initializeIterator() throws IOException { + private void initializeIterator() { fCurrentOffset = fPage.getDataStartingOffset(); fCurrentTimeStamp = fPage.getTimeStamp(); fCurrentTypeLen = -1; @@ -466,8 +434,7 @@ private void initializeIterator() throws IOException { fBuffer.movePointerToOffset(fPage.getDataStartingOffset()); } else { // Prepare the buffer - BinaryFTraceByteBuffer newBuffer = new BinaryFTraceByteBuffer(fFileHeader.getFilePath()); - newBuffer.setByteOrder(fFileHeader.getEndianess()); + BinaryFTraceByteBuffer newBuffer = fFileHeader.getMappedBuffer(); newBuffer.movePointerToOffset(fPage.getDataStartingOffset()); fBuffer = newBuffer; diff --git a/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/binary/iterator/BinaryFTraceCPUSectionIterator.java b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/binary/iterator/BinaryFTraceCPUSectionIterator.java index c76680ea5..1efd791b6 100644 --- a/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/binary/iterator/BinaryFTraceCPUSectionIterator.java +++ b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/binary/iterator/BinaryFTraceCPUSectionIterator.java @@ -140,11 +140,8 @@ public void close() throws IOException { * Get the current event of this iterator lazily. * * @return The current event as a BinaryFTrace event. - * @throws IOException - * if there is an error reading the event, likely because of - * byte buffer failure. */ - public @Nullable BinaryFTraceEvent getCurrentEvent() throws IOException { + public @Nullable BinaryFTraceEvent getCurrentEvent() { BinaryFTraceCPUPageIterator iter = fCurrPageIterator; if (iter != null) { return iter.getCurrentEvent(); diff --git a/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/binary/iterator/BinaryFTraceIterator.java b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/binary/iterator/BinaryFTraceIterator.java index 3648074fd..224c1c771 100644 --- a/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/binary/iterator/BinaryFTraceIterator.java +++ b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/binary/iterator/BinaryFTraceIterator.java @@ -69,7 +69,7 @@ public class BinaryFTraceIterator extends BinaryFTraceReader implements ITmfCont * The {@link BinaryFTraceHeaderInfo} linked to the trace. It * should be provided by the corresponding 'ctfTmfTrace'. * @param ftrace - * The {@link BinaryFTraceDirectImp} to iterate over + * The {@link BinaryFTrace} to iterate over * @throws IOException * If the iterator couldn't not be instantiated, probably due to * a read error. @@ -95,12 +95,8 @@ public BinaryFTraceIterator(BinaryFTraceHeaderInfo headerInfo, @NonNull BinaryFT * * @return GenericFtraceEvent The current event that the iterator currently * points to; null if there are no more events in the trace. - * @throws IOException - * If reading the next event fails, most likely because of - * buffer overflow. */ - @SuppressWarnings("resource") - public synchronized GenericFtraceEvent getCurrentEvent() throws IOException { + public synchronized GenericFtraceEvent getCurrentEvent() { final BinaryFTraceCPUSectionIterator top = super.getPrio().peek(); if (top != null) { if (!fCurLocation.equals(fPreviousLocation)) { @@ -175,10 +171,8 @@ public void dispose() { * The LocationData representing the position to seek to * @return True if the seek was successful, false if there was an error * seeking. - * @throws IOException - * If an error occurred while seeking the event */ - public synchronized boolean seek(BinaryFTraceLocationInfo ctfLocationData) throws IOException { + public synchronized boolean seek(BinaryFTraceLocationInfo ctfLocationData) { if (ctfLocationData.equals(BinaryFTraceLocation.INVALID_LOCATION)) { fCurLocation = NULL_LOCATION; return false; @@ -238,7 +232,7 @@ public boolean seek(long timestamp) { return seekSuccess; } - private long positionIteratorByIndex(long timestamp, long indexToSeek) throws IOException { + private long positionIteratorByIndex(long timestamp, long indexToSeek) { boolean success = true; long currentIndex = 0; @@ -269,12 +263,12 @@ private long positionIteratorByIndex(long timestamp, long indexToSeek) throws IO } @Override - public boolean advance() throws IOException { + public boolean advance() { boolean readNextEventSuccess = readNextEvent(); return readNextEventSuccess && skipRawSystemEvents(); } - private boolean readNextEvent() throws IOException { + private boolean readNextEvent() { boolean hasMoreEvents = false; try { hasMoreEvents = super.advance(); @@ -297,7 +291,7 @@ private boolean readNextEvent() throws IOException { return hasMoreEvents; } - private boolean skipRawSystemEvents() throws IOException { + private boolean skipRawSystemEvents() { // Position the trace at the first non raw event GenericFtraceEvent event = getCurrentEvent(); @@ -310,7 +304,7 @@ private boolean skipRawSystemEvents() throws IOException { return ret; } - private boolean skipToFirstValidEvent() throws IOException { + private boolean skipToFirstValidEvent() { // This means we are initializing the trace boolean initTrace = false; if (fCurLocation == null) { @@ -373,11 +367,9 @@ private static String eventNameRewrite(@Nullable String name) { * * @return 0 if there is no more event to read; else return the current * timestamp location. - * @throws IOException - * if an error occurred while getting the event */ @SuppressWarnings("resource") - public synchronized long getCurrentTimestamp() throws IOException { + public synchronized long getCurrentTimestamp() { final BinaryFTraceCPUSectionIterator top = super.getPrio().peek(); if (top != null) { diff --git a/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/binary/iterator/BinaryFTraceIteratorHelper.java b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/binary/iterator/BinaryFTraceIteratorHelper.java index 23584b91e..027104e0f 100644 --- a/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/binary/iterator/BinaryFTraceIteratorHelper.java +++ b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/binary/iterator/BinaryFTraceIteratorHelper.java @@ -11,7 +11,6 @@ package org.eclipse.tracecompass.incubator.internal.ftrace.core.binary.iterator; -import java.io.IOException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.Arrays; @@ -102,10 +101,8 @@ public int getDeltaTime(int value) { * @param headerInfo * The trace header * @return The iterator to get events from this page - * @throws IOException - * if an error occurs while creating the page iterator */ - public static @Nullable BinaryFTraceCPUPageIterator getPageIterator(BinaryFTraceCPUDataPage page, BinaryFTraceHeaderInfo headerInfo) throws IOException { + public static @Nullable BinaryFTraceCPUPageIterator getPageIterator(BinaryFTraceCPUDataPage page, BinaryFTraceHeaderInfo headerInfo) { if (headerInfo != null && page != null) { return new BinaryFTraceCPUPageIterator(page, headerInfo); } diff --git a/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/binary/iterator/BinaryFTraceReader.java b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/binary/iterator/BinaryFTraceReader.java index 4aee42616..7b004a2b2 100644 --- a/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/binary/iterator/BinaryFTraceReader.java +++ b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/binary/iterator/BinaryFTraceReader.java @@ -304,10 +304,8 @@ public boolean seek(long timestamp) throws IOException { * Go to the next event. * * @return True if an event was read. - * @throws IOException - * if an error occurs */ - public boolean advance() throws IOException { + public boolean advance() { /* * Remove the reader from the top of the priority queue. */ diff --git a/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/binary/parser/AbstractBinaryFTraceFileParser.java b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/binary/parser/AbstractBinaryFTraceFileParser.java index f484bc00e..bf6ac62d6 100644 --- a/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/binary/parser/AbstractBinaryFTraceFileParser.java +++ b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/binary/parser/AbstractBinaryFTraceFileParser.java @@ -23,7 +23,6 @@ import static org.eclipse.tracecompass.incubator.internal.ftrace.core.binary.event.BinaryFTraceConstants.HEADER_EVENT_TYPE_LENGTH_VALUE_SEPARATOR; import static org.eclipse.tracecompass.incubator.internal.ftrace.core.binary.event.BinaryFTraceConstants.NEW_LINE; -import java.io.IOException; import java.nio.ByteOrder; import java.util.ArrayList; import java.util.HashMap; @@ -79,7 +78,7 @@ protected static BinaryFTraceVersionHeader getMagicValuesAndFtraceVersion(byte[] BinaryFTraceVersion ftraceVersionEnum = BinaryFTraceVersion.getVersionAsEnum(ftraceVersionInt); return new BinaryFTraceVersionHeader(magicValues, ftraceVersionEnum); } catch (NumberFormatException e) { - throw new TmfTraceException("Cannot parse the magic values and FTrace version. Make sure you use trace-cmd v.2.9 and above.", e); //$NON-NLS-1$ + throw new TmfTraceException("Cannot parse the magic values and FTrace version. Make sure you use trace-cmd v.2.9 and above. strVersion=" + strVersion, e); //$NON-NLS-1$ } } @@ -90,16 +89,13 @@ protected static BinaryFTraceVersionHeader getMagicValuesAndFtraceVersion(byte[] * The buffer that is currently pointing to the endianess value * of the trace file * @return The endianess of the file as a {@link ByteOrder} value - * @throws IOException - * If an error occur while reading the file */ - protected static ByteOrder getFileEndianess(BinaryFTraceByteBuffer buffer) throws IOException { + protected static ByteOrder getFileEndianess(BinaryFTraceByteBuffer buffer) { int endianess = buffer.getNextBytes(1)[0]; ByteOrder byteOrder = ByteOrder.BIG_ENDIAN; if (endianess == 0) { byteOrder = ByteOrder.LITTLE_ENDIAN; } - buffer.setByteOrder(byteOrder); return byteOrder; } @@ -113,15 +109,12 @@ protected static ByteOrder getFileEndianess(BinaryFTraceByteBuffer buffer) throw * @return The long value size of the trace file (either 4 or 8) * @throws TmfTraceException * If an error occur while validating the long value size - * @throws IOException - * If an error occur while reading the long value size from the - * trace */ - protected static int getLongValueSize(BinaryFTraceByteBuffer buffer) throws TmfTraceException, IOException { + protected static int getLongValueSize(BinaryFTraceByteBuffer buffer) throws TmfTraceException { int longValueSize = buffer.getNextBytes(1)[0]; if (longValueSize != 4 && longValueSize != 8) { - throw new TmfTraceException("Invalid size for long value, must be either 4 or 8 bytes"); //$NON-NLS-1$ + throw new TmfTraceException("Invalid size for long value, must be either 4 or 8 bytes, got " + longValueSize); //$NON-NLS-1$ } return longValueSize; @@ -134,10 +127,8 @@ protected static int getLongValueSize(BinaryFTraceByteBuffer buffer) throws TmfT * The buffer that is currently pointing to the host page size * value in the trace file * @return The host page size value of the trace file - * @throws IOException - * If an error occurred while reading the host page size value */ - protected static int getHostPageSize(BinaryFTraceByteBuffer buffer) throws IOException { + protected static int getHostPageSize(BinaryFTraceByteBuffer buffer) { return buffer.getNextInt(); } diff --git a/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/binary/parser/BinaryFTraceByteBuffer.java b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/binary/parser/BinaryFTraceByteBuffer.java index 6735be4e1..3ec9d5897 100644 --- a/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/binary/parser/BinaryFTraceByteBuffer.java +++ b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/binary/parser/BinaryFTraceByteBuffer.java @@ -11,88 +11,46 @@ package org.eclipse.tracecompass.incubator.internal.ftrace.core.binary.parser; -import java.io.FileNotFoundException; import java.io.IOException; -import java.io.RandomAccessFile; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.channels.FileChannel; import org.eclipse.tracecompass.incubator.internal.ftrace.core.binary.header.BinaryFTraceDataType; /** - * A reader for Ftrace files that utilizes ByteBuffer + * A reader for Ftrace files using a ByteBuffer obtained mem-mapping the .dat file. * * @author Hoang Thuan Pham */ -public class BinaryFTraceByteBuffer implements AutoCloseable { - private static final int BUFFER_SIZE = 4096; - - private final RandomAccessFile fTraceFile; - private FileChannel fFileChannel; - private ByteBuffer fByteBuffer; - private ByteOrder fByteOrder = ByteOrder.BIG_ENDIAN; - private long fCurrentOffset; - - /** - * Constructor - * - * @param path - * The path to the file - * @throws FileNotFoundException - * Exception thrown when a file is not found - */ - public BinaryFTraceByteBuffer(String path) throws FileNotFoundException { - fTraceFile = new RandomAccessFile(path, "r"); //$NON-NLS-1$ - fFileChannel = fTraceFile.getChannel(); - fByteBuffer = ByteBuffer.allocate(BUFFER_SIZE); - fCurrentOffset = 0; - } +public class BinaryFTraceByteBuffer { + private BinaryFTraceFileMapping fMappedBuffer; + private long fCurrentOffset = 0; /** - * Get the byte order of the byte buffer + * Create a buffer mapping of the given file. * - * @return The current byte order of the buffer + * @param filePath the file to map + * @throws IOException if the file can't be opened or mapped */ - public ByteOrder getByteOrder() { - return fByteOrder; + public BinaryFTraceByteBuffer(String filePath) throws IOException { + this(new BinaryFTraceFileMapping(filePath)); } /** - * Set the byte order of the byte buffer + * Create a (usually temporary) buffer that uses the given mapping. * - * @param byteOrder - * The new byte order for the buffer + * @param mappedBuffer the mem-mapped .dat file */ - public void setByteOrder(ByteOrder byteOrder) { - this.fByteOrder = byteOrder; + public BinaryFTraceByteBuffer(BinaryFTraceFileMapping mappedBuffer) { + fMappedBuffer = mappedBuffer; } /** - * Close the file - * - * @throws IOException - * Cannot close the file - */ - @Override - public void close() throws IOException { - fFileChannel.close(); - fTraceFile.close(); - } - - /** - * Read into the byte buffer + * Move the byte buffer pointer to a specific offset in the file * - * @return The number of bytes read into the buffer - * @throws IOException - * Cannot read data into the buffer + * @param offset + * The new offset of the file */ - public int read() throws IOException { - fByteBuffer.compact(); // Write mode - int numOfBytesRead = fFileChannel.read(fByteBuffer); - fByteBuffer.flip(); // Enable reading - - return numOfBytesRead; + public void movePointerToOffset(long offset) { + fCurrentOffset = offset; } /** @@ -101,23 +59,11 @@ public int read() throws IOException { * @param byteCount * The number of byte to read from the buffer * @return A byte array containing the data read from the buffer - * @throws IOException - * An error occur while reading data from the buffer */ - public byte[] getNextBytes(int byteCount) throws IOException { + public byte[] getNextBytes(int byteCount) { byte[] bytesArray = new byte[byteCount]; - - fByteBuffer.flip(); // To switch to read mode - - // Buffer will overflow - if (fByteBuffer.remaining() < byteCount) { - read(); // Get more data - } - - fByteBuffer.get(bytesArray); - fByteBuffer.compact(); // Compact the size of the buffer + fMappedBuffer.get(fCurrentOffset, bytesArray); fCurrentOffset += byteCount; - return bytesArray; } @@ -126,30 +72,18 @@ public byte[] getNextBytes(int byteCount) throws IOException { * encounter a null terminating character (\0) * * @return The string read from the file - * @throws IOException - * Cannot read data from the buffer */ - public String getNextString() throws IOException { + public String getNextString() { + long pos = fCurrentOffset; StringBuilder strBuilder = new StringBuilder(); - fByteBuffer.flip(); - - // Make sure that there are some value to be read - if (fByteBuffer.remaining() == 0) { - read(); // Get more data - } - int value = fByteBuffer.get(); + byte value = fMappedBuffer.getByte(pos++); while (value > 0) { strBuilder.append((char) value); - if (fByteBuffer.remaining() == 0) { // If we run out of data - read(); // Get more data - } - value = fByteBuffer.get(); + value = fMappedBuffer.getByte(pos++); } - fByteBuffer.compact(); // Compact the size of the buffer - String returnString = strBuilder.toString(); fCurrentOffset += (returnString.length() + BinaryFTraceHeaderElementSize.STRING_TERMINATOR); @@ -162,93 +96,56 @@ public String getNextString() throws IOException { * @param byteCount * Number of bytes to read * @return The string obtained by parsing n number of bytes - * @throws IOException - * Cannot read data from the buffer */ - public String getNextBytesAsString(long byteCount) throws IOException { - StringBuilder strBuilder = new StringBuilder(); - long remainingByte = byteCount; - String str; - - while (remainingByte >= BUFFER_SIZE) { - str = new String(getNextBytes(BUFFER_SIZE)); - strBuilder.append(str); - remainingByte = remainingByte - BUFFER_SIZE; + public String getNextBytesAsString(long byteCount) { + if (byteCount > Integer.MAX_VALUE) { + throw new IllegalArgumentException("FTrace Binary buffer: byteCount too large: " + byteCount); //$NON-NLS-1$ } - - str = new String(getNextBytes((int) remainingByte)); // we are sure that - // the value is - // less than 1024 - strBuilder.append(str); - - return strBuilder.toString(); + return new String(getNextBytes((int) byteCount)); } /** * Get the next integer in the buffer stream * * @return The next integer in the buffer - * @throws IOException - * Cannot read data from the buffer */ - public int getNextInt() throws IOException { - byte[] byteArray = getNextBytes(BinaryFTraceDataType.INT.getSize()); - - ByteBuffer wrapped = ByteBuffer.wrap(byteArray).order(fByteOrder); - return wrapped.getInt(); + public int getNextInt() { + int value = fMappedBuffer.getInt(fCurrentOffset); + fCurrentOffset += BinaryFTraceDataType.INT.getSize(); + return value; } /** * Get the next double in the buffer stream * * @return The next double in the buffer - * @throws IOException - * Cannot read data from the buffer */ - public double getNextDouble() throws IOException { - byte[] byteArray = getNextBytes(8); - ByteBuffer wrapped = ByteBuffer.wrap(byteArray).order(fByteOrder); - return wrapped.getDouble(); + public double getNextDouble() { + double value = fMappedBuffer.getDouble(fCurrentOffset); + fCurrentOffset += 8; + return value; } /** * Get the next long in the buffer stream * * @return The next long in the buffer stream - * @throws IOException - * Cannot read data from the buffer */ - public long getNextLong() throws IOException { - byte[] byteArray = getNextBytes(8); - ByteBuffer wrapped = ByteBuffer.wrap(byteArray).order(fByteOrder); - return wrapped.getLong(); + public long getNextLong() { + long value = fMappedBuffer.getLong(fCurrentOffset); + fCurrentOffset += 8; + return value; } /** * Get the next short in the buffer stream * * @return The next short in the buffer stream - * @throws IOException - * Cannot read data from the buffer */ - public short getNextShort() throws IOException { - byte[] byteArray = getNextBytes(2); - ByteBuffer wrapped = ByteBuffer.wrap(byteArray).order(fByteOrder); - return wrapped.getShort(); - } - - /** - * Move the byte buffer pointer to a specific offset in the file - * - * @param offset - * The new offset of the file - * @throws IOException - * Cannot move the pointer to the value of the offset parameter - */ - public void movePointerToOffset(long offset) throws IOException { - fByteBuffer.clear(); - fTraceFile.seek(offset); - fCurrentOffset = offset; + public short getNextShort() { + short value = fMappedBuffer.getShort(fCurrentOffset); + fCurrentOffset += 2; + return value; } /** @@ -264,10 +161,8 @@ public long getCurrentOffset() { * Get the size of the file that is currently being read * * @return The file size - * @throws IOException - * If an error occurred while reading the file size */ - public long getFileSize() throws IOException { - return fTraceFile.length(); + public long getFileSize() { + return fMappedBuffer.length(); } } diff --git a/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/binary/parser/BinaryFTraceFileMapping.java b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/binary/parser/BinaryFTraceFileMapping.java new file mode 100644 index 000000000..c5c5d1de8 --- /dev/null +++ b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/binary/parser/BinaryFTraceFileMapping.java @@ -0,0 +1,140 @@ +package org.eclipse.tracecompass.incubator.internal.ftrace.core.binary.parser; + +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.ByteOrder; +import java.nio.MappedByteBuffer; +import java.nio.channels.FileChannel; +import java.nio.channels.FileChannel.MapMode; +import java.util.ArrayList; + +/** + * Helper class to map a large file (> 2GB) using a list of MappedByteBuffers. + * + * Provides an interface (read only) similar to ByteBuffer, but uses a long + * index instead of int. + */ +public final class BinaryFTraceFileMapping { + /** + * Length of the file segment mapped by each buffer. + */ + public static final long SEGMENT_LEN = ((long) 1) << 31; + + /** + * Overlap of each segment into the next, to easily access data that + * sits at segment boundary. + */ + public static final long SEGMENT_OVERLAP = 1 << 20; // 1MB overlap + + private final long fLength; + private ArrayList fMappedBuffers = new ArrayList<>(); + + /** + * Create a mapping for the given file. + * + * @param filePath the file path + * @throws IOException if the file can't be opened or mapped + */ + public BinaryFTraceFileMapping(String filePath) throws IOException { + try (RandomAccessFile file = new RandomAccessFile(filePath, "r")) { //$NON-NLS-1$ + @SuppressWarnings("resource") + FileChannel channel = file.getChannel(); // channel is closed automatically by the file + fLength = file.length(); + final int segmentCount = (int)(fLength / SEGMENT_LEN); + fMappedBuffers.ensureCapacity(segmentCount + 1); + for (int i = 0; i < segmentCount; i++) { + fMappedBuffers.add(channel.map(MapMode.READ_ONLY, i * SEGMENT_LEN, SEGMENT_LEN + SEGMENT_OVERLAP)); + } + long remaining = fLength - segmentCount * SEGMENT_LEN; + if (remaining > 0) { + fMappedBuffers.add(channel.map(MapMode.READ_ONLY, segmentCount * SEGMENT_LEN, remaining)); + } + } + } + + /** + * Set the byte order for the read operations. + * + * @param endianess the byte order to set + */ + public void order(ByteOrder endianess) { + for (MappedByteBuffer buffer : fMappedBuffers) { + buffer.order(endianess); + } + } + + /** + * Fill the given array with bytes from the file at the given position. + * + * @param index position to read from + * @param dst the byte array to fill + */ + public void get(long index, byte[] dst) { + MappedByteBuffer mappedBuffer = fMappedBuffers.get((int) (index / SEGMENT_LEN)); + mappedBuffer.get((int)(index % SEGMENT_LEN), dst); + } + + /** + * Read a single byte from the given position. + * + * @param index position to read from + * @return the value + */ + public byte getByte(long index) { + MappedByteBuffer mappedBuffer = fMappedBuffers.get((int) (index / SEGMENT_LEN)); + return mappedBuffer.get((int)(index % SEGMENT_LEN)); + } + + /** + * Read an int (4 bytes) from the given position. + * + * @param index position to read from + * @return the value + */ + public int getInt(long index) { + MappedByteBuffer mappedBuffer = fMappedBuffers.get((int) (index / SEGMENT_LEN)); + return mappedBuffer.getInt((int)(index % SEGMENT_LEN)); + } + + /** + * Read a double (8 bytes) from the given position. + * + * @param index position to read from + * @return the value + */ + public double getDouble(long index) { + MappedByteBuffer mappedBuffer = fMappedBuffers.get((int) (index / SEGMENT_LEN)); + return mappedBuffer.getDouble((int)(index % SEGMENT_LEN)); + } + + /** + * Read a long (8 bytes) from the given position. + * + * @param index position to read from + * @return the value + */ + public long getLong(long index) { + MappedByteBuffer mappedBuffer = fMappedBuffers.get((int) (index / SEGMENT_LEN)); + return mappedBuffer.getLong((int)(index % SEGMENT_LEN)); + } + + /** + * Read a short (2 bytes) from the given position. + * + * @param index position to read from + * @return the value + */ + public short getShort(long index) { + MappedByteBuffer mappedBuffer = fMappedBuffers.get((int) (index / SEGMENT_LEN)); + return mappedBuffer.getShort((int)(index % SEGMENT_LEN)); + } + + /** + * Get the mapped length (the file size). + * + * @return the mapped length (the file size) + */ + public long length() { + return fLength; + } +} \ No newline at end of file diff --git a/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/binary/parser/BinaryFTraceFileParser.java b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/binary/parser/BinaryFTraceFileParser.java index 09ae9d222..c82b748da 100644 --- a/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/binary/parser/BinaryFTraceFileParser.java +++ b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/binary/parser/BinaryFTraceFileParser.java @@ -49,7 +49,7 @@ private BinaryFTraceFileParser() { // Do nothing } - private static void validate(BinaryFTraceByteBuffer buffer, long bytesToRead) throws TmfTraceException, IOException { + private static void validate(BinaryFTraceByteBuffer buffer, long bytesToRead) throws TmfTraceException { /* * Validate if read reading bytesToRead amount of bytes will go over the * file size limit. There is no need to wrap IOException to @@ -81,7 +81,8 @@ private static void validate(BinaryFTraceByteBuffer buffer, long bytesToRead) th * Cannot open or parse the file */ public static BinaryFTraceVersionHeader getFtraceVersionHeader(String path) throws TmfTraceException { - try (BinaryFTraceByteBuffer buffer = new BinaryFTraceByteBuffer(path)) { + try { + BinaryFTraceByteBuffer buffer = new BinaryFTraceByteBuffer(path); return getFtraceVersionHeader(buffer); } catch (IOException e) { throw new TmfTraceException("Cannot open trace file", e); //$NON-NLS-1$ @@ -89,15 +90,11 @@ public static BinaryFTraceVersionHeader getFtraceVersionHeader(String path) thro } private static BinaryFTraceVersionHeader getFtraceVersionHeader(BinaryFTraceByteBuffer buffer) throws TmfTraceException { - try { - validate(buffer, BinaryFTraceHeaderElementSize.getMagicValueSectionSize()); + validate(buffer, BinaryFTraceHeaderElementSize.getMagicValueSectionSize()); - byte[] bytes = buffer.getNextBytes(10); - String strVersion = buffer.getNextString().trim(); - return getMagicValuesAndFtraceVersion(bytes, strVersion); - } catch (IOException e) { - throw new TmfTraceException("FTrace Version Header not readible", e); //$NON-NLS-1$ - } + byte[] bytes = buffer.getNextBytes(10); + String strVersion = buffer.getNextString().trim(); + return getMagicValuesAndFtraceVersion(bytes, strVersion); } /** @@ -111,20 +108,23 @@ private static BinaryFTraceVersionHeader getFtraceVersionHeader(BinaryFTraceByte * Cannot open or parse the file */ public static BinaryFTraceHeaderInfo parse(String path) throws TmfTraceException { - try (BinaryFTraceByteBuffer buffer = new BinaryFTraceByteBuffer(path)) { - + try { BinaryFTraceHeaderInfoBuilder builder = new BinaryFTraceHeaderInfoBuilder(); builder.filePath(path); + BinaryFTraceFileMapping traceMapping = new BinaryFTraceFileMapping(path); + BinaryFTraceByteBuffer buffer = new BinaryFTraceByteBuffer(traceMapping); + // Parse initial data section BinaryFTraceVersionHeader versionHeader = getFtraceVersionHeader(buffer); builder.version(versionHeader.getFTraceVersion()); ByteOrder endianess = getFileEndianess(buffer); builder.endianess(endianess); - buffer.setByteOrder(endianess); - // Now all numbers are in file endianess + // File content from now on has the specified endianess + traceMapping.order(endianess); + builder.longValueSize(getLongValueSize(buffer)); int pageSize = getHostPageSize(buffer); @@ -156,13 +156,13 @@ public static BinaryFTraceHeaderInfo parse(String path) throws TmfTraceException builder.fileType(BinaryFTraceFileType.FLY_RECORD); builder.cpus(parseFlyRecordSection(buffer, cpuCount, pageSize)); } - return builder.build(); + return builder.build(traceMapping); } catch (IOException ex) { throw new TmfTraceException(ex.getMessage(), ex); } } - private static List parseHeaderPage(BinaryFTraceByteBuffer buffer) throws IOException, TmfTraceException { + private static List parseHeaderPage(BinaryFTraceByteBuffer buffer) throws TmfTraceException { validate(buffer, BinaryFTraceHeaderElementSize.getHeaderPageSectionHeaderSize()); buffer.getNextBytesAsString(12); // Skipping the section name long headerPageSize = buffer.getNextLong(); @@ -172,7 +172,7 @@ private static List parseHeaderPage(BinaryFTraceByteBuf return extractHeaderPageContent(headerPageContent); } - private static BinaryFTraceHeaderEvent parseHeaderEvent(BinaryFTraceByteBuffer buffer) throws IOException, TmfTraceException { + private static BinaryFTraceHeaderEvent parseHeaderEvent(BinaryFTraceByteBuffer buffer) throws TmfTraceException { validate(buffer, BinaryFTraceHeaderElementSize.getHeaderEventSectionHeaderSize()); buffer.getNextBytesAsString(13); // Skipping the section header long headerEventSize = buffer.getNextLong(); @@ -182,7 +182,7 @@ private static BinaryFTraceHeaderEvent parseHeaderEvent(BinaryFTraceByteBuffer b return extractHeaderEventContent(strHeaderEventInfo); } - private static Map parseTraceEventsFormat(BinaryFTraceByteBuffer buffer) throws IOException, TmfTraceException { + private static Map parseTraceEventsFormat(BinaryFTraceByteBuffer buffer) throws TmfTraceException { ArrayList eventFormats = new ArrayList<>(); validate(buffer, BinaryFTraceHeaderElementSize.EVENT_COUNT); @@ -199,7 +199,7 @@ private static Map parseTraceEventsFormat(Bina return extractTraceEventsFormat(eventFormats); } - private static List parseEventSystemsAndFormats(BinaryFTraceByteBuffer buffer) throws IOException, TmfTraceException { + private static List parseEventSystemsAndFormats(BinaryFTraceByteBuffer buffer) throws TmfTraceException { HashMap> eventSystemData = new HashMap<>(); validate(buffer, BinaryFTraceHeaderElementSize.EVENT_SYSTEM_COUNT); @@ -226,7 +226,7 @@ private static List parseEventSystemsAndFormats(BinaryF return extractEventSystemsAndFormats(eventSystemData); } - private static Map parseFunctionMapping(BinaryFTraceByteBuffer buffer) throws IOException, TmfTraceException { + private static Map parseFunctionMapping(BinaryFTraceByteBuffer buffer) throws TmfTraceException { validate(buffer, BinaryFTraceHeaderElementSize.SMALL_SECTION_SIZE); int dataSize = buffer.getNextInt(); @@ -235,7 +235,7 @@ private static Map parseFunction return extractFunctionMappingContent(strMappings); } - private static Map parseTracePrintKInfo(BinaryFTraceByteBuffer buffer) throws IOException, TmfTraceException { + private static Map parseTracePrintKInfo(BinaryFTraceByteBuffer buffer) throws TmfTraceException { validate(buffer, BinaryFTraceHeaderElementSize.SMALL_SECTION_SIZE); int dataSize = buffer.getNextInt(); @@ -244,7 +244,7 @@ private static Map parseTracePrintKInfo(BinaryFTraceByteBuffer b return extractPrintKContent(strMappings); } - private static Map parseProcessToFunctionNameMapping(BinaryFTraceByteBuffer buffer) throws IOException, TmfTraceException { + private static Map parseProcessToFunctionNameMapping(BinaryFTraceByteBuffer buffer) throws TmfTraceException { validate(buffer, BinaryFTraceHeaderElementSize.LARGE_SECTION_SIZE); long dataSize = buffer.getNextLong(); @@ -253,7 +253,7 @@ private static Map parseProcessToFunctionNameMapping(BinaryFTra return extractFunctionNameMapping(strMappings); } - private static List parseFlyRecordSection(BinaryFTraceByteBuffer buffer, int cpuCount, int pageSize) throws IOException, TmfTraceException { + private static List parseFlyRecordSection(BinaryFTraceByteBuffer buffer, int cpuCount, int pageSize) throws TmfTraceException { // Validate that the size of the CPU information section is valid validate(buffer, (long) cpuCount * (BinaryFTraceHeaderElementSize.CPU_SECTION_OFFSET + BinaryFTraceHeaderElementSize.CPU_SECTION_SIZE)); @@ -281,7 +281,7 @@ private static List parseFlyRecordSection(BinaryFTraceByteB return parseCPUPageHeader(buffer, cpuSectionStartingOffset, cpuSectionSize, pageSize); } - private static List parseCPUPageHeader(BinaryFTraceByteBuffer buffer, long[] cpuSectionStartingOffset, long[] cpuSectionSize, int pageSize) throws IOException, TmfTraceException { + private static List parseCPUPageHeader(BinaryFTraceByteBuffer buffer, long[] cpuSectionStartingOffset, long[] cpuSectionSize, int pageSize) throws TmfTraceException { Map> mapTimeStamp = new HashMap<>(); Map> mapFlag = new HashMap<>(); Map> mapStartingOffset = new HashMap<>(); @@ -317,7 +317,7 @@ private static List parseCPUPageHeader(BinaryFTraceByteBuff return initializeCPUs(mapTimeStamp, mapFlag, cpuSectionStartingOffset, cpuSectionSize, pageSize); } - private static List parseOptionsSection(BinaryFTraceByteBuffer buffer) throws IOException, TmfTraceException { + private static List parseOptionsSection(BinaryFTraceByteBuffer buffer) throws TmfTraceException { ArrayList optionTypes = new ArrayList<>(); ArrayList optionData = new ArrayList<>(); @@ -340,7 +340,7 @@ private static List parseOptionsSection(BinaryFTraceByteBuff return extractOptionsSection(optionTypes, optionData); } - private static int parseCPUCount(BinaryFTraceByteBuffer buffer) throws IOException, TmfTraceException { + private static int parseCPUCount(BinaryFTraceByteBuffer buffer) throws TmfTraceException { validate(buffer, BinaryFTraceHeaderElementSize.SMALL_SECTION_SIZE); return buffer.getNextInt(); } diff --git a/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/strategies/BinaryFTraceV6Strategy.java b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/strategies/BinaryFTraceV6Strategy.java index aefdd0d78..848569791 100644 --- a/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/strategies/BinaryFTraceV6Strategy.java +++ b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/strategies/BinaryFTraceV6Strategy.java @@ -141,4 +141,11 @@ public ITmfContext seekEvent(ITmfLocation location) { public ITmfContext createIterator() throws IOException { return new BinaryFTraceIterator(fTraceHeaderData, fFTrace); } + + @Override + public void dispose() { + // release (indirect) references to mem-mapped file buffers so that tracecompass + // can garbage-collect them and unlock the file (e.g. if the user wants to delete it) + fTraceHeaderData = null; + } } diff --git a/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/strategies/IBinaryFTraceStrategy.java b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/strategies/IBinaryFTraceStrategy.java index 73ffa9a6a..f293e4295 100644 --- a/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/strategies/IBinaryFTraceStrategy.java +++ b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/strategies/IBinaryFTraceStrategy.java @@ -68,4 +68,11 @@ public interface IBinaryFTraceStrategy { * provided by the parameter. */ public ITmfContext seekEvent(ITmfLocation location); + + /** + * Dispose of the strategy. + * + * Can be used to release system resources. + */ + public void dispose(); } diff --git a/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/trace/BinaryFTrace.java b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/trace/BinaryFTrace.java index de92cedbe..39e00aa30 100644 --- a/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/trace/BinaryFTrace.java +++ b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/trace/BinaryFTrace.java @@ -115,6 +115,14 @@ public void initTrace(IResource resource, String path, Class