ss: Replace AttributeNotFoundException with IOOBE for quark parameters
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.core / src / org / eclipse / tracecompass / tmf / core / callstack / CallStackStateProvider.java
index 1eed618d9290ee701409c459085282878ed38368..7159df876d35167379da355ece44bc32ba447bfe 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2013, 2015 Ericsson
+ * Copyright (c) 2013, 2016 Ericsson
  *
  * All rights reserved. This program and the accompanying materials are
  * made available under the terms of the Eclipse Public License v1.0 which
@@ -19,7 +19,6 @@ import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.osgi.util.NLS;
 import org.eclipse.tracecompass.internal.tmf.core.Activator;
 import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder;
-import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
 import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
 import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
 import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
@@ -60,11 +59,12 @@ import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
  *
  * where:
  * <ul>
- * <li>(PID n) is an attribute name representing a unique process identifier.
- * </li>
+ * <li>(PID n) is an attribute whose name is the display name of the process.
+ * Optionally, its value can be an int representing the process id. Otherwise,
+ * the attribute name can be set to the process id formatted as a string.</li>
  * <li>(TID n) is an attribute whose name is the display name of the thread.
- * Optionally, its value is a long representing the thread id, used for sorting.
- * </li>
+ * Optionally, its value can be a long representing the thread id. Otherwise,
+ * the attribute name can be set to the thread id formatted as a string.</li>
  * <li>"CallStack" is a stack-attribute whose pushed values are either a string,
  * int or long representing the function name or address in the call stack. The
  * type of value used must be constant for a particular CallStack.</li>
@@ -75,26 +75,33 @@ import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
 @NonNullByDefault
 public abstract class CallStackStateProvider extends AbstractTmfStateProvider {
 
-    /** Thread attribute
-     * @since 2.0 */
+    /**
+     * Thread attribute
+     *
+     * @since 2.0
+     */
     public static final String PROCESSES = "Processes"; //$NON-NLS-1$
 
     /** CallStack stack-attribute */
     public static final String CALL_STACK = "CallStack"; //$NON-NLS-1$
 
-    /** Undefined process ID
-     * @since 2.0 */
-    protected static final int UNDEFINED_PID = -1;
+    /**
+     * Unknown process ID
+     *
+     * @since 2.0
+     */
+    public static final int UNKNOWN_PID = -1;
 
-    /** Undefined function exit name */
-    protected static final String UNDEFINED = "UNDEFINED"; //$NON-NLS-1$
+    /**
+     * Unknown name
+     *
+     * @since 2.0
+     */
+    public static final String UNKNOWN = "UNKNOWN"; //$NON-NLS-1$
 
     /** CallStack state system ID */
     private static final String ID = "org.eclipse.linuxtools.tmf.callstack"; //$NON-NLS-1$
 
-    /** Dummy function name for when no function is expected */
-    private static final String NO_FUNCTION = "no function"; //$NON-NLS-1$
-
     /**
      * Default constructor
      *
@@ -113,49 +120,58 @@ public abstract class CallStackStateProvider extends AbstractTmfStateProvider {
 
         ITmfStateSystemBuilder ss = checkNotNull(getStateSystemBuilder());
 
-        try {
-            /* Check if the event is a function entry */
-            String functionEntryName = functionEntry(event);
-            if (functionEntryName != null) {
-                long timestamp = event.getTimestamp().toNanos();
-                int pid = getProcessId(event);
-                String threadName = getThreadName(event);
-                int threadQuark = ss.getQuarkAbsoluteAndAdd(PROCESSES, Integer.toString(pid), threadName);
-
-                long threadId = getThreadId(event);
-                ss.updateOngoingState(TmfStateValue.newValueLong(threadId), threadQuark);
-
-                int callStackQuark = ss.getQuarkRelativeAndAdd(threadQuark, CALL_STACK);
-                ITmfStateValue value = TmfStateValue.newValueString(functionEntryName);
-                ss.pushAttribute(timestamp, value, callStackQuark);
-                return;
+        /* Check if the event is a function entry */
+        ITmfStateValue functionEntryName = functionEntry(event);
+        if (functionEntryName != null) {
+            long timestamp = event.getTimestamp().toNanos();
+
+            String processName = getProcessName(event);
+            int processId = getProcessId(event);
+            if (processName == null) {
+                processName = (processId == UNKNOWN_PID) ? UNKNOWN : Integer.toString(processId);
             }
+            int processQuark = ss.getQuarkAbsoluteAndAdd(PROCESSES, processName);
+            ss.updateOngoingState(TmfStateValue.newValueInt(processId), processQuark);
 
-            /* Check if the event is a function exit */
-            String functionExitName = functionExit(event);
-            if (functionExitName != null) {
-                long timestamp = event.getTimestamp().toNanos();
-                int pid = getProcessId(event);
-                String thread = getThreadName(event);
-                int quark = ss.getQuarkAbsoluteAndAdd(PROCESSES, Integer.toString(pid), thread, CALL_STACK);
-                ITmfStateValue poppedValue = ss.popAttribute(timestamp, quark);
-                String poppedName = (poppedValue == null ? NO_FUNCTION : poppedValue.unboxStr());
-
-                /*
-                 * Verify that the value we are popping matches the one in the
-                 * event field, unless the latter is undefined.
-                 */
-                if (!functionExitName.equals(UNDEFINED) &&
-                        !functionExitName.equals(poppedName)) {
-                    Activator.logWarning(NLS.bind(
-                            Messages.CallStackStateProvider_UnmatchedPoppedValue,
-                            functionExitName,
-                            poppedName));
-                }
+            String threadName = getThreadName(event);
+            long threadId = getThreadId(event);
+            if (threadName == null) {
+                threadName = Long.toString(threadId);
             }
+            int threadQuark = ss.getQuarkRelativeAndAdd(processQuark, threadName);
+            ss.updateOngoingState(TmfStateValue.newValueLong(threadId), threadQuark);
+
+            int callStackQuark = ss.getQuarkRelativeAndAdd(threadQuark, CALL_STACK);
+            ITmfStateValue value = functionEntryName;
+            ss.pushAttribute(timestamp, value, callStackQuark);
+            return;
+        }
 
-        } catch (AttributeNotFoundException e) {
-            e.printStackTrace();
+        /* Check if the event is a function exit */
+        ITmfStateValue functionExitState = functionExit(event);
+        if (functionExitState != null) {
+            long timestamp = event.getTimestamp().toNanos();
+            String processName = getProcessName(event);
+            if (processName == null) {
+                int processId = getProcessId(event);
+                processName = (processId == UNKNOWN_PID) ? UNKNOWN : Integer.toString(processId);
+            }
+            String threadName = getThreadName(event);
+            if (threadName == null) {
+                threadName = Long.toString(getThreadId(event));
+            }
+            int quark = ss.getQuarkAbsoluteAndAdd(PROCESSES, processName, threadName, CALL_STACK);
+            ITmfStateValue poppedValue = ss.popAttribute(timestamp, quark);
+            /*
+             * Verify that the value we are popping matches the one in the
+             * event field, unless the latter is undefined.
+             */
+            if (!functionExitState.isNull() && !functionExitState.equals(poppedValue)) {
+                Activator.logWarning(NLS.bind(
+                        Messages.CallStackStateProvider_UnmatchedPoppedValue,
+                        functionExitState,
+                        poppedValue));
+            }
         }
     }
 
@@ -185,25 +201,28 @@ public abstract class CallStackStateProvider extends AbstractTmfStateProvider {
      *
      * @param event
      *            An event to check for function entry
-     * @return The function name of the function entry, or null if not a
-     *         function entry.
+     * @return The state value representing the function being entered, or null
+     *         if not a function entry
+     * @since 2.0
      */
-    protected abstract @Nullable String functionEntry(ITmfEvent event);
+    protected abstract @Nullable ITmfStateValue functionEntry(ITmfEvent event);
 
     /**
      * Check an event if it indicates a function exit.
      *
      * @param event
      *            An event to check for function exit
-     * @return The function name, or UNDEFINED, for a function exit, or null if
-     *         not a function exit.
+     * @return The state value representing the function being exited, or
+     *         TmfStateValue#nullValue() if the exited function is undefined,
+     *         or null if not a function exit.
+     * @since 2.0
      */
-    protected abstract @Nullable String functionExit(ITmfEvent event);
+    protected abstract @Nullable ITmfStateValue functionExit(ITmfEvent event);
 
     /**
      * Return the process ID of a function entry event.
-     *
-     * Use {@link #UNDEFINED_PID} if it is not known.
+     * <p>
+     * Use {@link #UNKNOWN_PID} if it is not known.
      *
      * @param event
      *            The event
@@ -212,6 +231,20 @@ public abstract class CallStackStateProvider extends AbstractTmfStateProvider {
      */
     protected abstract int getProcessId(ITmfEvent event);
 
+    /**
+     * Return the process name of a function entry event.
+     *
+     * @param event
+     *            The event
+     * @return The process name (as will be shown in the view) or null to use
+     *         the process ID formatted as a string (or {@link #UNKNOWN})
+     * @since 2.0
+     */
+    protected @Nullable String getProcessName(ITmfEvent event) {
+        /* Override to provide a process name */
+        return null;
+    }
+
     /**
      * Return the thread id of a function entry event.
      *
@@ -227,7 +260,11 @@ public abstract class CallStackStateProvider extends AbstractTmfStateProvider {
      *
      * @param event
      *            The event
-     * @return The thread name (as will be shown in the view)
+     * @return The thread name (as will be shown in the view) or null to use the
+     *         thread id formatted as a string
      */
-    protected abstract String getThreadName(ITmfEvent event);
+    protected @Nullable String getThreadName(ITmfEvent event) {
+        /* Override to provide a thread name */
+        return null;
+    }
 }
This page took 0.028319 seconds and 5 git commands to generate.