From 5d10d135ad7448e4e2f5cdf3c0212b99a7fd86ed Mon Sep 17 00:00:00 2001 From: Alvaro Sanchez-Leon Date: Mon, 31 May 2010 19:20:20 +0000 Subject: [PATCH 1/1] --- org.eclipse.linuxtools.lttng/.classpath | 7 + org.eclipse.linuxtools.lttng/.project | 28 + .../META-INF/MANIFEST.MF | 27 + org.eclipse.linuxtools.lttng/build.properties | 5 + .../plugin.properties | 3 + .../linuxtools/lttng/LTTngCorePlugin.java | 83 + .../linuxtools/lttng/LttngException.java | 14 + .../linuxtools/lttng/LttngFactory.java | 34 + .../eclipse/linuxtools/lttng/TraceDebug.java | 151 ++ .../control/LttngCoreProviderFactory.java | 33 + .../control/LttngSyntheticEventProvider.java | 442 +++++ .../linuxtools/lttng/event/LttngEvent.java | 182 ++ .../lttng/event/LttngEventContent.java | 264 +++ .../lttng/event/LttngEventField.java | 63 + .../lttng/event/LttngEventReference.java | 88 + .../lttng/event/LttngEventSource.java | 65 + .../lttng/event/LttngEventType.java | 87 + .../linuxtools/lttng/event/LttngLocation.java | 138 ++ .../lttng/event/LttngSyntheticEvent.java | 295 ++++ .../lttng/event/LttngTimestamp.java | 161 ++ .../lttng/model/ILTTngTreeNode.java | 119 ++ .../linuxtools/lttng/model/LTTngTreeNode.java | 67 + .../lttng/model/LTTngTreeNodeGeneric.java | 351 ++++ .../lttng/request/ILttngSyntEventRequest.java | 96 + .../lttng/request/IRequestStatusListener.java | 39 + .../lttng/request/LttngBaseEventRequest.java | 129 ++ .../lttng/request/LttngSyntEventRequest.java | 194 +++ .../lttng/request/RequestCompletedSignal.java | 18 + .../lttng/request/RequestEventDispatcher.java | 95 + .../request/RequestEventDispatcherToFact.java | 150 ++ .../lttng/request/RequestStartedSignal.java | 18 + .../ILttExperimentSelectedListener.java | 39 + .../lttng/signal/StateExperimentListener.java | 44 + .../lttng/state/LttngStateException.java | 85 + .../lttng/state/StateDataRequest.java | 220 +++ .../linuxtools/lttng/state/StateStrings.java | 653 +++++++ .../AbsEventToHandlerResolver.java | 217 +++ .../evProcessor/EventProcessorProxy.java | 95 + .../evProcessor/IBaseEventProcessor.java | 27 + .../evProcessor/IEventToHandlerResolver.java | 34 + .../evProcessor/ILttngEventProcessor.java | 36 + .../evProcessor/ITransEventProcessor.java | 37 + .../evProcessor/state/AbsStateProcessing.java | 209 +++ .../evProcessor/state/AbsStateUpdate.java | 250 +++ .../state/StateEventToHandlerFactory.java | 184 ++ .../state/StateUpdateHandlers.java | 1543 +++++++++++++++++ .../experiment/IStateExperimentManager.java | 86 + .../experiment/StateExperimentManager.java | 257 +++ .../state/experiment/StateManagerFactory.java | 160 ++ .../lttng/state/model/LTTngCPUState.java | 178 ++ .../lttng/state/model/LttngBdevState.java | 89 + .../state/model/LttngExecutionState.java | 152 ++ .../lttng/state/model/LttngIRQState.java | 85 + .../lttng/state/model/LttngProcessState.java | 490 ++++++ .../lttng/state/model/LttngSoftIRQState.java | 114 ++ .../lttng/state/model/LttngTraceState.java | 566 ++++++ .../lttng/state/model/LttngTrapState.java | 86 + .../lttng/state/model/StateModelFactory.java | 60 + .../state/resource/ILTTngStateResource.java | 102 ++ .../state/resource/ILttngStateContext.java | 71 + .../state/resource/LTTngStateResource.java | 94 + .../lttng/state/trace/IStateTraceManager.java | 64 + .../lttng/state/trace/StateTraceManager.java | 637 +++++++ .../lttng/trace/LTTngTextTrace.java | 518 ++++++ .../linuxtools/lttng/trace/LTTngTrace.java | 909 ++++++++++ .../lttng/trace/LTTngTraceVersion.java | 156 ++ 66 files changed, 11993 insertions(+) create mode 100644 org.eclipse.linuxtools.lttng/.classpath create mode 100644 org.eclipse.linuxtools.lttng/.project create mode 100644 org.eclipse.linuxtools.lttng/META-INF/MANIFEST.MF create mode 100644 org.eclipse.linuxtools.lttng/build.properties create mode 100644 org.eclipse.linuxtools.lttng/plugin.properties create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/LTTngCorePlugin.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/LttngException.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/LttngFactory.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/TraceDebug.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/control/LttngCoreProviderFactory.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/control/LttngSyntheticEventProvider.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/event/LttngEvent.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/event/LttngEventContent.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/event/LttngEventField.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/event/LttngEventReference.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/event/LttngEventSource.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/event/LttngEventType.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/event/LttngLocation.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/event/LttngSyntheticEvent.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/event/LttngTimestamp.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/model/ILTTngTreeNode.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/model/LTTngTreeNode.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/model/LTTngTreeNodeGeneric.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/request/ILttngSyntEventRequest.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/request/IRequestStatusListener.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/request/LttngBaseEventRequest.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/request/LttngSyntEventRequest.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/request/RequestCompletedSignal.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/request/RequestEventDispatcher.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/request/RequestEventDispatcherToFact.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/request/RequestStartedSignal.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/signal/ILttExperimentSelectedListener.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/signal/StateExperimentListener.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/LttngStateException.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/StateDataRequest.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/StateStrings.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/AbsEventToHandlerResolver.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/EventProcessorProxy.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/IBaseEventProcessor.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/IEventToHandlerResolver.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/ILttngEventProcessor.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/ITransEventProcessor.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/state/AbsStateProcessing.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/state/AbsStateUpdate.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/state/StateEventToHandlerFactory.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/state/StateUpdateHandlers.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/experiment/IStateExperimentManager.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/experiment/StateExperimentManager.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/experiment/StateManagerFactory.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/model/LTTngCPUState.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/model/LttngBdevState.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/model/LttngExecutionState.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/model/LttngIRQState.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/model/LttngProcessState.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/model/LttngSoftIRQState.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/model/LttngTraceState.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/model/LttngTrapState.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/model/StateModelFactory.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/resource/ILTTngStateResource.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/resource/ILttngStateContext.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/resource/LTTngStateResource.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/trace/IStateTraceManager.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/trace/StateTraceManager.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/trace/LTTngTextTrace.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/trace/LTTngTrace.java create mode 100644 org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/trace/LTTngTraceVersion.java diff --git a/org.eclipse.linuxtools.lttng/.classpath b/org.eclipse.linuxtools.lttng/.classpath new file mode 100644 index 0000000000..64c5e31b7a --- /dev/null +++ b/org.eclipse.linuxtools.lttng/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/org.eclipse.linuxtools.lttng/.project b/org.eclipse.linuxtools.lttng/.project new file mode 100644 index 0000000000..bb740cc9fb --- /dev/null +++ b/org.eclipse.linuxtools.lttng/.project @@ -0,0 +1,28 @@ + + + org.eclipse.linuxtools.lttng + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/org.eclipse.linuxtools.lttng/META-INF/MANIFEST.MF b/org.eclipse.linuxtools.lttng/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..326bd6e351 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/META-INF/MANIFEST.MF @@ -0,0 +1,27 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %Bundle-Name +Bundle-SymbolicName: org.eclipse.linuxtools.lttng +Bundle-Version: 0.2.0.qualifier +Bundle-Activator: org.eclipse.linuxtools.lttng.LTTngCorePlugin +Bundle-Vendor: %Bundle-Vendor +Require-Bundle: org.eclipse.core.runtime, + org.eclipse.linuxtools.tmf;bundle-version="0.2.0", + org.eclipse.linuxtools.lttng.jni;bundle-version="0.2.0" +Bundle-RequiredExecutionEnvironment: J2SE-1.5 +Bundle-ActivationPolicy: lazy +Export-Package: org.eclipse.linuxtools.lttng, + org.eclipse.linuxtools.lttng.control, + org.eclipse.linuxtools.lttng.event, + org.eclipse.linuxtools.lttng.model, + org.eclipse.linuxtools.lttng.request, + org.eclipse.linuxtools.lttng.signal, + org.eclipse.linuxtools.lttng.state, + org.eclipse.linuxtools.lttng.state.evProcessor, + org.eclipse.linuxtools.lttng.state.evProcessor.state, + org.eclipse.linuxtools.lttng.state.experiment, + org.eclipse.linuxtools.lttng.state.model, + org.eclipse.linuxtools.lttng.state.resource, + org.eclipse.linuxtools.lttng.state.trace, + org.eclipse.linuxtools.lttng.trace +Bundle-Localization: plugin diff --git a/org.eclipse.linuxtools.lttng/build.properties b/org.eclipse.linuxtools.lttng/build.properties new file mode 100644 index 0000000000..aa1a008269 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/build.properties @@ -0,0 +1,5 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.properties diff --git a/org.eclipse.linuxtools.lttng/plugin.properties b/org.eclipse.linuxtools.lttng/plugin.properties new file mode 100644 index 0000000000..9415eb3102 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/plugin.properties @@ -0,0 +1,3 @@ +#Properties file for org.eclipse.linuxtools.lttng +Bundle-Vendor = Eclipse Linux Tools +Bundle-Name = LTTng - Linux Tracing Toolkit (Incubation) \ No newline at end of file diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/LTTngCorePlugin.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/LTTngCorePlugin.java new file mode 100644 index 0000000000..533f53704e --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/LTTngCorePlugin.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright (c) 2009 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: + * Francois Chouinard - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.lttng; + +import org.eclipse.core.runtime.Plugin; +import org.osgi.framework.BundleContext; + +/** + * LTTngCorePlugin + *

+ * The activator class controls the plug-in life cycle + */ +public class LTTngCorePlugin extends Plugin { + + // ======================================================================== + // Attributes + // ======================================================================== + + // The plug-in ID + public static final String PLUGIN_ID = "org.eclipse.linuxtools.lttng"; + + // The shared instance + private static LTTngCorePlugin plugin; + + // ======================================================================== + // Constructors + // ======================================================================== + + /** + * The constructor + */ + public LTTngCorePlugin() { + } + + // ======================================================================== + // Accessors + // ======================================================================== + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static LTTngCorePlugin getDefault() { + return plugin; + } + + // ======================================================================== + // Operators + // ======================================================================== + + /* + * (non-Javadoc) + * @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext) + */ + @Override + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + LttngFactory.init(); + } + + /* + * (non-Javadoc) + * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext) + */ + @Override + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/LttngException.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/LttngException.java new file mode 100644 index 0000000000..36de9fae25 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/LttngException.java @@ -0,0 +1,14 @@ +package org.eclipse.linuxtools.lttng; + +/** + * LttngException + *

+ * Super exception class for Lttng + */ +public class LttngException extends Exception { + static final long serialVersionUID = 4016530589556719360L; + + public LttngException(String errMsg) { + super(errMsg); + } +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/LttngFactory.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/LttngFactory.java new file mode 100644 index 0000000000..2191dc2a38 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/LttngFactory.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 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: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.linuxtools.lttng; + +import org.eclipse.linuxtools.lttng.control.LttngCoreProviderFactory; +import org.eclipse.linuxtools.lttng.state.experiment.StateManagerFactory; + +/** + * @author alvaro + * + */ +public class LttngFactory { + static void init() { + // Make sure the experiment component is ready to listen to experiment + // selections + StateManagerFactory.getExperimentManager(); + // The Synthetic event provider must also be notified of selections, in + // order to keep the sychronization orders from TMF, this element is + // shared for all synthetic event requests + LttngCoreProviderFactory.getEventProvider(); + + // start debugging as per .options + TraceDebug.init(); + } +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/TraceDebug.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/TraceDebug.java new file mode 100644 index 0000000000..c2cd34637d --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/TraceDebug.java @@ -0,0 +1,151 @@ +package org.eclipse.linuxtools.lttng; + +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.eclipse.core.runtime.ILog; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Plugin; +import org.eclipse.core.runtime.Status; + +public class TraceDebug { + static boolean DEBUG = false; + static boolean INFO = false; + static boolean WARN = false; + + private static Plugin plugin = LTTngCorePlugin.getDefault(); + private static String pluginID = LTTngCorePlugin.PLUGIN_ID; + private static SimpleDateFormat stimeformat = new SimpleDateFormat( + "HH:mm:ss:SSS"); + + public static void init() { + // Update JniTrace configuration options + String debugTrace = Platform.getDebugOption(pluginID + "/debug"); + String infoTrace = Platform.getDebugOption(pluginID + "/info"); + String warnTrace = Platform.getDebugOption(pluginID + "/warn"); + + if (debugTrace != null) { + DEBUG = (new Boolean(debugTrace)).booleanValue(); + } + + if (infoTrace != null) { + INFO = (new Boolean(infoTrace)).booleanValue(); + } + + if (warnTrace != null) { + WARN = (new Boolean(warnTrace)).booleanValue(); + } + } + + public static void info(String message) { + if (INFO) { + ILog logger = plugin.getLog(); + logger.log(new Status(IStatus.INFO, LTTngCorePlugin.PLUGIN_ID, + IStatus.OK, message, null)); + } + } + + public static void warn(String message) { + if (WARN) { + ILog logger = plugin.getLog(); + logger.log(new Status(IStatus.WARNING, LTTngCorePlugin.PLUGIN_ID, + IStatus.WARNING, message, null)); + } + } + + public static void debug(String message) { + if (DEBUG) { + String location = getCallingLocation(); + System.out.println(location + "\n\t-> " + message); + + } + } + + public static void debug(String message, int additionalStackLines) { + if (DEBUG) { + String location = getCallingLocation(additionalStackLines); + System.out.println(location + "\n\t-> " + message); + } + } + + public static void throwException(String message) { + if (DEBUG) { + try { + triggerException(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + private static void triggerException(String message) throws Exception { + throw new Exception(message); + } + + private static String getCallingLocation() { + StringBuilder sb = new StringBuilder(); + sb.append(trace(Thread.currentThread().getStackTrace(), 4)); + sb.append("\n" + trace(Thread.currentThread().getStackTrace(), 3)); + return sb.toString(); + } + + private static String getCallingLocation(int numOfStackLines) { + int stackCalledFromIdx = 3; + int earliestRequested = numOfStackLines > 0 ? stackCalledFromIdx + + numOfStackLines : stackCalledFromIdx; + StringBuilder sb = new StringBuilder(); + int max = Thread.currentThread().getStackTrace().length - 1; + earliestRequested = earliestRequested > max ? max : earliestRequested; + for (int i = earliestRequested; i >= stackCalledFromIdx; i--) { + sb.append(trace(Thread.currentThread().getStackTrace(), i) + "\n"); + } + return sb.toString(); + } + + private static String trace(StackTraceElement e[], int level) { + if (e != null) { + level = level >= e.length ? e.length - 1 : level; + StackTraceElement s = e[level]; + if (s != null) { + String simpleClassName = s.getClassName(); + String[] clsNameSegs = simpleClassName.split("\\."); + if (clsNameSegs.length > 0) + simpleClassName = clsNameSegs[clsNameSegs.length - 1]; + return stimeformat.format(new Date()) + " " + simpleClassName + + "." + s.getLineNumber() + "." + s.getMethodName(); + } + } + return null; + } + + public static boolean setDEBUG(boolean newValue) { + boolean oldValue = DEBUG; + DEBUG = newValue; + return oldValue; + } + + public static boolean setINFO(boolean newValue) { + boolean oldValue = INFO; + INFO = newValue; + return oldValue; + } + + public static boolean setWARN(boolean newValue) { + boolean oldValue = WARN; + WARN = newValue; + return oldValue; + } + + public static boolean isDEBUG() { + return DEBUG; + } + + public static boolean isINFO() { + return INFO; + } + + public static boolean isWARN() { + return WARN; + } +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/control/LttngCoreProviderFactory.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/control/LttngCoreProviderFactory.java new file mode 100644 index 0000000000..b92b12148a --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/control/LttngCoreProviderFactory.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2009,2010 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: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.linuxtools.lttng.control; + +import org.eclipse.linuxtools.lttng.event.LttngSyntheticEvent; + +/** + * @author alvaro + * + */ +public class LttngCoreProviderFactory { + + private static LttngSyntheticEventProvider fSynEventProvider = null; + + public static LttngSyntheticEventProvider getEventProvider() { + // create if necessary + if (fSynEventProvider == null) { + fSynEventProvider = new LttngSyntheticEventProvider( + LttngSyntheticEvent.class); + } + + return fSynEventProvider; + } +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/control/LttngSyntheticEventProvider.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/control/LttngSyntheticEventProvider.java new file mode 100644 index 0000000000..1f9074154c --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/control/LttngSyntheticEventProvider.java @@ -0,0 +1,442 @@ +/******************************************************************************* + * Copyright (c) 2010 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: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.lttng.control; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.linuxtools.lttng.TraceDebug; +import org.eclipse.linuxtools.lttng.event.LttngEvent; +import org.eclipse.linuxtools.lttng.event.LttngEventType; +import org.eclipse.linuxtools.lttng.event.LttngSyntheticEvent; +import org.eclipse.linuxtools.lttng.event.LttngSyntheticEvent.SequenceInd; +import org.eclipse.linuxtools.lttng.event.LttngTimestamp; +import org.eclipse.linuxtools.lttng.model.LTTngTreeNode; +import org.eclipse.linuxtools.lttng.request.LttngBaseEventRequest; +import org.eclipse.linuxtools.lttng.state.evProcessor.ITransEventProcessor; +import org.eclipse.linuxtools.lttng.state.evProcessor.state.StateEventToHandlerFactory; +import org.eclipse.linuxtools.lttng.state.model.LttngTraceState; +import org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager; +import org.eclipse.linuxtools.tmf.component.TmfEventProvider; +import org.eclipse.linuxtools.tmf.event.TmfEventSource; +import org.eclipse.linuxtools.tmf.event.TmfTimeRange; +import org.eclipse.linuxtools.tmf.event.TmfTimestamp; +import org.eclipse.linuxtools.tmf.experiment.TmfExperiment; +import org.eclipse.linuxtools.tmf.request.ITmfDataRequest; +import org.eclipse.linuxtools.tmf.request.ITmfEventRequest; +import org.eclipse.linuxtools.tmf.request.TmfDataRequest; +import org.eclipse.linuxtools.tmf.request.TmfEventRequest; +import org.eclipse.linuxtools.tmf.trace.ITmfContext; +import org.eclipse.linuxtools.tmf.trace.TmfContext; +import org.eclipse.linuxtools.tmf.trace.TmfTrace; + +/** + * @author alvaro + * + */ +public class LttngSyntheticEventProvider extends + TmfEventProvider { + + // ======================================================================== + // Data + // ======================================================================== + public static final int BLOCK_SIZE = 1; + public static final int NB_EVENTS = 1; + public static final int QUEUE_SIZE = 1; // lttng specific, one event at a + // time + + // TmfDataProvider fExtProvider = null; + private ITmfDataRequest fmainRequest = null; + private final Map feventProviderRequests = new HashMap(); + private final LttngSyntheticEvent fStatusEvent; + private final LttngSyntheticEvent fStatusEventAck; + private int fmainReqEventCount = 0; + volatile boolean startIndSent = false; + private LTTngTreeNode fExperiment = null; + private ITransEventProcessor fstateUpdateProcessor = StateEventToHandlerFactory + .getInstance(); + private boolean waitForRequest = false; + + // ======================================================================== + // Constructor + // ======================================================================== + /** + * Accessibility to package - use factory instead of this constructor + * + * @param type + */ + LttngSyntheticEventProvider(Class type) { + super("LttngSyntheticEventProvider", type, QUEUE_SIZE); + + // prepare empty instance status indicators and allow them to travel via + // the framework + TmfEventSource source = new TmfEventSource(this); + LttngEventType dtype = new LttngEventType(); + LttngTimestamp statusTimeStamp = new LttngTimestamp( + TmfTimestamp.BigBang); + + fStatusEvent = new LttngSyntheticEvent(null, statusTimeStamp, source, + dtype, null, null, null); + fStatusEvent.setSequenceInd(SequenceInd.STARTREQ); + + fStatusEventAck = new LttngSyntheticEvent(null, statusTimeStamp, + source, dtype, null, null, null); + fStatusEventAck.setSequenceInd(SequenceInd.ACK); + } + + // ======================================================================== + // Methods + // ======================================================================== + @SuppressWarnings("unchecked") + @Override + public ITmfContext armRequest( + final ITmfDataRequest request) { + // validate + // make sure we have the right type of request + if (!(request instanceof ITmfEventRequest)) { + request.cancel(); + TraceDebug.debug("Request is not an instance of ITmfEventRequest"); + return null; + } + + if (fExperiment == null) { + TraceDebug.debug("Experiment is null"); + request.cancel(); + return null; + } + + // get ready to start processing + reset(fExperiment); + + // At least one base provider shall be available + if (feventProviderRequests.size() < 1) { + request.cancel(); + TraceDebug.debug("No Base event providers available"); + return null; + } + + fmainRequest = request; + // define event data handling + ITmfEventRequest eventRequest = (ITmfEventRequest) fmainRequest; + TmfTimeRange reqWindow = eventRequest.getRange(); + + TraceDebug.debug("Main Synthethic event request started on thread: " + Thread.currentThread().getName()); + + // loop for every traceManager in current experiment + for (IStateTraceManager traceManager : feventProviderRequests + .keySet()) { + + // restore trace state system to nearest check point + TmfTimestamp checkPoint = traceManager + .restoreCheckPointByTimestamp(reqWindow.getStartTime()); + // validate so checkpoint restore is within requested bounds + TmfTimeRange traceRange = traceManager.getTrace().getTimeRange(); + if (!(checkPoint.getValue() >= traceRange.getStartTime().getValue() + && checkPoint.getValue() <= traceRange.getEndTime() + .getValue() && checkPoint.getValue() < reqWindow + .getEndTime().getValue())) { + // checkpoint is out of trace bounds + continue; + } + + // adjust start time bound to check point + TmfTimeRange adjustedRange = new TmfTimeRange(checkPoint, reqWindow + .getEndTime()); + + LttngTraceState traceModel = traceManager.getStateModel(); + // create sub-request for one trace within experiment + final LttngBaseEventRequest subRequest = new LttngBaseEventRequest( + adjustedRange, reqWindow.getStartTime(), 0, + TmfEventRequest.ALL_DATA, BLOCK_SIZE, traceModel) { + + private LttngSyntheticEvent syntheticEvent = null; + private LttngSyntheticEvent syntheticAckIndicator = null; + long subEventCount = 0L; + + private final long fDispatchTime = getDispatchTime().getValue(); + private final LttngTraceState fTraceModel = getTraceModel(); + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.linuxtools.lttng.control.LttngEventRequest#handleData + * () + */ + @Override + public void handleData() { + LttngEvent[] events = getData(); + if (events.length > 0) { + for (LttngEvent e : events) { + handleIncomingData(e); + } + } else { + TraceDebug.debug("handle data received with no data"); + // done(); + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.linuxtools.tmf.request.TmfDataRequest#done() + */ + @Override + public void done() { + // mark this sub-request as completed + super.done(); + handleProviderDone(getTraceModel()); + } + + /** + * Trigger the Analysis and sequential control of the events. + * + * @param e + */ + private void handleIncomingData(LttngEvent e) { + long eventTime = e.getTimestamp().getValue(); + + // if (eventTime == 13589777932952L) { + // // syscall entry id 78 expected + // System.out.println("debug mark at 13589777932952L"); + // } + + // queue the new event data and an ACK + updateSynEvent(e); + + + + // If time at or above requested time, update application + if (eventTime >= fDispatchTime) { + // Before update + syntheticEvent.setSequenceInd(SequenceInd.BEFORE); + queueResult(syntheticEvent); + queueResult(syntheticAckIndicator); + + // Update state locally + syntheticEvent.setSequenceInd(SequenceInd.UPDATE); + fstateUpdateProcessor.process(syntheticEvent, + fTraceModel); + + // After Update + syntheticEvent.setSequenceInd(SequenceInd.AFTER); + queueResult(syntheticEvent); + queueResult(syntheticAckIndicator); + + // increment once per dispatch + incrementSynEvenCount(); + subEventCount++; + } else { + // event time is between checkpoint adjusted time and + // requested time i.e. application does not expect the + // event, however the state system needs to be re-built + // to the dispatch point + syntheticEvent.setSequenceInd(SequenceInd.UPDATE); + fstateUpdateProcessor.process(syntheticEvent, + fTraceModel); + } + } + + /** + * Create a synthetic event from the received new reference, if + * the reference is the same there is no need for a new instance + * + * if this is the first event for this request, call start + * handler + * + * @param e + * @return + */ + private LttngSyntheticEvent updateSynEvent(LttngEvent e) { + if (syntheticEvent == null + || syntheticEvent.getBaseEvent() != e) { + syntheticEvent = new LttngSyntheticEvent(e); + syntheticAckIndicator = new LttngSyntheticEvent(e); + syntheticAckIndicator.setSequenceInd(SequenceInd.ACK); + } + + // Trace model needed by application handlers + syntheticEvent.setTraceModel(fTraceModel); + + // send the start request indication once per request thread + if (!startIndSent) { + TraceDebug.debug("Thread started: " + Thread.currentThread().getName()); + handleProviderStarted(getTraceModel()); + startIndSent = true; + } + + return syntheticEvent; + } + }; + + // preserve the associated sub request to control it e.g. + // cancellation + feventProviderRequests.put(traceManager, subRequest); + + // start request + TmfTrace provider = (TmfTrace) traceManager + .getTrace(); + provider.sendRequest(subRequest); + } + + // Return a dummy context, not used for relay provider + return new TmfContext(); + } + + /** + * Notify listeners to prepare to receive data e.g. clean previous data etc. + */ + public void handleProviderStarted(LttngTraceState traceModel) { + LttngSyntheticEvent startIndEvent = new LttngSyntheticEvent( + fStatusEvent); + startIndEvent.setSequenceInd(SequenceInd.STARTREQ); + + // Notify application + queueResult(startIndEvent); + queueResult(fStatusEventAck); + + // Notify state event processor + fstateUpdateProcessor.process(startIndEvent, null); + } + + /** + * Notify listeners, no more events for the current request will be + * distributed e.g. update view. + */ + public synchronized void handleProviderDone(LttngTraceState traceModel) { + // TODO: The use of a thread per main request and thread per sub-request + // requires + // to make sure the proper main request is marked completed. So a + // relationship of sub-requests to parent needs to be established to + // handle completion and cancellations properly + + // Close the main request when all sub-requests are marked completed + for (LttngBaseEventRequest subRequest : feventProviderRequests.values()) { + if (subRequest != null) { + if (!subRequest.isCompleted()) { + // Not ready to complete main request + return; + } + } + } + + // All sub-requests are marked completed so the main request can be + // completed as well + // Notify application, + LttngSyntheticEvent finishEvent = new LttngSyntheticEvent(fStatusEvent); + finishEvent.setSequenceInd(SequenceInd.ENDREQ); + finishEvent.setTraceModel(traceModel); + queueResult(finishEvent); + queueResult(fStatusEventAck); + // End the loop in the main request + queueResult(LttngSyntheticEvent.NullEvent); + } + + /** + * Increment the global event counter i.e. events from any sub requests + */ + private synchronized void incrementSynEvenCount() { + fmainReqEventCount++; + } + + /** + * @return + */ + public synchronized int getSynEvenCount() { + return fmainReqEventCount; + } + + /** + * Reset provider to a state ready to begin thread execution + * + * @param experimentNode + */ + public /* synchronized */ void reset(LTTngTreeNode experimentNode) { + + fmainRequest = null; + + // Make sure previous request are terminated + for (LttngBaseEventRequest tmpRequest : feventProviderRequests.values()) { + if (tmpRequest != null && !tmpRequest.isCompleted()) { + tmpRequest.cancel(); + } + } + + feventProviderRequests.clear(); + fmainReqEventCount = 0; + startIndSent = false; + + // set of base event providers + if (fExperiment != null) { + LTTngTreeNode[] traces = fExperiment.getChildren(); + for (LTTngTreeNode trace : traces) { + IStateTraceManager traceBaseEventProvider = (IStateTraceManager) trace; + feventProviderRequests.put(traceBaseEventProvider, null); + } + } + + if (fExperiment != experimentNode) { + updateExperimentNode(experimentNode); + } + } + + /** + * Point to a new experiment reference + * + * @param experiment + */ + private synchronized void updateExperimentNode(LTTngTreeNode experiment) { + if (experiment != null + && experiment.getValue() instanceof TmfExperiment) { + fExperiment = experiment; + } else { + TraceDebug + .debug("Experiment received is not instance of TmfExperiment: " + + experiment.getClass().getName()); + } + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.linuxtools.tmf.component.TmfDataProvider#sendRequest(org. + * eclipse.linuxtools.tmf.request.TmfDataRequest) + */ + public void sendRequest(final TmfDataRequest request) { + super.sendRequest(request); + if (waitForRequest) { + try { + request.waitForCompletion(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + /** + * @return the waitForRequest + */ + public boolean isWaitForRequest() { + return waitForRequest; + } + + /** + * @param waitForRequest + * configures the provider to wait for the request completion + */ + public void setWaitForRequest(boolean waitForRequest) { + this.waitForRequest = waitForRequest; + } + +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/event/LttngEvent.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/event/LttngEvent.java new file mode 100644 index 0000000000..3204207bb9 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/event/LttngEvent.java @@ -0,0 +1,182 @@ +package org.eclipse.linuxtools.lttng.event; + +import org.eclipse.linuxtools.lttng.jni.JniEvent; +import org.eclipse.linuxtools.tmf.event.TmfEvent; +import org.eclipse.linuxtools.tmf.event.TmfEventSource; +import org.eclipse.linuxtools.tmf.trace.TmfTrace; + +/** + * LttngEvent

+ * + * Lttng specific TmfEvent implementation.

+ * + * The main difference from the basic Tmf implementation is that we keep an internal reference to the JniEvent
+ * The conversion from this LttngEvent to the JniEvent is then possible. + */ +public class LttngEvent extends TmfEvent { + + // Reference to the JNI JniEvent. Should only be used INTERNALLY + private JniEvent jniEventReference = null; + + // Reference to the parent trace that own this event + private TmfTrace parentTrace = null; + + /** + * Constructor with parameters.

+ * + * @param timestamp The timestamp of this event + * @param source The source of this event + * @param type The type of this event + * @param content The content of this event + * @param reference The reference of this event + * @param lttEvent A reference to a valid JniEvent object + * + * @see org.eclipse.linuxtools.tmf.event.TmfTimestamp + * @see org.eclipse.linuxtools.tmf.event.TmfEventSource + * @see org.eclipse.linuxtools.lttng.event.LttngEventType + * @see org.eclipse.linuxtools.lttng.event.LttngEventContent + * @see org.eclipse.linuxtools.lttng.event.LttngEventReference + * @see org.eclipse.linuxtools.org.eclipse.linuxtools.lttng.jni.JniEvent + */ + public LttngEvent(TmfTrace parent, LttngTimestamp timestamp, TmfEventSource source, LttngEventType type, LttngEventContent content, LttngEventReference reference, JniEvent lttEvent) { + super(timestamp, source, type, reference); + + fContent = content; + jniEventReference = lttEvent; + setParentTrace(parent); + } + + /** + * Copy constructor.

+ * + * @param oldEvent Event we want to copy from. + */ + public LttngEvent(LttngEvent oldEvent) { + this( + oldEvent.getParentTrace(), + (LttngTimestamp)oldEvent.getTimestamp(), + (TmfEventSource)oldEvent.getSource(), + (LttngEventType)oldEvent.getType(), + (LttngEventContent)oldEvent.getContent(), + (LttngEventReference)oldEvent.getReference(), + oldEvent.jniEventReference + ); + } + + + /** + * Return the parent trace asoociated with this event + * + * @return Parent trace + */ + public TmfTrace getParentTrace() { + return parentTrace; + } + + /** + * Set a new parent trace for this event + * + * @param parentTrace The new parent + */ + public void setParentTrace(TmfTrace parentTrace) { + this.parentTrace = parentTrace; + } + + + /** + * Return the channel name of this event.

+ * + * @return Channel (tracefile) for this event + */ + public String getChannelName() { + return ( (LttngEventType)this.getType() ).getTracefileName(); + } + + /** + * Cpu id number of this event.

+ * + * @return CpuId + */ + public long getCpuId() { + return ( (LttngEventType)this.getType() ).getCpuId(); + } + + /** + * Marker name of this event.

+ * + * @return Marker name + */ + public String getMarkerName() { + return ( (LttngEventType)this.getType() ).getMarkerName(); + } + + @Override + public LttngEventContent getContent() { + return (LttngEventContent)fContent; + } + + public void setContent(LttngEventContent newContent) { + fContent = newContent; + } + + @Override + public LttngEventType getType() { + return (LttngEventType)fType; + } + + public void setType(LttngEventType newType) { + fType = newType; + } + + /** + * Set a new JniReference for this event.

+ * + * Note : Reference is used to get back to the Jni during event parsing and need to be consistent. + * + * @param newJniEventReference New reference + * + * @see org.eclipse.linuxtools.org.eclipse.linuxtools.lttng.jni.JniEvent + */ + public synchronized void updateJniEventReference(JniEvent newJniEventReference) { + this.jniEventReference = newJniEventReference; + } + + /** + * Convert this event into a Jni JniEvent.

+ * + * Note : Some verifications are done to make sure the event is still valid on + * the Jni side before conversion.
If it is not the case, null will be returned. + * + * @return The converted JniEvent + * + * @see org.eclipse.linuxtools.org.eclipse.linuxtools.lttng.jni.JniEvent + */ + public synchronized JniEvent convertEventTmfToJni() { + JniEvent tmpEvent = null; + + // ***TODO*** + // Should we remove the check to save some time?? + + // We don't want to send away events that are outdated as their informations could be invalid + // If the timestamp between the event and the trace are not coherent we will not perform the conversion + if ( jniEventReference.getParentTracefile().getParentTrace().getCurrentEventTimestamp().getTime() == getTimestamp().getValue() ) { + tmpEvent = jniEventReference; + } + else { + System.out.println("convertEventTmfToJni() failed: Unsynced Timestamp > TMF:" + getTimestamp().getValue() + " <--> JNI:" + jniEventReference.getParentTracefile().getParentTrace().getCurrentEventTimestamp().getTime()); + } + return tmpEvent; + } + + @Override + public String toString() { + String returnedData=""; + + returnedData += "Event timestamp:" + this.getTimestamp().getValue() + " "; + returnedData += "Channel:" + getChannelName() + " "; + returnedData += "CPU:" + getCpuId() + " "; + returnedData += "Marker:" + getMarkerName() + " "; + + return returnedData; + } +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/event/LttngEventContent.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/event/LttngEventContent.java new file mode 100644 index 0000000000..116b90e058 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/event/LttngEventContent.java @@ -0,0 +1,264 @@ +/******************************************************************************* + * Copyright (c) 2009 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: + * William Bourque (wbourque@gmail.com) - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.lttng.event; + +import java.util.HashMap; + +import org.eclipse.linuxtools.lttng.jni.JniEvent; +import org.eclipse.linuxtools.tmf.event.TmfEventContent; +import org.eclipse.linuxtools.tmf.event.TmfNoSuchFieldException; + +/** + * LttngEventContent

+ * + * Lttng specific implementation of the TmfEventContent.

+ */ +public class LttngEventContent extends TmfEventContent { + + // Hash map that contain the (parsed) fields. This is the actual payload of the event. + HashMap fFieldsMap = new HashMap(); + + /** + * Default constructor.

+ * + * + */ + public LttngEventContent() { + super(null, null); + } + + /** + * Constructor with parameters.

+ * + * @param thisParent Parent event for this content. + * + * @see org.eclipse.linuxtools.lttng.event.LttngEvent + */ + public LttngEventContent(LttngEvent thisParent) { + super(thisParent, null); + } + + /** + * Constructor with parameters, with optional content.

+ * + * @param thisParent Parent event for this content. + * @param thisContent Already parsed content. + * + * @see org.eclipse.linuxtools.lttng.event.LttngEvent + */ + public LttngEventContent(LttngEvent thisParent, HashMap thisContent) { + super(thisParent, null); + + fFieldsMap = thisContent; + } + + /** + * Copy Constructor.

+ * + * @param oldContent Content to copy from + */ + public LttngEventContent(LttngEventContent oldContent) { + this((LttngEvent)oldContent.getEvent(), oldContent.getRawContent() ); + } + + + @Override + public LttngEvent getEvent() { + return (LttngEvent)fParentEvent; + } + + public void setEvent(LttngEvent newParent) { + fParentEvent = newParent; + } + + + // *** VERIFY *** + // These are not very useful, are they? + @Override + public LttngEventType getType() { + return (LttngEventType)fParentEvent.getType(); + } + public void setType(LttngEventType newType) { + ((LttngEvent)fParentEvent).setType(newType); + } + + + // ***TODO*** + // Find a better way to ensure content is sane!! + public void emptyContent() { + fFieldsMap.clear(); + } + + // ***VERIFY*** + // A bit weird to return the _currently_parsed fields (unlike all fields like getFields() ) + // Should we keep this? + /** + * Return currently parsed fields in an object array format.

+ * + * @return Currently parsed fields. + */ + @Override + public Object[] getContent() { + Object[] returnedContent = fFieldsMap.values().toArray( new Object[fFieldsMap.size()] ); + + return returnedContent; + } + + /** + * Return currently parsed fields in the internal hashmap format.

+ * + * @return Currently parsed fields. + */ + public HashMap getRawContent() { + return fFieldsMap; + } + +// @SuppressWarnings("unchecked") +// @Override +// public LttngEventField[] getFields() { +// LttngEventField tmpField = null; +// +// // *** TODO *** +// // SLOW! SLOW! SLOW! We should prevent the user to use this!! +// HashMap parsedContent = parseContent(); +// +// String contentKey = null; +// Iterator contentItr = parsedContent.keySet().iterator(); +// while ( contentItr.hasNext() ) { +// contentKey = contentItr.next(); +// +// tmpField = new LttngEventField(this, contentKey, parsedContent.get(contentKey)); +// ((HashMap)fFields).put(contentKey, tmpField); +// } +// +// return fFields.values().toArray(new LttngEventField[fFields.size()]); +// } + + /** + * Parse all fields and return them as an array of LttngFields.

+ * + * Note : This function is heavy and should only be called if all fields are really needed. + * + * @return All fields. + * + * @see @see org.eclipse.linuxtools.lttng.event.LttngEventField + */ + @Override + public synchronized LttngEventField[] getFields() { + if ( fFieldsMap.size() < fParentEvent.getType().getNbFields() ) { + LttngEventField tmpField = null; + LttngEventType tmpType = (LttngEventType)fParentEvent.getType(); + + for ( int pos=0; pos + * + * @return The parsed field or null. + * + * @see @see org.eclipse.linuxtools.lttng.event.LttngEventField + */ + @Override + public LttngEventField getField(int position) { + LttngEventField returnedField = null; + String label = null; + try { + label = fParentEvent.getType().getLabel(position); + + returnedField = this.getField(label); + } + catch (TmfNoSuchFieldException e) { + System.out.println("Invalid field position requested : " + position + ", ignoring (getField)."); + } + + return returnedField; + } + + /** + * Parse a single field from its given name.

+ * + * @return The parsed field or null. + * + * @see @see org.eclipse.linuxtools.lttng.event.LttngEventField + */ + @Override + public synchronized LttngEventField getField(String name) { + // *** VERIFY *** + // Should we check if the field exists in LttngType before parsing? + // It could avoid calling parse for non-existent fields but would waste some cpu cycle on check? + LttngEventField returnedField = fFieldsMap.get(name); + + if ( returnedField == null ) { + // *** VERIFY *** + // Should we really make sure we didn't get null before creating/inserting a field? + JniEvent tmpEvent = ((LttngEvent)getEvent()).convertEventTmfToJni(); + + if ( tmpEvent != null) { + Object newValue = tmpEvent.parseFieldByName(name); + + if ( newValue!= null ) { + returnedField = new LttngEventField(this, name, newValue); + fFieldsMap.put(name, returnedField ); + } + } + } + + return returnedField; + } + + // *** VERIFY *** + // *** Is this even useful? + @Override + protected void parseContent() { + fFields = getFields(); + } + + /** + * toString() method to print the content + * + * Note : this function parse all fields and so is very heavy to use. + */ + @Override + public String toString() { + LttngEventField[] allFields = getFields(); + + StringBuffer strBuffer = new StringBuffer(); + for ( int pos=0; pos < allFields.length; pos++) { + strBuffer.append(allFields[pos].toString()); + } + + return strBuffer.toString(); + + } +} \ No newline at end of file diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/event/LttngEventField.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/event/LttngEventField.java new file mode 100644 index 0000000000..31b15bb2e0 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/event/LttngEventField.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright (c) 2009 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: + * William Bourque (wbourque@gmail.com) - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.lttng.event; + +import org.eclipse.linuxtools.tmf.event.TmfEventContent; +import org.eclipse.linuxtools.tmf.event.TmfEventField; + +/** + * LttngEventField

+ * + * Lttng specific implementation of the TmfEventField.

+ * + * LttngEventField add a "name" attribute to the Tmf implementation This + * mean the fields will have a name and a value. + */ +public class LttngEventField extends TmfEventField { + + /** + * Constructor with parameters.

+ * + * @param parent Parent content for this field + * @param id Name (label) of this field + */ + public LttngEventField(TmfEventContent parent, String id) { + super(parent, id, null); + } + + /** + * Constructor with parameters with optional value.

+ * + * @param parent Parent content for this field + * @param id Name (label) of this field + * @param value Parsed value (payload) of this field + */ + public LttngEventField(TmfEventContent parent, String id, Object value) { + super(parent, id, value); + } + + /** + * Copy constructor.

+ * + * @param oldField the field to copy from + */ + public LttngEventField(LttngEventField oldField) { + this(oldField.getParent(), oldField.getId(), oldField.getValue()); + } + + @Override + public String toString() { + return getId().toString() + ":" + getValue().toString(); + } + +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/event/LttngEventReference.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/event/LttngEventReference.java new file mode 100644 index 0000000000..9ed0652854 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/event/LttngEventReference.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (c) 2009 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: + * William Bourque (wbourque@gmail.com) - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.lttng.event; + +import org.eclipse.linuxtools.tmf.event.*; + +/** + * LttngEventReference

+ * + * Lttng specific implementation of the TmfEventReference + */ +public class LttngEventReference extends TmfEventReference { + + private String tracename = ""; + + /** + * Constructor with parameters.

+ * + * @param newTraceName Trace name + */ + public LttngEventReference(String newTraceName) { + super(""); + tracename = newTraceName; + } + + /** + * Constructor with parameters with optional tracefile path.

+ * + * @param newTracefilePath Complete tracefile path + * @param newTraceName Trace name + */ + public LttngEventReference(String newTracefilePath, String newTraceName) { + super(newTracefilePath); + + // Save the name of the trace + tracename = newTraceName; + } + + /** + * Copy Constructor.

+ * + * @param oldReference LttngEventReference to copy from. + */ + public LttngEventReference(LttngEventReference oldReference) { + this( oldReference.getValue().toString(), oldReference.getTracepath() ); + } + + + public String getTracepath() { + return tracename; + } + + public void setTracepath(String tracename) { + this.tracename = tracename; + } + + public String getValue() { + return (String)fReference; + } + + public void setValue(String newReference) { + fReference = newReference; + } + + /** + * toString() method.

+ * + * We return only tracename, as it will be used directly in the eventsView. + * Returning only tracename gives a better output. + * + * @return tracename as String + */ + @Override + public String toString() { + return tracename; + } + +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/event/LttngEventSource.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/event/LttngEventSource.java new file mode 100644 index 0000000000..861c03bb38 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/event/LttngEventSource.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright (c) 2009 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: + * William Bourque (wbourque@gmail.com) - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.lttng.event; + +import org.eclipse.linuxtools.tmf.event.*; + +/** + * LttngEventSource

+ * + * Lttng specific implementation of the TmfEventSource + */ +public class LttngEventSource extends TmfEventSource { + + /** + * Default Constructor.

+ * + */ + public LttngEventSource() { + super(); + } + + /** + * Copy Constructor.

+ * + * @param newSource Source of the event as string. + */ + public LttngEventSource(String newSource) { + super(newSource); + } + + + /** + * Copy Constructor.

+ * + * @param oldSource LttngEventSource to copy from. + */ + public LttngEventSource(LttngEventSource oldSource) { + this( (String)oldSource.getSourceId() ); + } + + + @Override + public String getSourceId() { + return (String)fSourceId; + } + + public void setSourceId(String newSource) { + fSourceId = newSource; + } + + @Override + public String toString() { + return fSourceId.toString(); + } +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/event/LttngEventType.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/event/LttngEventType.java new file mode 100644 index 0000000000..156cd4e8f4 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/event/LttngEventType.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright (c) 2009 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: + * William Bourque (wbourque@gmail.com) - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.lttng.event; + +import org.eclipse.linuxtools.tmf.event.*; + +/** + * LttngEventType

+ * + * Lttng specific implementation of the TmfEventType.

+ * + * This implementation add some attributes to the basic Tmf object. + */ +public class LttngEventType extends TmfEventType { + + private String tracefileName = null; + private Long cpuId = null; + private String markerName = null; + + /** + * Default Constructor.

+ * + */ + public LttngEventType() { + super(); + } + + /** + * Constructor with parameters.

+ * + * @param thisTracefileName Tracefile (channel) name in Ltt + * @param thisMarkerName Marker name in LTT + * @param thisMarkerfieldsName MarkerFields related to this marker + */ + public LttngEventType(String thisTracefileName, Long thisCpuId, String thisMarkerName, String[] thisMarkerfieldsName) { + super( thisTracefileName + "/" + thisCpuId + "/" + thisMarkerName, thisMarkerfieldsName); + + tracefileName = thisTracefileName; + cpuId = thisCpuId; + markerName = thisMarkerName; + } + + /** + * Copy constructor.

+ * + * @param oldType Type we want to copy from + */ + public LttngEventType(LttngEventType oldType) { + this(oldType.tracefileName, oldType.cpuId, oldType.markerName, oldType.getLabels()); + } + + + public String getTracefileName() { + return tracefileName; + } + + public Long getCpuId() { + return cpuId; + } + + public String getMarkerName() { + return markerName; + } + + /** + * toString() method. + * + * @return TypeId (channel/marker) of the object + */ + @Override + public String toString() { + // *** TODO *** + // This is used as-it in the events view, so we won't change its format. + // ...but maybe we should? + return tracefileName + "/" + cpuId.toString() + "/" + markerName; + } +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/event/LttngLocation.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/event/LttngLocation.java new file mode 100644 index 0000000000..08ae5aae88 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/event/LttngLocation.java @@ -0,0 +1,138 @@ +package org.eclipse.linuxtools.lttng.event; + +import org.eclipse.linuxtools.tmf.trace.ITmfLocation; + + +public class LttngLocation implements ITmfLocation { + + private final static long DEFAULT_CURR_TIME = 0L; + + private boolean isLastOperationParse = false ; + private boolean isLastOperationReadNext = false; + private boolean isLastOperationSeek = false; + + private LttngTimestamp operationTime = null; + + public LttngLocation() { + this( DEFAULT_CURR_TIME ); + } + + public LttngLocation(long newCurrentTimestampValue) { + isLastOperationParse = false; + isLastOperationReadNext = false; + isLastOperationSeek = false; + operationTime = new LttngTimestamp(newCurrentTimestampValue); + } + + public LttngLocation(LttngTimestamp newCurrentTimestamp) { + isLastOperationParse = false; + isLastOperationReadNext = false; + isLastOperationSeek = false; + operationTime = new LttngTimestamp(newCurrentTimestamp); + } + + + public LttngLocation(LttngLocation oldLocation) { + this.isLastOperationParse = oldLocation.isLastOperationParse; + this.isLastOperationReadNext = oldLocation.isLastOperationReadNext; + this.isLastOperationSeek = oldLocation.isLastOperationSeek; + this.operationTime = oldLocation.operationTime; + } + + @Override + public LttngLocation clone() { + + LttngLocation newLocation = null; + + try { + newLocation = (LttngLocation)super.clone(); + + // *** IMPORTANT *** + // Basic type in java are immutable! + // Thus, using assignation ("=") on basic type is VALID. + newLocation.isLastOperationParse = this.isLastOperationParse; + newLocation.isLastOperationReadNext = this.isLastOperationReadNext; + newLocation.isLastOperationSeek = this.isLastOperationSeek; + + // For other type, we need to create a new timestamp + newLocation.operationTime = new LttngTimestamp( this.operationTime ); + } + catch (CloneNotSupportedException e) { + System.out.println("Cloning failed with : " + e.getMessage()); + } + + return newLocation; + } + + public LttngTimestamp getOperationTime() { + return operationTime; + } + + public long getOperationTimeValue() { + return operationTime.getValue(); + } + + public void setOperationTime(LttngTimestamp newOperationTime) { + this.operationTime.setValue(newOperationTime.getValue()); + } + + public void setOperationTime(Long newOperationTimeValue) { + this.operationTime.setValue(newOperationTimeValue); + } + + + public void setLastOperationParse() { + isLastOperationParse = true; + isLastOperationReadNext = false; + isLastOperationSeek = false; + } + + public boolean isLastOperationParse() { + return isLastOperationParse; + } + + + public void setLastOperationReadNext() { + isLastOperationParse = false; + isLastOperationReadNext = true; + isLastOperationSeek = false; + } + + public boolean isLastOperationReadNext() { + return isLastOperationReadNext; + } + + + public void setLastOperationSeek() { + isLastOperationParse = false; + isLastOperationReadNext = false; + isLastOperationSeek = true; + } + + public boolean isLastOperationSeek() { + return isLastOperationSeek; + } + + public void resetLocationState() { + isLastOperationParse = false; + isLastOperationReadNext = false; + isLastOperationSeek = false; + } + + @Override + public String toString() { + return "\tLttngLocation[ P/R/S : " + isLastOperationParse + "/" + isLastOperationReadNext + "/" + isLastOperationSeek + " Current : " + operationTime + " ]"; + } + + // ------------------------------------------------------------------------ + // ITmfLocation + // ------------------------------------------------------------------------ + public void setLocation(LttngTimestamp location) { + operationTime = (LttngTimestamp)location; + } + + public LttngTimestamp getLocation() { + return new LttngTimestamp ( operationTime ); + } + +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/event/LttngSyntheticEvent.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/event/LttngSyntheticEvent.java new file mode 100644 index 0000000000..52aee15cd5 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/event/LttngSyntheticEvent.java @@ -0,0 +1,295 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 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: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.linuxtools.lttng.event; + +import org.eclipse.linuxtools.lttng.jni.JniEvent; +import org.eclipse.linuxtools.lttng.state.model.LttngTraceState; +import org.eclipse.linuxtools.tmf.event.TmfEventSource; +import org.eclipse.linuxtools.tmf.trace.TmfTrace; + +/** + * @author alvaro + * + */ +public class LttngSyntheticEvent extends LttngEvent { + + public static final LttngSyntheticEvent NullEvent = new LttngSyntheticEvent(); + + // ======================================================================+ + // Data + // ======================================================================= + /** + *

+ * BEFORE: Before the update to the state system + *

+ *

+ * UPDATE: Proceed to update the state system + *

+ *

+ * AFTER: After the update of the state system + *

+ *

+ * ACK: Acknowledge indicator for any of the previous sequences + *

+ */ + public enum SequenceInd { + STARTREQ, BEFORE, UPDATE, AFTER, ENDREQ, ACK + }; + + private SequenceInd sequence = SequenceInd.BEFORE; + private LttngEvent baseEvent = null; + private LttngTraceState fTraceModel = null; + // ======================================================================+ + // Constructors + // ======================================================================= + /** + * @param baseEvent + */ + public LttngSyntheticEvent(LttngEvent baseEvent) { + super(baseEvent); + this.baseEvent = baseEvent; + } + + /** + * @param parent + * @param timestamp + * @param source + * @param type + * @param content + * @param reference + * @param lttEvent + */ + public LttngSyntheticEvent(TmfTrace parent, + LttngTimestamp timestamp, TmfEventSource source, + LttngEventType type, LttngEventContent content, + LttngEventReference reference, JniEvent lttEvent) { + super(parent, timestamp, source, type, content, reference, lttEvent); + } + + private LttngSyntheticEvent() { + this(null, null, null, null, null, null, null); + } + + // ======================================================================+ + // Methods + // ======================================================================= + + /** + * @return the sequence indicator + */ + public SequenceInd getSynType() { + return sequence; + } + + /** + * @param type + * the sequence indicator to set + */ + public void setSequenceInd(SequenceInd sequence) { + this.sequence = sequence; + } + + /** + * @return the baseEvent + */ + public LttngEvent getBaseEvent() { + return baseEvent; + } + + /** + * @param traceModel + * the trace state-data-model associated to this event + */ + public void setTraceModel(LttngTraceState traceModel) { + this.fTraceModel = traceModel; + } + + /** + * @return the traceModel + */ + public LttngTraceState getTraceModel() { + return fTraceModel; + } + + /** + * /* (non-Javadoc) + * + * @see org.eclipse.linuxtools.lttng.event.LttngEvent#getParentTrace() + */ + public TmfTrace getParentTrace() { + if (baseEvent != null) { + return baseEvent.getParentTrace(); + } else { + return super.getParentTrace(); + } + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.linuxtools.lttng.event.LttngEvent#setParentTrace(org.eclipse + * .linuxtools.tmf.trace.TmfTrace) + */ + public void setParentTrace(TmfTrace parentTrace) { + if (baseEvent != null) { + baseEvent.setParentTrace(parentTrace); + } else { + super.setParentTrace(parentTrace); + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.linuxtools.lttng.event.LttngEvent#getChannelName() + */ + public String getChannelName() { + if (baseEvent != null) { + return baseEvent.getChannelName(); + } else { + return super.getChannelName(); + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.linuxtools.lttng.event.LttngEvent#getCpuId() + */ + public long getCpuId() { + if (baseEvent != null) { + return baseEvent.getCpuId(); + } else { + return super.getCpuId(); + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.linuxtools.lttng.event.LttngEvent#getMarkerName() + */ + public String getMarkerName() { + if (baseEvent != null) { + return baseEvent.getMarkerName(); + } else { + return super.getMarkerName(); + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.linuxtools.lttng.event.LttngEvent#getContent() + */ + public LttngEventContent getContent() { + if (baseEvent != null) { + return baseEvent.getContent(); + } else { + return super.getContent(); + } + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.linuxtools.lttng.event.LttngEvent#setContent(org.eclipse. + * linuxtools.lttng.event.LttngEventContent) + */ + public void setContent(LttngEventContent newContent) { + if (baseEvent != null) { + baseEvent.setContent(newContent); + } else { + super.setContent(newContent); + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.linuxtools.lttng.event.LttngEvent#getType() + */ + public LttngEventType getType() { + if (baseEvent != null) { + return baseEvent.getType(); + } else { + return super.getType(); + } + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.linuxtools.lttng.event.LttngEvent#setType(org.eclipse.linuxtools + * .lttng.event.LttngEventType) + */ + public void setType(LttngEventType newType) { + if (baseEvent != null) { + baseEvent.setType(newType); + } else { + super.setType(newType); + } + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.linuxtools.lttng.event.LttngEvent#updateJniEventReference + * (org.eclipse.linuxtools.lttng.jni.JniEvent) + */ + public void updateJniEventReference(JniEvent newJniEventReference) { + if (baseEvent != null) { + baseEvent.updateJniEventReference(newJniEventReference); + } else { + super.updateJniEventReference(newJniEventReference); + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.linuxtools.lttng.event.LttngEvent#convertEventTmfToJni() + */ + public JniEvent convertEventTmfToJni() { + if (baseEvent != null) { + return baseEvent.convertEventTmfToJni(); + } else { + return super.convertEventTmfToJni(); + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.linuxtools.lttng.event.LttngEvent#isNullRef() + */ + public boolean isNullRef() { + return this == NullEvent; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.linuxtools.lttng.event.LttngEvent#toString() + */ + public String toString() { + if (baseEvent != null) { + return baseEvent.toString(); + } else { + return super.toString(); + } + } +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/event/LttngTimestamp.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/event/LttngTimestamp.java new file mode 100644 index 0000000000..df1da9e42a --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/event/LttngTimestamp.java @@ -0,0 +1,161 @@ +/******************************************************************************* + * Copyright (c) 2009 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: + * William Bourque (wbourque@gmail.com) - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.lttng.event; + +import org.eclipse.linuxtools.tmf.event.TmfTimestamp; + +/** + * LttngTimestamp

+ * + * Lttng specific implementation of the TmfTimestamp.

+ * + * The Lttng implementation is the same as the basic Tmf Implementation but allow construction with a TmfTimestamp or a long. + */ +public class LttngTimestamp extends TmfTimestamp { + + // Required by Serializable + private static final long serialVersionUID = -7016853105162491273L; + + /** + * Default Constructor.

+ * + */ + public LttngTimestamp() { + super(Long.MIN_VALUE, (byte) -9); + } + + /** + * Constructor with parameters.

+ * + * @param newEventTime Time as long, unit expected to be nanoseconds + */ + public LttngTimestamp(long newEventTime) { + super(newEventTime, (byte) -9); + } + + /** + * Copy Constructor.

+ * + * @param oldEventTime The timestamp object we want to copy from + */ + public LttngTimestamp(TmfTimestamp oldEventTime) { + this(oldEventTime.getValue()); + } + + @Override + public long getValue() { + return fValue; + } + + public void setValue(long newValue) { + fValue = newValue; + } + + /** + * Get the second part in timestamp.

+ * + * Note : We do not use scale and assumes contents to be in nano seconds. + * + * @return Seconds in the object, in string. + */ + public String getSeconds() { + return formatSecs(fValue); + } + + /** + * Get the nanosecond part in timestamp.

+ * + * Note : We do not use scale and assumes contents to be in nanoseconds. + * + * @return Seconds in the object, in string. + */ + public String getNanoSeconds() { + return formatNs(fValue); + } + + /* + * Use the exponent to format the second in the correct format. + */ + private String formatSecs(long time) { + long sec = (long) (time * 1E-9); + return String.valueOf(sec); + } + + /* + * Obtains the remainder fraction on unit Seconds of the entered value in + * nanoseconds. e.g. input: 1241207054171080214 ns. + * The number of fraction seconds can be obtained by removing the last 9 digits: + * In 1241207054, the fractional portion of seconds, expressed in ns is: 171080214 + */ + private String formatNs(long time) { + boolean neg = time < 0; + if (neg) { + time = -time; + } + // The following approach could be used although performance + // decreases in half. + // String strVal = String.format("%09d", time); + // String tmp = strVal.substring(strVal.length() - 9) + StringBuffer temp = new StringBuffer(); + long ns = time; + ns %= 1000000000; + if (ns < 10) { + temp.append("00000000"); + } else if (ns < 100) { + temp.append("0000000"); + } else if (ns < 1000) { + temp.append("000000"); + } else if (ns < 10000) { + temp.append("00000"); + } else if (ns < 100000) { + temp.append("0000"); + } else if (ns < 1000000) { + temp.append("000"); + } else if (ns < 10000000) { + temp.append("00"); + } else if (ns < 100000000) { + temp.append("0"); + } + + temp.append(ns); + return temp.toString(); + } + + + /** + * toString() method. + * + * @return timestamp, as string + */ + @Override + public String toString() { + + // If we are dealing with units of seconds (or higher), + // use the plain formatter + if (fScale >= 0) { + Double value = fValue * Math.pow(10, fScale); + return value.toString(); + } + + // Define a format string + String format = String.format("%%1d.%%0%dd", -fScale); + + // And format the timestamp value + double scale = Math.pow(10, fScale); + long seconds = (long) (fValue * scale); + long fracts = fValue - (long) ((double) seconds / scale); + String result = String.format(format, seconds, fracts); + + return result; + } +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/model/ILTTngTreeNode.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/model/ILTTngTreeNode.java new file mode 100644 index 0000000000..0d6da5eb5d --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/model/ILTTngTreeNode.java @@ -0,0 +1,119 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 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: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.linuxtools.lttng.model; + +import org.eclipse.core.runtime.IAdaptable; + +/** + * @author alvaro + * + */ +public interface ILTTngTreeNode> extends IAdaptable { + // ======================================================================== + // Methods + // ======================================================================== + /** + * Return the unique id of this resource + * + * @return + */ + public Long getId(); + + /** + * Types are defined by the user application + * + * @return + */ + public Object getType(); + + /** + * Return this resource name + * + * @return + */ + public E getChildByName(String name); + + /** + * @param k + * k needed for the creation of the generic array + * @return + */ + public E[] getChildren(); + + /** + * Get the child by its unique id + * + * @param id + * @return + */ + public E getChildById(Long id); + + /** + * Get the parent of this resource + * + * @return + */ + public E getParent(); + + /** + * @return + */ + public boolean hasChildren(); + + /** + * Return the name of this resource + * + * @return + */ + public String getName(); + + /** + *

+ * Get the path from parent resources to this resource + *

+ *

+ * e.g. /root/name1/name2 + *

+ * + * @return + */ + public String getPath(); + + /** + * Return the reference value associated to this tree node + * + * @return + */ + public Object getValue(); + + /** + * returns the next value to be used as unique id in reference to this + * instance e.g. can be used to construct children unique ids. + */ + public Long getNextUniqueId(); + + /** + * Returns an attribute by name and casts the attribute value to the + * specified type, returns null if the attribute itself is null, not and + * instance of the specified class or the attribute has not been added + * + * @return + */ + public T getAttribute(String name, Class type); + + /** + * Adds an attribute by name and which is not a tree node element + * + * @return true if the element was not added e.g. invalid input + */ + public boolean addAttribute(String name, Object attribute); +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/model/LTTngTreeNode.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/model/LTTngTreeNode.java new file mode 100644 index 0000000000..65f40aca75 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/model/LTTngTreeNode.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 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: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.linuxtools.lttng.model; + + +public class LTTngTreeNode extends + LTTngTreeNodeGeneric { + + // ======================================================================== + // Data + // ======================================================================== + + + // ======================================================================== + // Constructors + // ======================================================================== + /** + * @param id + * @param parent + * @param name + */ + public LTTngTreeNode(Long id, LTTngTreeNode parent, String name) { + super(id, parent, name, null); + } + + /** + * @param id + * @param parent + * @param name + * @param value + */ + public LTTngTreeNode(Long id, LTTngTreeNode parent, String name, + Object value) { + super(id, parent, name, value); + } + + /** + * When parent is not know just yet + * + * @param id + * @param name + * @param value + */ + public LTTngTreeNode(Long id, String name, Object value) { + this(id, null, name, value); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.linuxtools.lttng.model.LTTngTreeNodeGeneric#getChildren() + */ + public LTTngTreeNode[] getChildren() { + return childrenToArray(fchildren.values(), this.getClass()); + } + +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/model/LTTngTreeNodeGeneric.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/model/LTTngTreeNodeGeneric.java new file mode 100644 index 0000000000..b46cc52d75 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/model/LTTngTreeNodeGeneric.java @@ -0,0 +1,351 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 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: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.linuxtools.lttng.model; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.linuxtools.lttng.TraceDebug; +import org.eclipse.linuxtools.tmf.event.TmfData; + +public abstract class LTTngTreeNodeGeneric> + extends TmfData implements ILTTngTreeNode { + + // ======================================================================== + // Data + // ======================================================================== + private final Long fid; + private final Object ftype; + private final Object fvalue; + protected final Map fchildren = new HashMap(); + protected final Map fchildrenByName = new HashMap(); + protected final Map fattributesByName = new HashMap(); + private E fparent = null; + private final String fname; + private Long idCount = 0L; + + // ======================================================================== + // Constructors + // ======================================================================== + /** + * @param id + * @param parent + * @param name + * @param value + */ + public LTTngTreeNodeGeneric(Long id, E parent, String name, + Object value) { + fid = id; + fparent = parent; + fname = name; + + if (value != null) { + fvalue = value; + ftype = fvalue.getClass(); + } else { + fvalue = this; + ftype = this.getClass(); + } + } + + /** + * @param id + * @param parent + * @param name + */ + public LTTngTreeNodeGeneric(Long id, E parent, String name) { + this(id, parent, name, null); + } + + /** + * When parent is not know just yet + * + * @param id + * @param type + * @param name + */ + public LTTngTreeNodeGeneric(Long id, String name, Object value) { + this(id, null, name, value); + } + + // ======================================================================== + // Methods + // ======================================================================== + + /* + * (non-Javadoc) + * + * @see org.eclipse.linuxtools.lttng.control.ILTTngAnalysisResource#getId() + */ + public Long getId() { + return fid; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.linuxtools.lttng.control.ILTTngAnalysisResource#getType() + */ + public Object getType() { + return ftype; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.linuxtools.lttng.control.ILTTngAnalysisResource#getChildByName + * () + */ + public E getChildByName(String name) { + E child = null; + if (name != null) { + child = fchildrenByName.get(name); + } + return child; + } + + /** + * @param child + */ + public void addChild(E child) { + if (child != null) { + Long id = child.getId(); + if (id != null) { + if (fchildren.containsKey(id) && fchildren.get(id) != child) { + TraceDebug.debug("Replaced child " + id + " for: " + child); + } + fchildren.put(id, child); + fchildrenByName.put(child.getName(), child); + } + } + + return; + } + + /** + * @param child + */ + public void removeChild(E child) { + if (child != null) { + Long id = child.getId(); + if (id != null) { + E childToRemove = fchildren.remove(id); + if (childToRemove != null) { + fchildrenByName.remove(childToRemove.getName()); + } + } + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.linuxtools.lttng.model.ILTTngTreeNode#getChildren() + */ + public abstract E[] getChildren(); + // { + // return (T[]) childrenToArray(fchildren.values(), this.getClass()); + // } + + /** + * Convert from generic collection to generic array. An empty array is + * provided when no children nodes are defined + * + * @param collection + * @param k + * @return + */ + @SuppressWarnings("unchecked") + protected E[] childrenToArray(Collection collection, Class k) { + // check entries + if (collection == null || k == null) { + return null; + } + + int size = collection.size(); + + // unchecked cast + E[] childrenArray = (E[]) java.lang.reflect.Array.newInstance(k, size); + int i = 0; + for (E item : collection) { + childrenArray[i++] = item; + } + + return childrenArray; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.linuxtools.lttng.control.ILTTngAnalysisResource#getChildById + * (java.lang.Long) + */ + public E getChildById(Long id) { + if (id == null) + return null; + return fchildren.get(id); + } + + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.linuxtools.lttng.control.ILTTngAnalysisResource#getParent() + */ + public E getParent() { + return fparent; + } + + /** + * @param parent + */ + public void setParent(E parent) { + fparent = parent; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.linuxtools.lttng.control.ILTTngAnalysisResource#hasChildren() + */ + public boolean hasChildren() { + if (fchildren.size() > 0) { + return true; + } + return false; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.linuxtools.lttng.control.ILTTngAnalysisResource#getName() + */ + public String getName() { + return fname; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.linuxtools.lttng.control.ILTTngAnalysisResource#getPath() + */ + public String getPath() { + return getPath(this, ""); + } + + /** + * Obtaining the path recursively up to the related parents until no parent + * is found + * + * @param child + * @param ipath + * @return + */ + private String getPath(LTTngTreeNodeGeneric child, + String ipath) { + String path = ipath; + if (ipath != null) { + if (child == null) { + return ipath; + } else { + E parent = child.getParent(); + path = getPath(parent, "/" + child.getName() + ipath); + } + } + + return path; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class) + */ + @SuppressWarnings("rawtypes") + public Object getAdapter(Class clazz) { + if (clazz == ftype) { + return fvalue; + } + return null; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.linuxtools.lttng.model.ILTTngTreeNode#getValue() + */ + public Object getValue() { + return fvalue; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.linuxtools.lttng.model.ILTTngTreeNode#getNextUniqueId() + */ + public synchronized Long getNextUniqueId() { + return idCount++; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.linuxtools.lttng.model.ILTTngTreeNode#getAttribute(java.lang + * .String) + */ + @SuppressWarnings("unchecked") + public T getAttribute(String key, Class type) { + if (key != null) { + Object value = fattributesByName.get(key); + if (value.getClass().isAssignableFrom(type)) { + return (T) value; + } + } + + return null; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.linuxtools.lttng.model.ILTTngTreeNode#addAttribute(java.lang + * .String, java.lang.Object) + */ + public boolean addAttribute(String key, Object value) { + // validate + if (key == null || value == null) { + return false; + } + + fattributesByName.put(key, value); + return true; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.linuxtools.tmf.event.TmfData#isNullRef() + */ + public boolean isNullRef() { + return false; + } +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/request/ILttngSyntEventRequest.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/request/ILttngSyntEventRequest.java new file mode 100644 index 0000000000..f74e93c4c3 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/request/ILttngSyntEventRequest.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright (c) 20010 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: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.linuxtools.lttng.request; + +import org.eclipse.linuxtools.lttng.event.LttngSyntheticEvent; +import org.eclipse.linuxtools.tmf.component.TmfEventProvider; +import org.eclipse.linuxtools.tmf.event.TmfTimeRange; +import org.eclipse.linuxtools.tmf.request.ITmfDataRequest; + +public interface ILttngSyntEventRequest extends ITmfDataRequest { + + /** + * Trigger the start to process this request right after the notification to + * the interested listeners + * + * @param provider + * @param broadcast + * true: All views, false: only to registered listeners + */ + public abstract void startRequestInd( + TmfEventProvider provider); + + /** + * to be called by the handleCompletion in superclass method, notifies the + * interested listeners. i.e. if the request start indicated broadcast, the + * completion will also be broadcasted otherwise only registered listeners + * will be notified. + */ + public abstract void notifyCompletion(); + + public abstract void notifyStarting(); + + public abstract TmfTimeRange getExperimentTimeRange(); + + /** + * @param numOfEvents + * the numOfEvents to set + */ + public abstract void setSynEventCount(Long numOfEvents); + + /** + * @return the numOfEvents + */ + public abstract Long getSynEventCount(); + + /** + * @param clearAllData + * indicates the need to clear all previous data e.g. a new + * experiment selection + */ + public abstract void setclearDataInd(boolean clearAllData); + + /** + * Returns indication - clearing of all existing data model is required e.g + * from the selection of a new experiment + * + * @return + */ + public abstract boolean isclearDataInd(); + + /** + * @return

+ * The associated source of the request + *

+ *

+ * Returns null if no source object has been previously set + *

+ * + */ + public abstract Object getSource(); + + /** + * Sets a reference to the source of this request + * + * @param source + */ + public abstract void setSource(Object source); + + + /** + * Return the time range associated to this request + * + * @return + */ + public abstract TmfTimeRange getRange(); + +} \ No newline at end of file diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/request/IRequestStatusListener.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/request/IRequestStatusListener.java new file mode 100644 index 0000000000..c0d1feb8a6 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/request/IRequestStatusListener.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2009 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: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.linuxtools.lttng.request; + + + +/** + * Interface to be used to receive notification of Processing start and + * completed + * + * @author alvaro + * + */ +public interface IRequestStatusListener { + // ======================================================================== + // Methods + // ======================================================================== + + /** + * + * @param request + * @return + */ + public void processingStarted(RequestStartedSignal request); + + /** + * @param signal + */ + public void processingCompleted(RequestCompletedSignal signal); +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/request/LttngBaseEventRequest.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/request/LttngBaseEventRequest.java new file mode 100644 index 0000000000..ce3ff8104b --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/request/LttngBaseEventRequest.java @@ -0,0 +1,129 @@ +/******************************************************************************* + * Copyright (c) 2010 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: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.linuxtools.lttng.request; + +import org.eclipse.linuxtools.lttng.event.LttngEvent; +import org.eclipse.linuxtools.lttng.state.model.LttngTraceState; +import org.eclipse.linuxtools.tmf.event.TmfTimeRange; +import org.eclipse.linuxtools.tmf.event.TmfTimestamp; +import org.eclipse.linuxtools.tmf.experiment.TmfExperiment; +import org.eclipse.linuxtools.tmf.request.TmfEventRequest; + +/** + * This class is an extension of Tmf Event Request which includes specific + * references i.e. a status listener to indicate the start and end of the + * request + * + * @author alvaro + * + */ +public abstract class LttngBaseEventRequest extends TmfEventRequest { + + // ======================================================================== + // Data + // ======================================================================= + private long numOfEvents = 0; + private boolean clearDataInd = false; + private final LttngTraceState ftraceModel; + /** + * The time to send events to the application as requested, Note: The start + * time of the request for base events is adjusted to the nearest check + * point + */ + private final TmfTimestamp fDispatchTime; + + // ======================================================================== + // Constructors + // ======================================================================= + /** + * @param range + * @param dispatchTime + * @param offset + * @param nbEvents + * @param maxBlockSize + * @param traceModel + * @param listener + */ + public LttngBaseEventRequest(TmfTimeRange range, TmfTimestamp dispatchTime, + long offset, int nbEvents, int maxBlockSize, + LttngTraceState traceModel) { + super(LttngEvent.class, range, nbEvents, maxBlockSize); + ftraceModel = traceModel; + fDispatchTime = dispatchTime; + } + + // ======================================================================== + // Methods + // ======================================================================= + + /** + * Trigger the start to process this request right after the notification to + * the interested listeners + * + * @param experiment + * @param broadcast + * true: All views, false: only to registered listeners + */ + public void startRequestInd(TmfExperiment experiment, + boolean broadcast) { + // trigger the start to process this request + experiment.sendRequest(this); + } + + /** + * @param numOfEvents + * the numOfEvents to set + */ + public void setNumOfEvents(long numOfEvents) { + this.numOfEvents = numOfEvents; + } + + /** + * @return the numOfEvents + */ + public long getNumOfEvents() { + return numOfEvents; + } + + /** + * @param clearAllData + * indicates the need to clear all previous data e.g. a new + * experiment selection + */ + public void setclearDataInd(boolean clearAllData) { + this.clearDataInd = clearAllData; + } + + /** + * Returns indication - clearing of all existing data model is required e.g + * from the selection of a new experiment + * + * @return + */ + public boolean isclearDataInd() { + return clearDataInd; + } + + /** + * @return the ftraceModel, Trace state-data-model associated to this event + */ + public LttngTraceState getTraceModel() { + return ftraceModel; + } + + /** + * @return The time to start dispatching events to the application + */ + public TmfTimestamp getDispatchTime() { + return fDispatchTime; + } +} \ No newline at end of file diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/request/LttngSyntEventRequest.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/request/LttngSyntEventRequest.java new file mode 100644 index 0000000000..ee8bd416dc --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/request/LttngSyntEventRequest.java @@ -0,0 +1,194 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 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: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.linuxtools.lttng.request; + +import java.util.Vector; + +import org.eclipse.linuxtools.lttng.event.LttngSyntheticEvent; +import org.eclipse.linuxtools.lttng.state.evProcessor.ITransEventProcessor; +import org.eclipse.linuxtools.tmf.component.TmfEventProvider; +import org.eclipse.linuxtools.tmf.event.TmfTimeRange; +import org.eclipse.linuxtools.tmf.request.TmfEventRequest; + +/** + * This class is an extension of Data Request which includes specific references + * i.e. a status listener to indicate the start and end of the request + * + * @author alvaro + * + */ +public class LttngSyntEventRequest extends TmfEventRequest + implements ILttngSyntEventRequest { + + // ======================================================================== + // Data + // ======================================================================= + private Vector listeners = new Vector(); + private Long feventCount = 0L; + private boolean clearDataInd = false; + private TmfTimeRange fExperimentTimeRange = null; + private Object fsource = null; + private final ITransEventProcessor fprocessor; + + // ======================================================================== + // Constructors + // ======================================================================= + /** + * @param range + * @param offset + * @param nbEvents + * @param maxBlockSize + * @param listener + */ + public LttngSyntEventRequest(TmfTimeRange range, long offset, int nbEvents, + int maxBlockSize, IRequestStatusListener listener, + TmfTimeRange experimentTimeRange, ITransEventProcessor processor) { + + super(LttngSyntheticEvent.class, range, nbEvents, maxBlockSize); + //super(0, nbEvents, maxBlockSize); + fExperimentTimeRange = experimentTimeRange; + addListener(listener); + + fprocessor = processor; + } + + /** + * @param listener + */ + public void addListener(IRequestStatusListener listener) { + if (listener != null && !listeners.contains(listener)) { + listeners.add(listener); + } + } + + /** + * @param listener + */ + public void removeListner(IRequestStatusListener listener) { + if (listener != null) { + listeners.remove(listener); + } + } + + // ======================================================================== + // Methods + // ======================================================================= + /* (non-Javadoc) + * @see org.eclipse.linuxtools.lttng.request.ILttngEventRequest#startRequestInd(org.eclipse.linuxtools.tmf.experiment.TmfExperiment, boolean) + */ + public void startRequestInd(TmfEventProvider provider) { + // trigger the start to process this request + provider.sendRequest(this); + } + + /* (non-Javadoc) + * @see org.eclipse.linuxtools.lttng.request.ILttngEventRequest#notifyCompletion() + */ + public void notifyCompletion() { + // Notify specific state views + for (IRequestStatusListener listener : listeners) { + listener.processingCompleted(new RequestCompletedSignal(this)); + } + } + + /* (non-Javadoc) + * @see org.eclipse.linuxtools.lttng.request.ILttngEventRequest#notifyStarting() + */ + public void notifyStarting() { + for (IRequestStatusListener listener : listeners) { + listener.processingStarted(new RequestStartedSignal(this)); + } + } + + /* (non-Javadoc) + * @see org.eclipse.linuxtools.lttng.request.ILttngEventRequest#getExperimentTimeRange() + */ + public TmfTimeRange getExperimentTimeRange() { + return fExperimentTimeRange; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.linuxtools.lttng.request.ILttngSyntEventRequest#setSynEventCount + * (java.lang.Long) + */ + public synchronized void setSynEventCount(Long numOfEvents) { + this.feventCount = numOfEvents; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.linuxtools.lttng.request.ILttngSyntEventRequest#getEventCount + * () + */ + public Long getSynEventCount() { + return feventCount; + } + + /* (non-Javadoc) + * @see org.eclipse.linuxtools.lttng.request.ILttngEventRequest#setclearDataInd(boolean) + */ + public void setclearDataInd(boolean clearAllData) { + this.clearDataInd = clearAllData; + } + + /* (non-Javadoc) + * @see org.eclipse.linuxtools.lttng.request.ILttngEventRequest#isclearDataInd() + */ + public boolean isclearDataInd() { + return clearDataInd; + } + + /* (non-Javadoc) + * @see org.eclipse.linuxtools.lttng.request.ILttngEventRequest#handleData() + */ + @Override + public void handleData() { + } + + + /* + * (non-Javadoc) + * + * @see org.eclipse.linuxtools.tmf.request.TmfDataRequest#handleCompleted() + */ + public void handleCompleted() { + // notify listeners + notifyCompletion(); + super.handleCompleted(); + } + + /** + * @return the source + */ + public Object getSource() { + return fsource; + } + + /** + * @param source + */ + public void setSource(Object source) { + this.fsource = source; + } + + /** + * @return the event processor associated to this request + */ + public ITransEventProcessor getProcessor() { + return fprocessor; + } +} \ No newline at end of file diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/request/RequestCompletedSignal.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/request/RequestCompletedSignal.java new file mode 100644 index 0000000000..6604dd2144 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/request/RequestCompletedSignal.java @@ -0,0 +1,18 @@ +package org.eclipse.linuxtools.lttng.request; + +import org.eclipse.linuxtools.tmf.signal.TmfSignal; + +public class RequestCompletedSignal extends TmfSignal { + + LttngSyntEventRequest request; + + public RequestCompletedSignal(LttngSyntEventRequest request) { + super(request); + this.request = request; + } + + public LttngSyntEventRequest getRequest() { + return request; + } + +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/request/RequestEventDispatcher.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/request/RequestEventDispatcher.java new file mode 100644 index 0000000000..d8727e2858 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/request/RequestEventDispatcher.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 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: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.linuxtools.lttng.request; + +import java.util.Set; + +import org.eclipse.linuxtools.lttng.TraceDebug; +import org.eclipse.linuxtools.lttng.event.LttngEvent; +import org.eclipse.linuxtools.lttng.state.evProcessor.IBaseEventProcessor; +import org.eclipse.linuxtools.lttng.state.evProcessor.IEventToHandlerResolver; +import org.eclipse.linuxtools.lttng.state.evProcessor.ILttngEventProcessor; +import org.eclipse.linuxtools.lttng.state.model.LttngTraceState; +import org.eclipse.linuxtools.tmf.event.TmfEvent; + +/** + * @author Alvaro + * + */ +public class RequestEventDispatcher implements IBaseEventProcessor { + // ======================================================================== + // Table data + // ======================================================================= + protected Set eventsNotHandled = null; + private final IEventToHandlerResolver fhandlerRegistry; + + // ======================================================================== + // Constructors + // ======================================================================== + public RequestEventDispatcher(IEventToHandlerResolver rhandlerRegistry) { + fhandlerRegistry = rhandlerRegistry; + } + + // ======================================================================== + // Methods + // ======================================================================= + + + /* (non-Javadoc) + * @see org.eclipse.linuxtools.lttng.state.trace.IEventDispatcher#processEvent(org.eclipse.linuxtools.tmf.event.TmfEvent) + */ + public void process(TmfEvent tmfEvent, LttngTraceState traceStateModel) { + if (tmfEvent == null) { + return; + } + + if (!(tmfEvent instanceof LttngEvent)) { + TraceDebug + .debug("The event received is not an instance of LttngEvent and can not be processed"); + return; + } + + LttngEvent trcEvent = (LttngEvent) tmfEvent; + + String inEventName = trcEvent.getMarkerName(); + + // Check if the received event is a transition state event + // TODO: Remove temporarily to allow other events to go to the + // statistics view. + // Needs restructuring. + // Events eventStruct = StateStrings.getInstance() + // .getStateTransEventMap().get(inEventName); + // if (eventStruct != null) { + // String expectedChannel = eventStruct.getParent().getInName(); + // check that received channel is the expected channel in the + // structure + // if (inChannel.equals(expectedChannel)) { + + // Notify the STATE UPDATE handler + ILttngEventProcessor handler = fhandlerRegistry + .getStateUpdaterProcessor(inEventName); + + if (handler != null) { + // process State Update + handler.process(trcEvent, traceStateModel); + } + } + + /** + * Used for troubleshooting when debug mode is on + * + * @return + */ + public Set getEventsNotHandled() { + return eventsNotHandled; + } +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/request/RequestEventDispatcherToFact.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/request/RequestEventDispatcherToFact.java new file mode 100644 index 0000000000..94cf946360 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/request/RequestEventDispatcherToFact.java @@ -0,0 +1,150 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 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: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.linuxtools.lttng.request; + +import java.util.Iterator; +import java.util.Set; +import java.util.Vector; + +import org.eclipse.linuxtools.lttng.TraceDebug; +import org.eclipse.linuxtools.lttng.event.LttngEvent; +import org.eclipse.linuxtools.lttng.state.evProcessor.AbsEventToHandlerResolver; +import org.eclipse.linuxtools.lttng.state.evProcessor.EventProcessorProxy; +import org.eclipse.linuxtools.lttng.state.evProcessor.IBaseEventProcessor; +import org.eclipse.linuxtools.lttng.state.evProcessor.IEventToHandlerResolver; +import org.eclipse.linuxtools.lttng.state.evProcessor.ILttngEventProcessor; +import org.eclipse.linuxtools.lttng.state.model.LttngTraceState; +import org.eclipse.linuxtools.tmf.event.TmfEvent; + +/** + * @author Alvaro + * + */ +public class RequestEventDispatcherToFact implements IBaseEventProcessor { + // ======================================================================== + // Table data + // ======================================================================= + protected Set eventsNotHandled = null; + protected Vector listeners = new Vector(); + + // ======================================================================== + // Constructors + // ======================================================================== + public RequestEventDispatcherToFact(IEventToHandlerResolver handlerRegistry) { + + } + + // ======================================================================== + // Methods + // ======================================================================= + + + /* (non-Javadoc) + * @see org.eclipse.linuxtools.lttng.state.trace.IEventDispatcher#processEvent(org.eclipse.linuxtools.tmf.event.TmfEvent) + */ + public void process(TmfEvent tmfEvent, LttngTraceState traceStateModel) { + if (tmfEvent == null) { + return; + } + + if (!(tmfEvent instanceof LttngEvent)) { + TraceDebug + .debug("The event received is not an instance of LttngEvent and can not be processed"); + return; + } + +// System.out.println("Event: " + nbEvents++ + ", timestamp: " + tmfEvent.getTimestamp()); + + LttngEvent trcEvent = (LttngEvent) tmfEvent; +// LttngEventField[] fields = ((LttngEventContent)trcEvent.getContent()).getFields(); + + if (trcEvent != null) { + String inEventName = trcEvent.getMarkerName(); + // String inChannel = trcEvent.getChannelName(); + // TraceDebug.debug("Event: " + inEventName); + + // Check if the received event is a transition state event + // TODO: Remove temporarily to allow other events to go to the + // statistics view. + // Needs restructuring. + // Events eventStruct = StateStrings.getInstance() + // .getStateTransEventMap().get(inEventName); + // if (eventStruct != null) { + // String expectedChannel = eventStruct.getParent().getInName(); + // check that received channel is the expected channel in the + // structure + // if (inChannel.equals(expectedChannel)) { + // Notify the before Handlers + Set handlerRegister = EventProcessorProxy + .getInstance().getProcessingFactories(); + // Notify the state BEFORE update handlers + for (Iterator iterator = handlerRegister + .iterator(); iterator.hasNext();) { + IEventToHandlerResolver handlerRegistry = (IEventToHandlerResolver) iterator + .next(); + ILttngEventProcessor handler = handlerRegistry + .getBeforeProcessor(inEventName); + if (handler != null) { + // process State Update + handler.process(trcEvent, traceStateModel); + } + + } + + // Notify the STATE UPDATE handlers + // Only one state update expected + for (Iterator iterator = handlerRegister + .iterator(); iterator.hasNext();) { + IEventToHandlerResolver handlerRegistry = (IEventToHandlerResolver) iterator + .next(); + ILttngEventProcessor handler = handlerRegistry + .getStateUpdaterProcessor(inEventName); + if (handler != null) { + // process State Update + handler.process(trcEvent, traceStateModel); + } + + } + + // Notify the AFTER update handlers + for (Iterator iterator = handlerRegister + .iterator(); iterator.hasNext();) { + IEventToHandlerResolver handlerRegistry = (IEventToHandlerResolver) iterator + .next(); + ILttngEventProcessor handler = handlerRegistry + .getAfterProcessor(inEventName); + if (handler != null) { + // process State Update + handler.process(trcEvent, traceStateModel); + } + } + + // } else { + // StringBuilder sb = new StringBuilder( + // "Unexpected channel received for: " + inEventName + // + ", channel rec: " + inChannel + // + " chanel expected: " + expectedChannel); + // TraceDebug.debug(sb.toString()); + // } + // } + } + } + + /** + * Used for troubleshooting when debug mode is on + * + * @return + */ + public Set getEventsNotHandled() { + return eventsNotHandled; + } +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/request/RequestStartedSignal.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/request/RequestStartedSignal.java new file mode 100644 index 0000000000..624cb87719 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/request/RequestStartedSignal.java @@ -0,0 +1,18 @@ +package org.eclipse.linuxtools.lttng.request; + +import org.eclipse.linuxtools.tmf.signal.TmfSignal; + +public class RequestStartedSignal extends TmfSignal { + + LttngSyntEventRequest request; + + public RequestStartedSignal(LttngSyntEventRequest request) { + super(request); + this.request = request; + } + + public LttngSyntEventRequest getRequest() { + return request; + } + +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/signal/ILttExperimentSelectedListener.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/signal/ILttExperimentSelectedListener.java new file mode 100644 index 0000000000..06db70672d --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/signal/ILttExperimentSelectedListener.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2010 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: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.linuxtools.lttng.signal; + +import org.eclipse.linuxtools.lttng.event.LttngEvent; +import org.eclipse.linuxtools.tmf.experiment.TmfExperiment; +import org.eclipse.linuxtools.tmf.signal.TmfExperimentUpdatedSignal; + +/** + * @author alvaro + * + */ +public interface ILttExperimentSelectedListener { + + /** + * + * @param source + * @param experiment + */ + public void experimentSelected(Object source, + TmfExperiment experiment); + + /** + * @param signal + * @param waitForComplete + * if true: wait for the request to complete before returning + */ + public void experimentUpdated(TmfExperimentUpdatedSignal signal, boolean waitForComplete); + +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/signal/StateExperimentListener.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/signal/StateExperimentListener.java new file mode 100644 index 0000000000..3ce9235655 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/signal/StateExperimentListener.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2010 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: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.linuxtools.lttng.signal; + +import org.eclipse.linuxtools.lttng.event.LttngEvent; +import org.eclipse.linuxtools.tmf.component.TmfComponent; +import org.eclipse.linuxtools.tmf.event.TmfEvent; +import org.eclipse.linuxtools.tmf.experiment.TmfExperiment; +import org.eclipse.linuxtools.tmf.signal.TmfExperimentSelectedSignal; +import org.eclipse.linuxtools.tmf.signal.TmfSignalHandler; + +/** + * @author alvaro + * + */ +public class StateExperimentListener extends TmfComponent { + + private final ILttExperimentSelectedListener fhandler; + + public StateExperimentListener(String name, ILttExperimentSelectedListener handler) { + super(name); + fhandler = handler; + } + + @SuppressWarnings("unchecked") + @TmfSignalHandler + public void experimentSelected( + TmfExperimentSelectedSignal signal) { + TmfExperiment experiment = (TmfExperiment) signal + .getExperiment(); + + // notify handler + fhandler.experimentSelected(signal.getSource(), experiment); + } +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/LttngStateException.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/LttngStateException.java new file mode 100644 index 0000000000..843d6e72e9 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/LttngStateException.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright (c) 2009 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: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.lttng.state; + +/** + * + * @author alvaro + * + */ +public class LttngStateException extends Exception { + /** + * + */ + private static final long serialVersionUID = 7122881233964952441L; + + /** + * Constructs an {@code LttngStateException} with {@code null} as its error detail + * message. + */ + public LttngStateException() { + super(); + } + + /** + * Constructs an {@code LttngStateException} with the specified detail message. + * + * @param message + * The detail message (which is saved for later retrieval by the + * {@link #getMessage()} method) + */ + public LttngStateException(String message) { + super(message); + } + + /** + * Constructs an {@code LttngStateException} with the specified detail message and + * cause. + * + *

+ * Note that the detail message associated with {@code cause} is not + * automatically incorporated into this exception's detail message. + * + * @param message + * The detail message (which is saved for later retrieval by the + * {@link #getMessage()} method) + * + * @param cause + * The cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is permitted, and + * indicates that the cause is nonexistent or unknown.) + * + * @since 1.6 + */ + public LttngStateException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructs an {@code LttngStateException} with the specified cause and a detail + * message of {@code (cause==null ? null : cause.toString())} (which + * typically contains the class and detail message of {@code cause}). This + * constructor is useful for exceptions that are little more than + * wrappers for other throwables. + * + * @param cause + * The cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is permitted, and + * indicates that the cause is nonexistent or unknown.) + * + * @since 1.6 + */ + public LttngStateException(Throwable cause) { + super(cause); + } +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/StateDataRequest.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/StateDataRequest.java new file mode 100644 index 0000000000..667426ef31 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/StateDataRequest.java @@ -0,0 +1,220 @@ +/******************************************************************************* + * Copyright (c) 2009 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: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.linuxtools.lttng.state; + + +/** + * This class is an extension of Data Request which includes specific references + * i.e. a status listener to indicate the start and end of the request + * + * @author alvaro + * + */ +public class StateDataRequest { + // // + // ======================================================================== + // // Data + // // + // ======================================================================= + // private Vector listeners = new + // Vector(); + // private String transactionId = ""; /* optional user's attribute */ + // private StateManager manager = null; + // private long numOfEvents = 0; + // private boolean broadcast = false; + // private boolean clearDataInd = false; + // // + // ======================================================================== + // // Constructors + // // + // ======================================================================= + // /** + // * @param range + // * @param offset + // * @param nbEvents + // * @param maxBlockSize + // * @param listener + // */ + // public StateDataRequest(TmfTimeRange range, long offset, int nbEvents, + // int maxBlockSize, IStateDataRequestListener listener, + // StateManager manager) { + // + // super(range, nbEvents, maxBlockSize); + // //super(0, nbEvents, maxBlockSize); + // this.manager = manager; + // if (listener != null && !listeners.contains(listener)) { + // listeners.add(listener); + // } + // } + // + // /** + // * @param range + // * @param offset + // * @param nbEvents + // * @param maxBlockSize + // * @param listener + // * @param transactionID + // * optional use by user application + // */ + // public StateDataRequest(TmfTimeRange range, long offset, int nbEvents, + // int maxBlockSize, IStateDataRequestListener listener, + // String transactionID, StateManager manager) { + // + // this(range, offset, nbEvents, maxBlockSize, listener, manager); + // this.transactionId = transactionID; + // } + // + // // + // ======================================================================== + // // Methods + // // + // ======================================================================= + // + // /** + // * Trigger the start to process this request right after the notification + // to + // * the interested listeners + // * + // * @param experiment + // * @param broadcast + // * true: All views, false: only to registered listeners + // */ + // public void startRequestInd(TmfExperiment experiment, boolean broadcast, + // boolean waitForCompletion) { + // if (broadcast) { + // // Notify all state views. + // this.broadcast = broadcast; + // // TmfSignalManager.dispatchSignal(new RequestStartedSignal(this)); + // } + // // else { + // // // Notify specific state views + // // for (IStateDataRequestListener listener : listeners) { + // // listener.processingStarted(new RequestStartedSignal(this)); + // // } + // // } + // + // // trigger the start to process this request + // experiment.processRequest(this, waitForCompletion); + // } + // + // /** + // * to be called by the handleCompletion in superclass method, notifies the + // * interested listeners. i.e. if the request start indicated broadcast, + // the + // * completion will also be broadcasted otherwise only registered listeners + // * will be notified. + // */ + // public void notifyCompletion() { + // if (broadcast) { + // // Notify all state views. + // TraceDebug.debug("request completed" + this.toString()); + // TmfSignalManager.dispatchSignal(new RequestCompletedSignal(this)); + // } else { + // // Notify specific state views + // for (IStateDataRequestListener listener : listeners) { + // listener.processingCompleted(new RequestCompletedSignal(this)); + // } + // } + // } + // + // public void notifyStarting() { + // if (broadcast) { + // // Notify all state views. + // TraceDebug.debug("request started" + this.toString()); + // TmfSignalManager.dispatchSignal(new RequestStartedSignal(this)); + // } else { + // for (IStateDataRequestListener listener : listeners) { + // listener.processingStarted(new RequestStartedSignal(this)); + // } + // } + // } + // + // public String getTransactionId() { + // return transactionId; + // } + // + // public StateManager getStateManager() { + // return this.manager; + // } + // + // // public IStateDataRequestListener getListener() { + // // return listener; + // // } + // + // public void addListener(IStateDataRequestListener listener) { + // if (!listeners.contains(listener)) { + // listeners.add(listener); + // } + // } + // + // public void removeListener(IStateDataRequestListener listener) { + // if (listener != null) { + // listeners.remove(listener); + // } + // } + // + // /** + // * @param numOfEvents + // * the numOfEvents to set + // */ + // public void setNumOfEvents(long numOfEvents) { + // this.numOfEvents = numOfEvents; + // } + // + // /** + // * @return the numOfEvents + // */ + // public long getNumOfEvents() { + // return numOfEvents; + // } + // + // /** + // * @param clearAllData + // * indicates the need to clear all previous data e.g. a new + // * experiment selection + // */ + // public void setclearDataInd(boolean clearAllData) { + // this.clearDataInd = clearAllData; + // } + // + // /** + // * Returns indication - clearing of all existing data model is required + // e.g + // * from the selection of a new experiment + // * + // * @return + // */ + // public boolean isclearDataInd() { + // return clearDataInd; + // } + // + // /** + // * Compare the time range with a Data Request. + // * + // * @param trange + // * @return + // */ + // public boolean equalTime(StateDataRequest otherRequest) { + // TmfTimeRange trange = otherRequest.getRange(); + // TmfTimeRange myTimeRange = getRange(); + // TmfTimestamp myStartTime = myTimeRange.getStartTime(); + // TmfTimestamp myEndTime = myTimeRange.getEndTime(); + // + // if (myStartTime.equals(trange.getStartTime())) { + // if (myEndTime.equals(trange.getEndTime())) { + // return true; + // } + // } + // + // return false; + // } +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/StateStrings.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/StateStrings.java new file mode 100644 index 0000000000..f0c803e374 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/StateStrings.java @@ -0,0 +1,653 @@ +/******************************************************************************* + * Copyright (c) 2009 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: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.linuxtools.lttng.state; + +import java.util.HashMap; +import java.util.HashSet; + +/** + * Singleton + * Establishes relationships of state related strings, since the strings and + * relations are fixed, the elements are final i.e. just for reading. + * + * @author alvaro + * + */ +public class StateStrings { + + // ======================================================================== + // Table data + // ======================================================================= + private static StateStrings instance = null; + public static final String LTTV_STATE_UNBRANDED = ""; + private final HashMap eventStrMap = new HashMap(); + private final HashMap stateTransEventMap = new HashMap(); + private final String[] syscall_names = new String[256];; + private final String[] trap_names = new String[256]; + private final String[] irq_names = new String[256]; + private final String[] soft_irq_names = new String[32]; + + private StateStrings() { + // Build a Hash map from string name to actual event structure + for (Events event : Events.values()) { + eventStrMap.put(event.inName, event); + if (event.isStateTransition()) { + stateTransEventMap.put(event.inName, event); + } + } + + // Build system call names + for (int i = 0; i < 256; i++) { + syscall_names[i] = "syscall " + i; + } + + // Build trap names + for (int i = 0; i < 256; i++) { + trap_names[i] = "trap " + i; + } + + // Build irq names + for (int i = 0; i < 256; i++) { + irq_names[i] = "irq " + i; + } + + // Build softirq names + for (int i = 0; i < 32; i++) { + soft_irq_names[i] = "softirq " + i; + } + + } + + public static StateStrings getInstance() { + // Singleton to provide string constant + if (instance == null) { + instance = new StateStrings(); + } + return instance; + } + + public enum Channels { + LTT_CHANNEL_FD_STATE("fd_state"), /* */ + LTT_CHANNEL_GLOBAL_STATE("global_state"), /* */ + LTT_CHANNEL_IRQ_STATE("irq_state"), /* */ + LTT_CHANNEL_MODULE_STATE("module_state"), /* */ + LTT_CHANNEL_NETIF_STATE("netif_state"), /* */ + LTT_CHANNEL_SOFTIRQ_STATE("softirq_state"), /* */ + LTT_CHANNEL_SWAP_STATE("swap_state"), /* */ + LTT_CHANNEL_SYSCALL_STATE("syscall_state"), /* */ + LTT_CHANNEL_TASK_STATE("task_state"), /* */ + LTT_CHANNEL_VM_STATE("vm_state"), /* */ + LTT_CHANNEL_KPROBE_STATE("kprobe_state"), /* */ + LTT_CHANNEL_FS("fs"), /* */ + LTT_CHANNEL_KERNEL("kernel"), /* */ + LTT_CHANNEL_MM("mm"), /* */ + LTT_CHANNEL_USERSPACE("userspace"), /* */ + LTT_CHANNEL_BLOCK("block"); + + private final String inName; + + private Channels(String name) { + this.inName = name; + } + + public String getInName() { + return inName; + } + }; + + // + public enum Events { + LTT_EVENT_SYSCALL_ENTRY("syscall_entry"), /* */ + LTT_EVENT_SYSCALL_EXIT("syscall_exit"), /* */ + LTT_EVENT_TRAP_ENTRY("trap_entry"), /* */ + LTT_EVENT_TRAP_EXIT("trap_exit"), /* */ + LTT_EVENT_PAGE_FAULT_ENTRY("page_fault_entry"), /* */ + LTT_EVENT_PAGE_FAULT_EXIT("page_fault_exit"), /* */ + LTT_EVENT_PAGE_FAULT_NOSEM_ENTRY("page_fault_nosem_entry"), /* */ + LTT_EVENT_PAGE_FAULT_NOSEM_EXIT("page_fault_nosem_exit"), /* */ + LTT_EVENT_IRQ_ENTRY("irq_entry"), /* */ + LTT_EVENT_IRQ_EXIT("irq_exit"), /* */ + LTT_EVENT_SOFT_IRQ_RAISE("softirq_raise"), /* */ + LTT_EVENT_SOFT_IRQ_ENTRY("softirq_entry"), /* */ + LTT_EVENT_SOFT_IRQ_EXIT("softirq_exit"), /* */ + LTT_EVENT_SCHED_SCHEDULE("sched_schedule"), /* */ + LTT_EVENT_PROCESS_FORK("process_fork"), /* */ + LTT_EVENT_KTHREAD_CREATE("kthread_create"), /* */ + LTT_EVENT_PROCESS_EXIT("process_exit"), /* */ + LTT_EVENT_PROCESS_FREE("process_free"), /* */ + LTT_EVENT_EXEC("exec"), /* */ + LTT_EVENT_PROCESS_STATE("process_state"), /* */ + LTT_EVENT_STATEDUMP_END("statedump_end"), /* */ + LTT_EVENT_FUNCTION_ENTRY("function_entry"), /* */ + LTT_EVENT_FUNCTION_EXIT("function_exit"), /* */ + LTT_EVENT_THREAD_BRAND("thread_brand"), /* */ + LTT_EVENT_REQUEST_ISSUE("_blk_request_issue"), /* */ + LTT_EVENT_REQUEST_COMPLETE("_blk_request_complete"), /* */ + LTT_EVENT_LIST_INTERRUPT("interrupt"), /* */ + LTT_EVENT_SYS_CALL_TABLE("sys_call_table"), /* */ + LTT_EVENT_SOFTIRQ_VEC("softirq_vec"), /* */ + LTT_EVENT_KPROBE_TABLE("kprobe_table"), /* */ + LTT_EVENT_KPROBE("kprobe"); /* */ + + private final String inName; + private final HashSet children = new HashSet(); + private Channels parent = null; + // Expected to cause a state transition default flag + private boolean stateTransition = false; + + static { + associate(); + } + + private Events(String name) { + this.inName = name; + } + + public String getInName() { + return this.inName; + } + + public Channels getParent() { + return this.parent; + } + + public void setParent(Channels parent) { + this.parent = parent; + } + + public HashSet getChildren() { + return children; + } + + public boolean isStateTransition() { + return stateTransition; + } + + private static void associate() { + // SYSCALL, can receive ip, syscall_id + LTT_EVENT_SYSCALL_ENTRY.setParent(Channels.LTT_CHANNEL_KERNEL); + LTT_EVENT_SYSCALL_ENTRY.getChildren().add( + Fields.LTT_FIELD_SYSCALL_ID); + LTT_EVENT_SYSCALL_ENTRY.stateTransition = true; + + LTT_EVENT_SYSCALL_EXIT.setParent(Channels.LTT_CHANNEL_KERNEL); + LTT_EVENT_SYSCALL_EXIT.stateTransition = true; + + // TRAP + LTT_EVENT_TRAP_ENTRY.setParent(Channels.LTT_CHANNEL_KERNEL); + LTT_EVENT_TRAP_ENTRY.getChildren().add(Fields.LTT_FIELD_TRAP_ID); + LTT_EVENT_TRAP_ENTRY.stateTransition = true; + + LTT_EVENT_TRAP_EXIT.setParent(Channels.LTT_CHANNEL_KERNEL); + LTT_EVENT_TRAP_EXIT.stateTransition = true; + + // PAGE_FAULT + LTT_EVENT_PAGE_FAULT_ENTRY.setParent(Channels.LTT_CHANNEL_KERNEL); + LTT_EVENT_PAGE_FAULT_ENTRY.getChildren().add( + Fields.LTT_FIELD_TRAP_ID); + LTT_EVENT_PAGE_FAULT_ENTRY.stateTransition = true; + + LTT_EVENT_PAGE_FAULT_EXIT.setParent(Channels.LTT_CHANNEL_KERNEL); + LTT_EVENT_PAGE_FAULT_EXIT.stateTransition = true; + + // PAGE_FAULT_NOSEM + LTT_EVENT_PAGE_FAULT_NOSEM_ENTRY + .setParent(Channels.LTT_CHANNEL_KERNEL); + LTT_EVENT_PAGE_FAULT_NOSEM_ENTRY.getChildren().add( + Fields.LTT_FIELD_TRAP_ID); + LTT_EVENT_PAGE_FAULT_NOSEM_ENTRY.stateTransition = true; + + LTT_EVENT_PAGE_FAULT_NOSEM_EXIT.getChildren().add( + Fields.LTT_FIELD_TRAP_ID); + LTT_EVENT_PAGE_FAULT_NOSEM_EXIT.stateTransition = true; + + // IRQ it also receives fields kernel_mode, ip and handler + LTT_EVENT_IRQ_ENTRY.setParent(Channels.LTT_CHANNEL_KERNEL); + LTT_EVENT_IRQ_ENTRY.getChildren().add(Fields.LTT_FIELD_IRQ_ID); + LTT_EVENT_IRQ_ENTRY.stateTransition = true; + + LTT_EVENT_IRQ_EXIT.setParent(Channels.LTT_CHANNEL_KERNEL); + LTT_EVENT_IRQ_EXIT.stateTransition = true; + + // SOFT IRQ RAISE + LTT_EVENT_SOFT_IRQ_RAISE.setParent(Channels.LTT_CHANNEL_KERNEL); + LTT_EVENT_SOFT_IRQ_RAISE.getChildren().add( + Fields.LTT_FIELD_SOFT_IRQ_ID); + LTT_EVENT_SOFT_IRQ_RAISE.stateTransition = true; + + // SOFT IRQ ENTRY + LTT_EVENT_SOFT_IRQ_ENTRY.setParent(Channels.LTT_CHANNEL_KERNEL); + LTT_EVENT_SOFT_IRQ_ENTRY.getChildren().add( + Fields.LTT_FIELD_SOFT_IRQ_ID); + LTT_EVENT_SOFT_IRQ_ENTRY.stateTransition = true; + + LTT_EVENT_SOFT_IRQ_EXIT.setParent(Channels.LTT_CHANNEL_KERNEL); + LTT_EVENT_SOFT_IRQ_EXIT.stateTransition = true; + + // SCHED SCHEDULE + LTT_EVENT_SCHED_SCHEDULE.setParent(Channels.LTT_CHANNEL_KERNEL); + LTT_EVENT_SCHED_SCHEDULE.getChildren().add( + Fields.LTT_FIELD_PREV_PID); + LTT_EVENT_SCHED_SCHEDULE.getChildren().add( + Fields.LTT_FIELD_NEXT_PID); + LTT_EVENT_SCHED_SCHEDULE.getChildren().add( + Fields.LTT_FIELD_PREV_STATE); + LTT_EVENT_SCHED_SCHEDULE.stateTransition = true; + + // PROCESS FORK + LTT_EVENT_PROCESS_FORK.setParent(Channels.LTT_CHANNEL_KERNEL); + LTT_EVENT_PROCESS_FORK.getChildren().add( + Fields.LTT_FIELD_PARENT_PID); + LTT_EVENT_PROCESS_FORK.getChildren() + .add(Fields.LTT_FIELD_CHILD_PID); + LTT_EVENT_PROCESS_FORK.getChildren().add( + Fields.LTT_FIELD_CHILD_TGID); + LTT_EVENT_PROCESS_FORK.stateTransition = true; + + // KTHREAD + LTT_EVENT_KTHREAD_CREATE.setParent(Channels.LTT_CHANNEL_KERNEL); + LTT_EVENT_KTHREAD_CREATE.getChildren().add(Fields.LTT_FIELD_PID); + LTT_EVENT_KTHREAD_CREATE.stateTransition = true; + + // PROCES EXIT + LTT_EVENT_PROCESS_EXIT.setParent(Channels.LTT_CHANNEL_KERNEL); + LTT_EVENT_PROCESS_EXIT.getChildren().add(Fields.LTT_FIELD_PID); + LTT_EVENT_PROCESS_EXIT.stateTransition = true; + + // PROCESS FREE + LTT_EVENT_PROCESS_FREE.setParent(Channels.LTT_CHANNEL_KERNEL); + LTT_EVENT_PROCESS_FREE.getChildren().add(Fields.LTT_FIELD_PID); + LTT_EVENT_PROCESS_FREE.stateTransition = true; + + // EVENT EXEC + LTT_EVENT_EXEC.setParent(Channels.LTT_CHANNEL_FS); + LTT_EVENT_EXEC.getChildren().add(Fields.LTT_FIELD_FILENAME); + LTT_EVENT_EXEC.stateTransition = true; + + // THREAD BRAND + LTT_EVENT_THREAD_BRAND.setParent(Channels.LTT_CHANNEL_USERSPACE); + LTT_EVENT_THREAD_BRAND.getChildren().add(Fields.LTT_FIELD_NAME); + LTT_EVENT_THREAD_BRAND.stateTransition = true; + + // EVENT PROCESS STATE + LTT_EVENT_PROCESS_STATE.setParent(Channels.LTT_CHANNEL_TASK_STATE); + LTT_EVENT_PROCESS_STATE.getChildren().add(Fields.LTT_FIELD_PID); + LTT_EVENT_PROCESS_STATE.getChildren().add( + Fields.LTT_FIELD_PARENT_PID); + LTT_EVENT_PROCESS_STATE.getChildren().add(Fields.LTT_FIELD_NAME); + LTT_EVENT_PROCESS_STATE.getChildren().add(Fields.LTT_FIELD_TYPE); + LTT_EVENT_PROCESS_STATE.getChildren().add(Fields.LTT_FIELD_MODE); + LTT_EVENT_PROCESS_STATE.getChildren().add(Fields.LTT_FIELD_SUBMODE); + LTT_EVENT_PROCESS_STATE.getChildren().add(Fields.LTT_FIELD_STATUS); + LTT_EVENT_PROCESS_STATE.getChildren().add(Fields.LTT_FIELD_TGID); + LTT_EVENT_PROCESS_STATE.stateTransition = true; + + // EVENT STATEDUMP END + LTT_EVENT_STATEDUMP_END + .setParent(Channels.LTT_CHANNEL_GLOBAL_STATE); + LTT_EVENT_STATEDUMP_END.stateTransition = true; + + // LTT_EVENT_LIST_INTERRUPT + LTT_EVENT_LIST_INTERRUPT.setParent(Channels.LTT_CHANNEL_IRQ_STATE); + LTT_EVENT_LIST_INTERRUPT.getChildren().add(Fields.LTT_FIELD_ACTION); + LTT_EVENT_LIST_INTERRUPT.getChildren().add(Fields.LTT_FIELD_IRQ_ID); + LTT_EVENT_LIST_INTERRUPT.stateTransition = true; + + // LTT_EVENT_REQUEST_ISSUE + LTT_EVENT_REQUEST_ISSUE.setParent(Channels.LTT_CHANNEL_BLOCK); + LTT_EVENT_REQUEST_ISSUE.getChildren().add(Fields.LTT_FIELD_MAJOR); + LTT_EVENT_REQUEST_ISSUE.getChildren().add(Fields.LTT_FIELD_MINOR); + LTT_EVENT_REQUEST_ISSUE.getChildren().add(Fields.LTT_FIELD_OPERATION); + LTT_EVENT_REQUEST_ISSUE.getChildren().add( + Fields.LTT_FIELD_OPERATION); + LTT_EVENT_REQUEST_ISSUE.stateTransition = true; + + // LTT_EVENT_REQUEST_COMPLETE + LTT_EVENT_REQUEST_COMPLETE.setParent(Channels.LTT_CHANNEL_BLOCK); + LTT_EVENT_REQUEST_COMPLETE.getChildren() + .add(Fields.LTT_FIELD_MAJOR); + LTT_EVENT_REQUEST_COMPLETE.getChildren() + .add(Fields.LTT_FIELD_MINOR); + LTT_EVENT_REQUEST_COMPLETE.getChildren().add( + Fields.LTT_FIELD_OPERATION); + LTT_EVENT_REQUEST_COMPLETE.stateTransition = true; + + // LTT_EVENT_FUNCTION_ENTRY + LTT_EVENT_FUNCTION_ENTRY.setParent(Channels.LTT_CHANNEL_USERSPACE); + LTT_EVENT_FUNCTION_ENTRY.getChildren() + .add(Fields.LTT_FIELD_THIS_FN); + LTT_EVENT_FUNCTION_ENTRY.getChildren().add( + Fields.LTT_FIELD_CALL_SITE); + LTT_EVENT_FUNCTION_ENTRY.stateTransition = true; + + // LTT_EVENT_FUNCTION_EXIT + LTT_EVENT_FUNCTION_EXIT.setParent(Channels.LTT_CHANNEL_USERSPACE); + LTT_EVENT_FUNCTION_EXIT.getChildren().add(Fields.LTT_FIELD_THIS_FN); + LTT_EVENT_FUNCTION_EXIT.getChildren().add( + Fields.LTT_FIELD_CALL_SITE); + LTT_EVENT_FUNCTION_EXIT.stateTransition = true; + + // LTT_EVENT_FUNCTION_EXIT + LTT_EVENT_FUNCTION_EXIT.setParent(Channels.LTT_CHANNEL_USERSPACE); + LTT_EVENT_FUNCTION_EXIT.getChildren().add(Fields.LTT_FIELD_THIS_FN); + LTT_EVENT_FUNCTION_EXIT.getChildren().add( + Fields.LTT_FIELD_CALL_SITE); + LTT_EVENT_FUNCTION_EXIT.stateTransition = true; + + // LTT_EVENT_SYS_CALL_TABLE + LTT_EVENT_SYS_CALL_TABLE + .setParent(Channels.LTT_CHANNEL_SYSCALL_STATE); + LTT_EVENT_SYS_CALL_TABLE.getChildren().add(Fields.LTT_FIELD_ID); + LTT_EVENT_SYS_CALL_TABLE.getChildren() + .add(Fields.LTT_FIELD_ADDRESS); + LTT_EVENT_SYS_CALL_TABLE.getChildren().add(Fields.LTT_FIELD_SYMBOL); + LTT_EVENT_SYS_CALL_TABLE.stateTransition = true; + + // LTT_EVENT_SYS_CALL_TABLE + LTT_EVENT_KPROBE_TABLE.setParent(Channels.LTT_CHANNEL_KPROBE_STATE); + LTT_EVENT_KPROBE_TABLE.getChildren().add(Fields.LTT_FIELD_IP); + LTT_EVENT_KPROBE_TABLE.getChildren().add(Fields.LTT_FIELD_SYMBOL); + LTT_EVENT_KPROBE_TABLE.stateTransition = true; + + // LTT_EVENT_SOFTIRQ_VEC + LTT_EVENT_SOFTIRQ_VEC.setParent(Channels.LTT_CHANNEL_SOFTIRQ_STATE); + LTT_EVENT_SOFTIRQ_VEC.getChildren().add(Fields.LTT_FIELD_ID); + LTT_EVENT_SOFTIRQ_VEC.getChildren().add(Fields.LTT_FIELD_ADDRESS); + LTT_EVENT_SOFTIRQ_VEC.getChildren().add(Fields.LTT_FIELD_SYMBOL); + LTT_EVENT_SOFTIRQ_VEC.stateTransition = true; + } + + }; + + public enum Fields { + LTT_FIELD_SYSCALL_ID("syscall_id"), /* */ + LTT_FIELD_TRAP_ID("trap_id"), /* */ + LTT_FIELD_IRQ_ID("irq_id"), /* */ + LTT_FIELD_SOFT_IRQ_ID("softirq_id"), /* */ + LTT_FIELD_PREV_PID("prev_pid"), /* */ + LTT_FIELD_NEXT_PID("next_pid"), /* */ + LTT_FIELD_PREV_STATE("prev_state"), /* */ + LTT_FIELD_PARENT_PID("parent_pid"), /* */ + LTT_FIELD_CHILD_PID("child_pid"), /* */ + LTT_FIELD_PID("pid"), /* */ + LTT_FIELD_TGID("tgid"), /* */ + LTT_FIELD_CHILD_TGID("child_tgid"), /* */ + LTT_FIELD_FILENAME("filename"), /* */ + LTT_FIELD_NAME("name"), /* */ + LTT_FIELD_TYPE("type"), /* */ + LTT_FIELD_MODE("mode"), /* */ + LTT_FIELD_SUBMODE("submode"), /* */ + LTT_FIELD_STATUS("status"), /* */ + LTT_FIELD_THIS_FN("this_fn"), /* */ + LTT_FIELD_CALL_SITE("call_site"), /* */ + LTT_FIELD_MAJOR("major"), /* */ + LTT_FIELD_MINOR("minor"), /* */ + LTT_FIELD_OPERATION("direction"), /* */ + LTT_FIELD_ACTION("action"), /* */ + LTT_FIELD_ID("id"), /* */ + LTT_FIELD_ADDRESS("address"), /* */ + LTT_FIELD_SYMBOL("symbol"), /* */ + LTT_FIELD_IP("ip"); /* */ + + private final String inName; + + private Fields(String name) { + this.inName = name; + } + + public String getInName() { + return this.inName; + } + }; + + public enum CpuMode { + LTTV_CPU_UNKNOWN("unknown"), /* */ + LTTV_CPU_IDLE("idle"), /* */ + LTTV_CPU_BUSY("busy"), /* */ + LTTV_CPU_IRQ("irq"), /* */ + LTTV_CPU_SOFT_IRQ("softirq"), /* */ + LTTV_CPU_TRAP("trap"); /* */ + + String inName; + + private CpuMode(String name) { + this.inName = name; + } + + public String getInName() { + return this.inName; + } + + } + + public enum IRQMode { + LTTV_IRQ_UNKNOWN("unknown"), /* */ + LTTV_IRQ_IDLE("idle"), /* */ + LTTV_IRQ_BUSY("busy"); /* */ + + String inName; + + private IRQMode(String name) { + this.inName = name; + } + + public String getInName() { + return this.inName; + } + + } + + public enum SoftIRQMode { + LTTV_SOFT_IRQ_UNKNOWN("unknown"), /* */ + LTTV_SOFT_IRQ_IDLE("idle"), /* */ + LTTV_SOFT_IRQ_PENDING("pending"), /* */ + LTTV_SOFT_IRQ_BUSY("busy"); /* */ + + String inName; + + private SoftIRQMode(String name) { + this.inName = name; + } + + public String getInName() { + return this.inName; + } + + } + + public enum BdevMode { + LTTV_BDEV_UNKNOWN("unknown"), /* */ + LTTV_BDEV_IDLE("idle"), /* */ + LTTV_BDEV_BUSY_READING("busy_reading"), /* */ + LTTV_BDEV_BUSY_WRITING("busy_writing"); /* */ + + String inName; + + private BdevMode(String name) { + this.inName = name; + } + + public String getInName() { + return this.inName; + } + + } + + public enum TrapMode { + LTTV_TRAP_UNKNOWN("unknown"), /* */ + LTTV_TRAP_IDLE("idle"), /* */ + LTTV_TRAP_BUSY("busy"); /* */ + + String inName; + + private TrapMode(String name) { + this.inName = name; + } + + public String getInName() { + return this.inName; + } + + } + public enum ProcessType { + LTTV_STATE_USER_THREAD("USER_THREAD"), /* */ + LTTV_STATE_KERNEL_THREAD("KERNEL_THREAD"); /* */ + + String inName; + + private ProcessType(String name) { + this.inName = name; + } + + public String getInName() { + return this.inName; + } + + } + + public enum ProcessStatus { + LTTV_STATE_UNNAMED("UNNAMED"), LTTV_STATE_WAIT_FORK("WAIT_FORK"), /* */ + LTTV_STATE_WAIT_CPU("WAIT_CPU"), /* */ + LTTV_STATE_EXIT("EXIT"), /* */ + LTTV_STATE_ZOMBIE("ZOMBIE"), /* */ + LTTV_STATE_WAIT("WAIT"), /* */ + LTTV_STATE_RUN("RUN"), /* */ + LTTV_STATE_DEAD("DEAD"); /* */ + + String inName; + + private ProcessStatus(String name) { + this.inName = name; + } + + public String getInName() { + return this.inName; + } + + } + + public enum ExecutionSubMode { + LTTV_STATE_SUBMODE_UNKNOWN("UNKNOWN"), /* */ + LTTV_STATE_SUBMODE_NONE("NONE"); /* */ + + String inName; + + private ExecutionSubMode(String name) { + this.inName = name; + } + + public String getInName() { + return this.inName; + } + + } + + public enum ExecutionMode { + LTTV_STATE_MODE_UNKNOWN("MODE_UNKNOWN"), /* */ + LTTV_STATE_USER_MODE("USER_MODE"), /* */ + LTTV_STATE_SYSCALL("SYSCALL"), /* */ + LTTV_STATE_TRAP("TRAP"), /* */ + LTTV_STATE_IRQ("IRQ"), /* */ + LTTV_STATE_SOFT_IRQ("SOFTIRQ"); /* */ + + String inName; + + private ExecutionMode(String name) { + this.inName = name; + } + + public String getInName() { + return this.inName; + } + + } + + public enum GenStates { + LTTV_STATE_TRACEFILES("tracefiles"), /* */ + LTTV_STATE_PROCESSES("processes"), /* */ + LTTV_STATE_PROCESS("process"), /* */ + LTTV_STATE_RUNNING_PROCESS("running_process"), /* */ + LTTV_STATE_EVENT("event"), /* */ + LTTV_STATE_SAVED_STATES("saved states"), /* */ + LTTV_STATE_SAVED_STATES_TIME("saved states time"), /* */ + LTTV_STATE_TIME("time"), /* */ + LTTV_STATE_HOOKS("saved state hooks"), /* */ + LTTV_STATE_NAME_TABLES("name tables"), /* */ + LTTV_STATE_TRACE_STATE_USE_COUNT("trace_state_use_count"), /* */ + LTTV_STATE_RESOURCE_CPUS("cpu count"), /* */ + LTTV_STATE_RESOURCE_IRQS("irq resource states"), /* */ + LTTV_STATE_RESOURCE_SOFT_IRQS("soft irq resource states"), /* */ + LTTV_STATE_RESOURCE_TRAPS("trap resource states"), /* */ + LTTV_STATE_RESOURCE_BLKDEVS("blkdevs resource states"); /* */ + + String inName; + + private GenStates(String name) { + this.inName = name; + } + + public String getInName() { + return this.inName; + } + + } + + // ======================================================================== + // Methods + // ======================================================================= + /** + * Return the string to any known event + * + * @return the eventstrmap + */ + public HashMap getEventStrmap() { + return eventStrMap; + } + + /** + * Return the string to state transition events map + * + * @return the stateTransEventMap + */ + public HashMap getStateTransEventMap() { + return stateTransEventMap; + } + + /** + * @return the mapping from int to system call names + */ + public String[] getSyscallNames() { + return syscall_names; + } + + /** + * @return the mapping from int to trap names + */ + public String[] getTrapNames() { + return trap_names; + } + + /** + * @return the mapping from int to irq names + */ + public String[] getIrqNames() { + return irq_names; + } + + /** + * @return the mapping from int to softirq name + */ + public String[] getSoftIrqNames() { + return soft_irq_names; + } + +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/AbsEventToHandlerResolver.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/AbsEventToHandlerResolver.java new file mode 100644 index 0000000000..c74626ce44 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/AbsEventToHandlerResolver.java @@ -0,0 +1,217 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 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: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.lttng.state.evProcessor; + +import java.util.Set; + +import org.eclipse.linuxtools.lttng.TraceDebug; +import org.eclipse.linuxtools.lttng.event.LttngEvent; +import org.eclipse.linuxtools.lttng.event.LttngSyntheticEvent; +import org.eclipse.linuxtools.lttng.event.LttngSyntheticEvent.SequenceInd; +import org.eclipse.linuxtools.lttng.state.model.LttngTraceState; +import org.eclipse.linuxtools.tmf.event.TmfEvent; + +/** + * @author alvaro + * + */ +public abstract class AbsEventToHandlerResolver implements + IEventToHandlerResolver, ITransEventProcessor { + + Long fbeforeEventCount = 0L; + Long fstateUpdateCount = 0L; + Long filteredOutEventsCount = 0L; + + /* (non-Javadoc) + * @see org.eclipse.linuxtools.lttng.state.evProcessor.IEventToHandlerResolver#getBeforeProcessor(java.lang.String) + */ + public abstract ILttngEventProcessor getBeforeProcessor(String eventType); + + /* (non-Javadoc) + * @see org.eclipse.linuxtools.lttng.state.evProcessor.IEventToHandlerResolver#getAfterProcessor(java.lang.String) + */ + public abstract ILttngEventProcessor getAfterProcessor(String eventType); + + /* (non-Javadoc) + * @see org.eclipse.linuxtools.lttng.state.evProcessor.IEventToHandlerResolver#getfinishProcessor() + */ + public abstract ILttngEventProcessor getfinishProcessor(); + + /* (non-Javadoc) + * @see org.eclipse.linuxtools.lttng.state.evProcessor.IEventToHandlerResolver#getStateUpdaterProcessor(java.lang.String) + */ + public abstract ILttngEventProcessor getStateUpdaterProcessor( + String eventType); + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.linuxtools.lttng.state.evProcessor.ILttngEventProcessor#process + * (org.eclipse.linuxtools.lttng.event.LttngEvent, + * org.eclipse.linuxtools.lttng.state.model.LttngTraceState) + */ + /* + * (non-Javadoc) + * + * @see + * org.eclipse.linuxtools.lttng.state.evProcessor.ILttngEventProcessor#process + * (org.eclipse.linuxtools.lttng.event.LttngEvent, + * org.eclipse.linuxtools.lttng.state.model.LttngTraceState) + */ + public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) { + if (trcEvent instanceof LttngSyntheticEvent) { + + // prepare to dispatch synthetic events to its corresponding handler + LttngSyntheticEvent synEvent = (LttngSyntheticEvent) trcEvent; + ILttngEventProcessor processor = null; + + // Status indicators do not contain a valid marker name + if (synEvent.getSynType() == SequenceInd.STARTREQ) { + reset(); + return false; + } + + if (synEvent.getSynType() == SequenceInd.ENDREQ) { + processor = getfinishProcessor(); + TraceDebug.debug("EndRequest satus received:"); + } else { + // valid marker name expected + String eventType = synEvent.getMarkerName(); + + if (synEvent.getSynType() == SequenceInd.BEFORE) { + processor = getBeforeProcessor(eventType); + // increment event count only for one sequence indicator, + // Note: BEFORE is selected to be used as an indicator to + // prevent duplicated updates in the state system + incrementBeforeEventCount(); + } + + if (synEvent.getSynType() == SequenceInd.UPDATE) { + processor = getStateUpdaterProcessor(eventType); + incrementStateUpdateCount(); + } + + if (synEvent.getSynType() == SequenceInd.AFTER) { + processor = getAfterProcessor(eventType); + } + + // TODO: Implement filter of events not associated to this trace + // Make sure the event received is associated to this trace + // handling context + if (traceSt != null + && trcEvent.getParentTrace() != traceSt.getContext() + .getTraceIdRef()) { + // increment the number of events filtered out + filteredOutEventsCount++; + return false; + } + } + + if (processor != null) { + processor.process(trcEvent, traceSt); + } + } + + return true; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.linuxtools.lttng.state.evProcessor.IBaseEventProcessor#process + * (org.eclipse.linuxtools.tmf.event.TmfEvent, + * org.eclipse.linuxtools.lttng.state.model.LttngTraceState) + */ + public void process(TmfEvent tmfEvent, LttngTraceState traceSt) { + if (tmfEvent == null) { + return; + } + + if (!(tmfEvent instanceof LttngSyntheticEvent)) { + TraceDebug + .debug("The event received is not an instance of LttngSyntheticEvent and can not be processed"); + return; + } + + LttngSyntheticEvent trcEvent = (LttngSyntheticEvent) tmfEvent; + + process(trcEvent, traceSt); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.linuxtools.lttng.state.evProcessor.IBaseEventProcessor# + * getEventsNotHandled() + */ + public Set getEventsNotHandled() { + return null; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.linuxtools.lttng.state.evProcessor.ITransEventProcessor# + * getEventCount() + */ + public Long getBeforeEventCount() { + return fbeforeEventCount; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.linuxtools.lttng.state.evProcessor.ITransEventProcessor# + * getStateUpdateCount() + */ + public Long getStateUpdateCount() { + return fstateUpdateCount; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.linuxtools.lttng.state.evProcessor.ITransEventProcessor# + * getFilteredOutEventCount() + */ + public Long getFilteredOutEventCount() { + return filteredOutEventsCount; + } + + /** + *

+ * Initialise counter values, e.g before new requests + *

+ */ + protected void reset() { + fbeforeEventCount = 0L; + fstateUpdateCount = 0L; + filteredOutEventsCount = 0L; + } + + /** + * Multi-threading not expected + */ + protected void incrementBeforeEventCount() { + fbeforeEventCount++; + } + + /** + * Multi-threading not expected + */ + protected void incrementStateUpdateCount() { + fstateUpdateCount++; + } +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/EventProcessorProxy.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/EventProcessorProxy.java new file mode 100644 index 0000000000..272c5725f7 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/EventProcessorProxy.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright (c) 2009 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: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.lttng.state.evProcessor; + +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.linuxtools.lttng.TraceDebug; +import org.eclipse.linuxtools.lttng.state.evProcessor.state.StateEventToHandlerFactory; + +/** + * @author alvaro + * + */ +public class EventProcessorProxy { + // ======================================================================== + // Data + // ======================================================================= + private static EventProcessorProxy instance = null; + private final Set processingFactories = new HashSet(); + + + // ======================================================================== + // Constructors + // ======================================================================= + public EventProcessorProxy() { + // Manual creation of State update factory + addEventProcessorFactory(StateEventToHandlerFactory.getInstance()); + } + + // ======================================================================== + // Methods + // ======================================================================= + /** + * @return the processingFactories + */ + public Set getProcessingFactories() { + return processingFactories; + } + + /** + * Returns this singleton + * + * @return + */ + public static EventProcessorProxy getInstance() { + if (instance == null) { + instance = new EventProcessorProxy(); + } + + return instance; + } + + /** + * Register a factory of event handler methods, each factory provides a map + * to Before and After state update handlers + * + * @param handlersFactory + */ + public void addEventProcessorFactory( + AbsEventToHandlerResolver handlersFactory) { + if (handlersFactory != null) { + //only add the listener if not already included + if (!processingFactories.contains(handlersFactory)) { + processingFactories.add(handlersFactory); + } + } else { + TraceDebug + .debug("An attempt to register a null factory has been detected"); + } + } + + /** + * Remove a factory previously added with addEventProcessorFactory + * + * @param handlersFactory + */ + public void removeEventProcessorFactory( + IEventToHandlerResolver handlersFactory) { + if (handlersFactory != null) { + processingFactories.remove(handlersFactory); + } + } + +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/IBaseEventProcessor.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/IBaseEventProcessor.java new file mode 100644 index 0000000000..13c42a995c --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/IBaseEventProcessor.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2010 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: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.linuxtools.lttng.state.evProcessor; + +import org.eclipse.linuxtools.lttng.state.model.LttngTraceState; +import org.eclipse.linuxtools.tmf.event.TmfEvent; + +public interface IBaseEventProcessor { + + /** + * Base event handler, either dispatcher or actual handler + * + * @param tmfEvent + * @param traceSt + */ + public abstract void process(TmfEvent tmfEvent, LttngTraceState traceSt); + +} \ No newline at end of file diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/IEventToHandlerResolver.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/IEventToHandlerResolver.java new file mode 100644 index 0000000000..7d1de8c8b9 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/IEventToHandlerResolver.java @@ -0,0 +1,34 @@ +package org.eclipse.linuxtools.lttng.state.evProcessor; + +public interface IEventToHandlerResolver { + + /** + * + * @return The Event Handler for received event before the State data model + * is updated. + */ + public abstract ILttngEventProcessor getBeforeProcessor(String eventType); + + /** + * + * @return The Event Handler for received event after the State data model + * is updated. + */ + public abstract ILttngEventProcessor getAfterProcessor(String eventType); + + /** + * + * @return The Event Handler after the complete read request is completed, + * needed e.g. to draw the last state + */ + public abstract ILttngEventProcessor getfinishProcessor(); + + /** + * + * @return The Event Handler for received event in charge to update the + * state. Only one handler is expected so other factories must not + * override this method. + */ + public abstract ILttngEventProcessor getStateUpdaterProcessor(String eventType); + +} \ No newline at end of file diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/ILttngEventProcessor.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/ILttngEventProcessor.java new file mode 100644 index 0000000000..67ac6bf054 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/ILttngEventProcessor.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 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: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.linuxtools.lttng.state.evProcessor; + +import org.eclipse.linuxtools.lttng.event.LttngEvent; +import org.eclipse.linuxtools.lttng.state.model.LttngTraceState; + +/** + * @author alvaro + * + */ +public interface ILttngEventProcessor { + + // ======================================================================== + // Abstract methods + // ======================================================================= + /** + * Implementors will either dispatch or determine the handler of the event + * provided + * + * @param trcEvent + * @param traceSt + * @return + */ + public abstract boolean process(LttngEvent trcEvent, LttngTraceState traceSt); + +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/ITransEventProcessor.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/ITransEventProcessor.java new file mode 100644 index 0000000000..9ae9a24b38 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/ITransEventProcessor.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2010 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: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.linuxtools.lttng.state.evProcessor; + +/** + * @author alvaro + * + */ +public interface ITransEventProcessor extends IBaseEventProcessor, + ILttngEventProcessor { + + /** + * @return the eventCount + */ + public Long getBeforeEventCount(); + + /** + * @return the stateUpdateCount + */ + public Long getStateUpdateCount(); + + /** + * @return the count of filtered out events e.g. event received from a trace + * not matching the trace state system + */ + public Long getFilteredOutEventCount(); + +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/state/AbsStateProcessing.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/state/AbsStateProcessing.java new file mode 100644 index 0000000000..6126b9b24c --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/state/AbsStateProcessing.java @@ -0,0 +1,209 @@ +/** + * + */ +package org.eclipse.linuxtools.lttng.state.evProcessor.state; + +import org.eclipse.linuxtools.lttng.TraceDebug; +import org.eclipse.linuxtools.lttng.event.LttngEvent; +import org.eclipse.linuxtools.lttng.event.LttngEventContent; +import org.eclipse.linuxtools.lttng.event.LttngEventField; +import org.eclipse.linuxtools.lttng.state.StateStrings.Fields; +import org.eclipse.linuxtools.lttng.state.model.LttngProcessState; +import org.eclipse.linuxtools.lttng.state.model.LttngTraceState; +import org.eclipse.linuxtools.tmf.event.TmfEventField; + +/** + * Common utility methods for all state processing handlers, not intended to be + * instantiated on its own + * + * @author alvaro + * + */ +public abstract class AbsStateProcessing { + + /** + * protected method used when a Field is requested among several available + * fields and the expected type is Long + * + * @param trcEvent + * @param traceSt + * @param expectedNumFields + * @return + */ + protected Long getAFieldLong(LttngEvent trcEvent, LttngTraceState traceSt, Fields expectedField) { + Long fieldVal = 0L; + + String fieldname = expectedField.getInName(); + LttngEventField field = ((LttngEventContent) trcEvent.getContent()).getField(fieldname); + + if ( field == null ) { + TraceDebug.debug("***************** CONTENT : " + ((LttngEventContent) trcEvent.getContent()).toString()); + } + else { + Object fieldObj = field.getValue(); + if ( (fieldObj instanceof Long) || (fieldObj instanceof Integer) ) { + // Expected numeric value found + fieldVal = (Long) field.getValue(); + } + else { + if (TraceDebug.isDEBUG()) { + TraceDebug.debug("Unexpected field Type. Expected: Long, Received: "+ fieldObj.getClass().getSimpleName()); + } + } + } + + /* + // TmfEventField[] fields = trcEvent.getContent().getFields(); + TmfEventField[] fields = ((LttngEventContent) trcEvent.getContent()) + .getFields(trcEvent); + + // At least one field expected + if (fields.length == 0) { + TraceDebug.debug("Unexpected number of fields received: " + + fields.length); + return null; + } + + LttngEventField field; + String fieldname; + String expectedFieldName = expectedField.getInName(); + for (int i = 0; i < fields.length; i++) { + field = (LttngEventField) fields[i]; + fieldname = field.getName(); + if (fieldname.equals(expectedFieldName)) { + Object fieldObj = field.getValue(); + if (fieldObj instanceof Long) { + // Expected value found + fieldVal = (Long) field.getValue(); + // if (expectedField == Fields.LTT_FIELD_TYPE) { + // TraceDebug.debug("Field Type value is: " + fieldVal); + // } + break; + } else { + if (TraceDebug.isDEBUG()) { + TraceDebug + .debug("Unexpected field Type. Expected: Long, Received: " + + fieldObj.getClass().getSimpleName()); + } + return null; + } + } + } + */ + +// if (fieldVal == null) { +// if (TraceDebug.isDEBUG()) { +// sendNoFieldFoundMsg(((LttngEventContent) trcEvent.getContent()).getFields(), fieldname); +// } +// } + return fieldVal; + } + + /** + * protected method used when a Field is requested among several available + * fields and the expected type is String + * + * @param trcEvent + * @param traceSt + * @param expectedNumFields + * @return + */ + protected String getAFieldString(LttngEvent trcEvent, + LttngTraceState traceSt, Fields expectedField) { + String fieldVal = ""; + + String fieldname = expectedField.getInName(); + LttngEventField field = ((LttngEventContent) trcEvent.getContent()).getField(fieldname); + + if ( field == null ) { + TraceDebug.debug("***************** CONTENT : " + ((LttngEventContent) trcEvent.getContent()).toString()); + } + else { + Object fieldObj = field.getValue(); + if (fieldObj instanceof String) { + // Expected numeric value found + fieldVal = (String) field.getValue(); + } + else { + if (TraceDebug.isDEBUG()) { + TraceDebug.debug("Unexpected field Type. Expected: String, Received: "+ fieldObj.getClass().getSimpleName()); + } + } + } + + /* + // TmfEventField[] fields = trcEvent.getContent().getFields(); + TmfEventField[] fields = ((LttngEventContent) trcEvent.getContent()) + .getFields(trcEvent); + + // Only one field expected + if (fields.length == 0) { + TraceDebug.debug("Unexpected number of fields received: " + + fields.length); + return null; + } + + LttngEventField field; + String fieldname; + String expectedFieldName = expectedField.getInName(); + for (int i = 0; i < fields.length; i++) { + field = (LttngEventField) fields[i]; + fieldname = field.getName(); + if (fieldname.equals(expectedFieldName)) { + Object fieldObj = field.getValue(); + if (fieldObj instanceof String) { + // Expected value found + fieldVal = (String) field.getValue(); + break; + } else { + if (TraceDebug.isDEBUG()) { + TraceDebug + .debug("Unexpected field Type. Expected: String, Received: " + + fieldObj.getClass().getSimpleName()); + } + return null; + } + } + } + */ + +// if (fieldVal == null) { +// if (TraceDebug.isDEBUG()) { +// sendNoFieldFoundMsg(((LttngEventContent) trcEvent.getContent()).getFields(), fieldname); +// } +// } + return fieldVal; + } + + /** + * Find the process matching the given pid and cpu + * + * If cpu is 0, the cpu value is not matched and the selection is based on + * pid value only + * + * @param traceState + * @param cpu + * @param pid + * @return + */ + protected LttngProcessState lttv_state_find_process( + LttngTraceState traceState, Long cpu, Long pid) { + + return traceState.findProcessState(pid, cpu, traceState.getTraceId()); + } + + protected void sendNoFieldFoundMsg(TmfEventField[] fields, + String expectedFieldName) { + LttngEventField field; + StringBuilder sb = new StringBuilder("Field not found, requested: " + + expectedFieldName); + sb.append(" number of fields: " + fields.length + "Fields: "); + for (int i = 0; i < fields.length; i++) { + field = (LttngEventField) fields[i]; + sb.append(field.getId() + " "); + } + + TraceDebug.debug(sb.toString(), 5); + } + +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/state/AbsStateUpdate.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/state/AbsStateUpdate.java new file mode 100644 index 0000000000..2acc221d07 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/state/AbsStateUpdate.java @@ -0,0 +1,250 @@ +/******************************************************************************* + * Copyright (c) 2009 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: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.linuxtools.lttng.state.evProcessor.state; + + +import org.eclipse.linuxtools.lttng.TraceDebug; +import org.eclipse.linuxtools.lttng.event.LttngEvent; +import org.eclipse.linuxtools.lttng.state.StateStrings; +import org.eclipse.linuxtools.lttng.state.StateStrings.ExecutionMode; +import org.eclipse.linuxtools.lttng.state.StateStrings.IRQMode; +import org.eclipse.linuxtools.lttng.state.StateStrings.ProcessStatus; +import org.eclipse.linuxtools.lttng.state.evProcessor.ILttngEventProcessor; +import org.eclipse.linuxtools.lttng.state.model.LTTngCPUState; +import org.eclipse.linuxtools.lttng.state.model.LttngBdevState; +import org.eclipse.linuxtools.lttng.state.model.LttngExecutionState; +import org.eclipse.linuxtools.lttng.state.model.LttngIRQState; +import org.eclipse.linuxtools.lttng.state.model.LttngProcessState; +import org.eclipse.linuxtools.lttng.state.model.LttngTraceState; +import org.eclipse.linuxtools.tmf.event.TmfTimestamp; + +public abstract class AbsStateUpdate extends AbsStateProcessing implements + ILttngEventProcessor { + + // ======================================================================== + // Data + // ======================================================================= + protected static final Long ANY_CPU = 0L; + + // ======================================================================== + // push and pop from stack + // ======================================================================= + protected void push_state(Long cpu, StateStrings.ExecutionMode execMode, + String submode, TmfTimestamp eventTime, LttngTraceState traceSt) { + + LttngProcessState process = traceSt.getRunning_process().get(cpu); + LttngExecutionState exe_state = new LttngExecutionState(); + exe_state.setExec_mode(execMode); + exe_state.setExec_submode(submode); + exe_state.setEntry_Time(eventTime.getValue()); + exe_state.setChange_Time(eventTime.getValue()); + exe_state.setCum_cpu_time(0L); + exe_state.setProc_status(process.getState().getProc_status()); + process.pushToExecutionStack(exe_state); + } + + protected void pop_state(Long cpu, StateStrings.ExecutionMode execMode, + LttngTraceState traceSt, TmfTimestamp eventTime) { + + LttngProcessState process = traceSt.getRunning_process().get(cpu); + + if (!process.getState().getExec_mode().equals(execMode)) { + // Different execution mode + TraceDebug.debug("Different Execution Mode type \n\tTime:" + + eventTime.toString() + "\n\tprocess state has: \n\t" + + process.getState().getExec_mode().toString() + + "\n\twhen pop_int is:\n\t" + execMode.toString()); + return; + } + + //The process state is updated within the pop method + process.popFromExecutionStack(); + process.getState().setChange_Time(eventTime.getValue()); + } + + protected void irq_push_mode(LttngIRQState irqst, IRQMode state) { + irqst.pushToIrqStack(state); + } + + protected void irq_set_base_mode(LttngIRQState irqst, IRQMode state) { + irqst.clearAndSetBaseToIrqStack(state); + } + + protected void irq_pop_mode(LttngIRQState irqst) { + irqst.popFromIrqStack(); + } + + protected void cpu_push_mode(LTTngCPUState cpust, StateStrings.CpuMode state) { + // The initialization (init) creates a LttngCPUState instance per + // available cpu in the system + cpust.pushToCpuStack(state); + } + + protected void cpu_pop_mode(LTTngCPUState cpust) { + cpust.popFromCpuStack(); + } + + /* clears the stack and sets the state passed as argument */ + protected void cpu_set_base_mode(LTTngCPUState cpust, + StateStrings.CpuMode state) { + cpust.clearAndSetBaseToCpuStack(state); + } + + protected void bdev_pop_mode(LttngBdevState bdevst) { + bdevst.popFromBdevStack(); + } + + /** + * Push a new received function pointer to the user_stack + * + * @param traceSt + * @param funcptr + * @param cpu + */ + protected void push_function(LttngTraceState traceSt, Long funcptr, Long cpu) { + // Get the related process + LttngProcessState process = traceSt.getRunning_process().get(cpu); + + // update stack + process.pushToUserStack(funcptr); + + // update the pointer to the current function on the corresponding + // process + process.setCurrent_function(funcptr); + } + + protected void pop_function(LttngTraceState traceSt, LttngEvent trcEvent, + Long funcptr) { + Long cpu = trcEvent.getCpuId(); + LttngProcessState process = traceSt.getRunning_process().get(cpu); + Long curr_function = process.getCurrent_function(); + + if (curr_function != null && curr_function != funcptr) { + TraceDebug.debug("Different functions: " + funcptr + " current: " + + curr_function + " time stamp: " + + trcEvent.getTimestamp().toString()); + + // g_info("Different functions (%lu.%09lu): ignore it\n", + // tfs->parent.timestamp.tv_sec, tfs->parent.timestamp.tv_nsec); + // g_info("process state has %" PRIu64 " when pop_function is %" + // PRIu64 + // "\n", + // process->current_function, funcptr); + // g_info("{ %u, %u, %s, %s, %s }\n", + // process->pid, + // process->ppid, + // g_quark_to_string(process->name), + // g_quark_to_string(process->brand), + // g_quark_to_string(process->state->s)); + return; + } + + process.popFromUserStack(); + process.setCurrent_function(process.peekFromUserStack()); + } + + // ======================================================================== + // General methods + // ======================================================================= + // Adaption from MKDEV macro + protected Long mkdev(Long major, Long minor) { + Long result = null; + if (major != null && minor != null) { + result = (major << 20) | minor; + } + return result; + } + + /* + * FIXME : this function should be called when we receive an event telling + * that release_task has been called in the kernel. In happens generally + * when the parent waits for its child termination, but may also happen in + * special cases in the child's exit : when the parent ignores its children + * SIGCCHLD or has the flag SA_NOCLDWAIT. It can also happen when the child + * is part of a killed thread group, but isn't the leader. + */ + protected boolean exit_process(LttngTraceState ts, LttngProcessState process) { + /* + * Wait for both schedule with exit dead and process free to happen. + * They can happen in any order. + */ + process.incrementFree_events(); + if (process.getFree_events() < 2) { + return false; + } + + process.clearExecutionStack(); + process.clearUserStack(); + ts.removeProcessState(process); + + return true; + } + + /** + * @param traceSt + * @param cpu + * @param pid + * @param tgid + * @param timestamp + * @return + */ + protected LttngProcessState create_process(LttngTraceState traceSt, + Long cpu, Long pid, Long tgid, final TmfTimestamp timestamp) { + LttngProcessState process = create_process(traceSt, cpu, pid, tgid, + ProcessStatus.LTTV_STATE_UNNAMED.getInName(), timestamp); + return process; + } + + /** + * @param traceSt + * @param cpu + * @param pid + * @param tgid + * @param name + * @param timestamp + * @return + */ + protected LttngProcessState create_process(LttngTraceState traceSt, + Long cpu, Long pid, Long tgid, String name, + final TmfTimestamp timestamp) { + LttngProcessState process; + process = new LttngProcessState(cpu, pid, tgid, name, timestamp.getValue(), traceSt.getTraceId()); + traceSt.addProcessState(process); + return process; + } + + /** + * @param ts + * @param cpu + * @param pid + * @param timestamp + * , Used when a new process is needed + * @return + */ + protected LttngProcessState lttv_state_find_process_or_create( + LttngTraceState ts, Long cpu, Long pid, final TmfTimestamp timestamp) { + + LttngProcessState process = lttv_state_find_process(ts, cpu, pid); + /* Put ltt_time_zero creation time for non existing processes */ + if (process == null) { + process = create_process(ts, cpu, pid, 0L, timestamp); + // leave only one entry in the execution stack + process.popFromExecutionStack(); + LttngExecutionState es = process.getState(); + es.setExec_mode(ExecutionMode.LTTV_STATE_MODE_UNKNOWN); + es.setProc_status(ProcessStatus.LTTV_STATE_UNNAMED); + } + + return process; + } + +} \ No newline at end of file diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/state/StateEventToHandlerFactory.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/state/StateEventToHandlerFactory.java new file mode 100644 index 0000000000..9265ac7ed5 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/state/StateEventToHandlerFactory.java @@ -0,0 +1,184 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 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: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.linuxtools.lttng.state.evProcessor.state; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.linuxtools.lttng.state.StateStrings; +import org.eclipse.linuxtools.lttng.state.evProcessor.AbsEventToHandlerResolver; +import org.eclipse.linuxtools.lttng.state.evProcessor.ILttngEventProcessor; + +/** + * Builds a Map from string event name to a processing handler object, the + * processors implement the same interface to facilitate transparent methods + * call, + * + * The map key STring is the entry point of the raw events, using a hash speeds + * up the resolution of the appropriate processor + * + * @author alvaro + * + */ +public class StateEventToHandlerFactory extends AbsEventToHandlerResolver { + // ======================================================================== + // Data + // ======================================================================= + private final Map eventNametoStateProcessor = new HashMap(); + private final static StateEventToHandlerFactory instance = new StateEventToHandlerFactory(); + private StateUpdateHandlers instantiateHandler = new StateUpdateHandlers(); + + // ======================================================================== + // Constructors + // ======================================================================= + protected StateEventToHandlerFactory() { + //create one instance of each individual event handler and add the instance to the map + eventNametoStateProcessor.put(StateStrings.Events.LTT_EVENT_SYSCALL_ENTRY + .getInName(), instantiateHandler.getSyscallEntryHandler()); + + eventNametoStateProcessor.put(StateStrings.Events.LTT_EVENT_SYSCALL_EXIT + .getInName(), instantiateHandler.getsySyscallExitHandler()); + + eventNametoStateProcessor.put(StateStrings.Events.LTT_EVENT_TRAP_ENTRY + .getInName(), instantiateHandler.getTrapEntryHandler()); + + eventNametoStateProcessor.put(StateStrings.Events.LTT_EVENT_TRAP_EXIT + .getInName(), instantiateHandler.getTrapExitHandler()); + + eventNametoStateProcessor.put(StateStrings.Events.LTT_EVENT_PAGE_FAULT_ENTRY + .getInName(), instantiateHandler.getTrapEntryHandler()); + + eventNametoStateProcessor.put(StateStrings.Events.LTT_EVENT_PAGE_FAULT_EXIT + .getInName(), instantiateHandler.getTrapExitHandler()); + + eventNametoStateProcessor.put(StateStrings.Events.LTT_EVENT_PAGE_FAULT_NOSEM_ENTRY + .getInName(), instantiateHandler.getTrapEntryHandler()); + + eventNametoStateProcessor.put(StateStrings.Events.LTT_EVENT_PAGE_FAULT_NOSEM_EXIT + .getInName(), instantiateHandler.getTrapExitHandler()); + + eventNametoStateProcessor.put(StateStrings.Events.LTT_EVENT_IRQ_ENTRY + .getInName(), instantiateHandler.getIrqEntryHandler()); + + eventNametoStateProcessor.put(StateStrings.Events.LTT_EVENT_IRQ_EXIT + .getInName(), instantiateHandler.getIrqExitHandler()); + + eventNametoStateProcessor.put(StateStrings.Events.LTT_EVENT_SOFT_IRQ_RAISE + .getInName(), instantiateHandler.getSoftIrqRaiseHandler()); + + eventNametoStateProcessor.put(StateStrings.Events.LTT_EVENT_SOFT_IRQ_ENTRY + .getInName(), instantiateHandler.getSoftIrqEntryHandler()); + + eventNametoStateProcessor.put(StateStrings.Events.LTT_EVENT_SOFT_IRQ_EXIT + .getInName(), instantiateHandler.getSoftIrqExitHandler()); + + eventNametoStateProcessor.put(StateStrings.Events.LTT_EVENT_LIST_INTERRUPT + .getInName(), instantiateHandler.getEnumInterruptHandler()); + + eventNametoStateProcessor.put(StateStrings.Events.LTT_EVENT_REQUEST_ISSUE + .getInName(), instantiateHandler.getBdevRequestIssueHandler()); + + eventNametoStateProcessor.put(StateStrings.Events.LTT_EVENT_REQUEST_COMPLETE + .getInName(), instantiateHandler.getBdevRequestCompleteHandler()); + + eventNametoStateProcessor.put(StateStrings.Events.LTT_EVENT_FUNCTION_ENTRY + .getInName(), instantiateHandler.getFunctionEntryHandler()); + + eventNametoStateProcessor.put(StateStrings.Events.LTT_EVENT_FUNCTION_EXIT + .getInName(), instantiateHandler.getFunctionExitHandler()); + + eventNametoStateProcessor.put(StateStrings.Events.LTT_EVENT_SYS_CALL_TABLE + .getInName(), instantiateHandler.getDumpSyscallHandler()); + + eventNametoStateProcessor.put(StateStrings.Events.LTT_EVENT_KPROBE_TABLE + .getInName(), instantiateHandler.getDumpKprobeHandler()); + + eventNametoStateProcessor.put(StateStrings.Events.LTT_EVENT_SOFTIRQ_VEC + .getInName(), instantiateHandler.getDumpSoftIrqHandler()); + + eventNametoStateProcessor.put(StateStrings.Events.LTT_EVENT_SCHED_SCHEDULE + .getInName(), instantiateHandler.getSchedChangeHandler()); + + eventNametoStateProcessor.put(StateStrings.Events.LTT_EVENT_PROCESS_FORK + .getInName(), instantiateHandler.getProcessForkHandler()); + + eventNametoStateProcessor.put(StateStrings.Events.LTT_EVENT_KTHREAD_CREATE + .getInName(), instantiateHandler.getProcessKernelThreadHandler()); + + eventNametoStateProcessor.put(StateStrings.Events.LTT_EVENT_PROCESS_EXIT + .getInName(), instantiateHandler.getProcessExitHandler()); + + eventNametoStateProcessor.put(StateStrings.Events.LTT_EVENT_PROCESS_FREE + .getInName(), instantiateHandler.getProcessFreeHandler()); + + eventNametoStateProcessor.put(StateStrings.Events.LTT_EVENT_EXEC + .getInName(), instantiateHandler.getProcessExecHandler()); + + eventNametoStateProcessor.put(StateStrings.Events.LTT_EVENT_THREAD_BRAND + .getInName(), instantiateHandler.GetThreadBrandHandler()); + + eventNametoStateProcessor.put(StateStrings.Events.LTT_EVENT_STATEDUMP_END + .getInName(), instantiateHandler.getStateDumpEndHandler()); + + eventNametoStateProcessor.put(StateStrings.Events.LTT_EVENT_PROCESS_STATE + .getInName(), instantiateHandler.getEnumProcessStateHandler()); + + + } + + // ======================================================================== + // Public methods + // ======================================================================= + /** + * The event processors are common to all traces an multiple instances will + * use more memory unnecessarily + * + * @return + */ + public static AbsEventToHandlerResolver getInstance() { + return instance; + } + + + /* (non-Javadoc) + * @see org.eclipse.linuxtools.lttng.state.evProcessor.AbsEventProcessorFactory#getAfterProcessor(java.lang.String) + */ + @Override + public ILttngEventProcessor getAfterProcessor(String eventType) { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.linuxtools.lttng.state.evProcessor.AbsEventProcessorFactory#getBeforeProcessor(java.lang.String) + */ + @Override + public ILttngEventProcessor getBeforeProcessor(String eventType) { + return null; + } + + /** + * This is the only event handler to update the State provider + * @return + * + */ + @Override + public ILttngEventProcessor getStateUpdaterProcessor(String eventType) { + return eventNametoStateProcessor.get(eventType); + } + + @Override + public ILttngEventProcessor getfinishProcessor() { + // No finishing processor used + return null; + } + +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/state/StateUpdateHandlers.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/state/StateUpdateHandlers.java new file mode 100644 index 0000000000..d15b200831 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/state/StateUpdateHandlers.java @@ -0,0 +1,1543 @@ +/******************************************************************************* + * Copyright (c) 2009 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: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.linuxtools.lttng.state.evProcessor.state; + +import java.util.Map; + +import org.eclipse.linuxtools.lttng.TraceDebug; +import org.eclipse.linuxtools.lttng.event.LttngEvent; +import org.eclipse.linuxtools.lttng.state.StateStrings; +import org.eclipse.linuxtools.lttng.state.StateStrings.BdevMode; +import org.eclipse.linuxtools.lttng.state.StateStrings.CpuMode; +import org.eclipse.linuxtools.lttng.state.StateStrings.Events; +import org.eclipse.linuxtools.lttng.state.StateStrings.ExecutionMode; +import org.eclipse.linuxtools.lttng.state.StateStrings.ExecutionSubMode; +import org.eclipse.linuxtools.lttng.state.StateStrings.Fields; +import org.eclipse.linuxtools.lttng.state.StateStrings.IRQMode; +import org.eclipse.linuxtools.lttng.state.StateStrings.ProcessStatus; +import org.eclipse.linuxtools.lttng.state.StateStrings.ProcessType; +import org.eclipse.linuxtools.lttng.state.evProcessor.ILttngEventProcessor; +import org.eclipse.linuxtools.lttng.state.model.LTTngCPUState; +import org.eclipse.linuxtools.lttng.state.model.LttngBdevState; +import org.eclipse.linuxtools.lttng.state.model.LttngExecutionState; +import org.eclipse.linuxtools.lttng.state.model.LttngIRQState; +import org.eclipse.linuxtools.lttng.state.model.LttngProcessState; +import org.eclipse.linuxtools.lttng.state.model.LttngSoftIRQState; +import org.eclipse.linuxtools.lttng.state.model.LttngTraceState; +import org.eclipse.linuxtools.lttng.state.model.LttngTrapState; +import org.eclipse.linuxtools.tmf.event.TmfTimestamp; + +/** + * Wraps the creation of individual handlers, each method creates and instance + * of the corresponding handler + * + * @author alvaro + * + */ +class StateUpdateHandlers { + + final ILttngEventProcessor getSyscallEntryHandler() { + AbsStateUpdate handler = new AbsStateUpdate() { + + // @Override + public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) { + + Long cpu = trcEvent.getCpuId(); + + // No syscall_entry update for initialization process + LttngProcessState process = traceSt.getRunning_process().get( + cpu); + if ((process != null) && (process.getPid() != null) + && (process.getPid().longValue() == 0L)) { + return true; + } + + // Get the expected event field + Long syscall = getAFieldLong(trcEvent, traceSt, + Fields.LTT_FIELD_SYSCALL_ID); + + String submode = null; + if (syscall == null) { + TraceDebug + .debug("Syscall Field not found, traceVent time: " + + trcEvent.getTimestamp()); + } else { + submode = traceSt.getSyscall_names().get(syscall); + } + + if (submode == null) { + submode = ExecutionSubMode.LTTV_STATE_SUBMODE_UNKNOWN + .getInName(); + } + + push_state(cpu, StateStrings.ExecutionMode.LTTV_STATE_SYSCALL, + submode, trcEvent.getTimestamp(), traceSt); + return false; + } + }; + return handler; + } + + final ILttngEventProcessor getsySyscallExitHandler() { + AbsStateUpdate handler = new AbsStateUpdate() { + + // @Override + public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) { + + Long cpu = trcEvent.getCpuId(); + LttngProcessState process = traceSt.getRunning_process().get( + cpu); + + // No syscall_entry update for initialization process + if ((process != null) && (process.getPid() != null) + && (process.getPid().longValue() == 0L)) { + return true; + } + + pop_state(cpu, StateStrings.ExecutionMode.LTTV_STATE_SYSCALL, + traceSt, trcEvent.getTimestamp()); + return false; + + } + }; + return handler; + } + + /** + * Update stacks related to the parsing of an LttngEvent + * + * @return + */ + final ILttngEventProcessor getTrapEntryHandler() { + AbsStateUpdate handler = new AbsStateUpdate() { + + // @Override + public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) { + Long cpu = trcEvent.getCpuId(); + + Long trap = getAFieldLong(trcEvent, traceSt, + Fields.LTT_FIELD_TRAP_ID); + if (trap == null) { + TraceDebug + .debug("Trap field could not be found, event time: " + + trcEvent.getTimestamp()); + return true; + } + + // ready the trap submode name + String submode = traceSt.getTrap_names().get(trap); + + if (submode == null) { + submode = ExecutionSubMode.LTTV_STATE_SUBMODE_UNKNOWN + .getInName(); + } + + /* update process state */ + push_state(cpu, StateStrings.ExecutionMode.LTTV_STATE_TRAP, + submode, trcEvent.getTimestamp(), traceSt); + + /* update cpu status */ + LTTngCPUState cpust = traceSt.getCpu_states().get(cpu); + cpu_push_mode(cpust, StateStrings.CpuMode.LTTV_CPU_TRAP); + cpust.pushToTrapStack(trap); /* update trap status */ + + // update Trap State + LttngTrapState trap_state = null; + trap_state = traceSt.getTrap_states().get(trap); + + // If the trape_state exists, just increment it's counter, + // otherwise, create it + if ( trap_state == null ) { + trap_state = new LttngTrapState(); + trap_state.incrementRunning(); + traceSt.getTrap_states().put(trap, trap_state); + } + else { + trap_state.incrementRunning(); + } + + return false; + + } + }; + return handler; + } + + /** + * + * @return + */ + final ILttngEventProcessor getTrapExitHandler() { + AbsStateUpdate handler = new AbsStateUpdate() { + + // @Override + public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) { + + Long cpu = trcEvent.getCpuId(); + LTTngCPUState cpust = traceSt.getCpu_states().get(cpu); + Long trap = cpust.popFromTrapStack(); + + /* update process state */ + pop_state(cpu, ExecutionMode.LTTV_STATE_TRAP, traceSt, trcEvent + .getTimestamp()); + + /* update cpu status */ + cpu_pop_mode(cpust); + + if (trap != -1L) { + traceSt.getTrap_states().get(trap).decrementRunning(); + } + // else { + // TraceDebug.debug("remove this line"); + // } + + return false; + + } + }; + return handler; + } + + /** + * + * @return + */ + final ILttngEventProcessor getIrqEntryHandler() { + AbsStateUpdate handler = new AbsStateUpdate() { + + // @Override + public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) { + + Long cpu = trcEvent.getCpuId(); + + Long irq = getAFieldLong(trcEvent, traceSt, + Fields.LTT_FIELD_IRQ_ID); + if (irq == null || traceSt.getIrq_states().get(irq) == null) { + if (irq != null) { + System.out.println("Invalid irq (" + irq + "), ts = " + trcEvent.getOriginalTimestamp()); + } + return true; + } + + String submode; + submode = traceSt.getIrq_names().get(irq); + + if (submode == null) { + submode = ExecutionSubMode.LTTV_STATE_SUBMODE_UNKNOWN + .getInName(); + } + + /* + * Do something with the info about being in user or system mode + * when int? + */ + push_state(cpu, ExecutionMode.LTTV_STATE_IRQ, submode, trcEvent + .getTimestamp(), traceSt); + + /* update cpu state */ + LTTngCPUState cpust = traceSt.getCpu_states().get(cpu); + cpu_push_mode(cpust, CpuMode.LTTV_CPU_IRQ); /* mode stack */ + cpust.pushToIrqStack(irq); /* last irq */ + + /* udpate irq state */ + irq_push_mode(traceSt.getIrq_states().get(irq), + IRQMode.LTTV_IRQ_BUSY); + return false; + + } + }; + return handler; + } + + /** + * + * @return + */ + final ILttngEventProcessor getSoftIrqExitHandler() { + AbsStateUpdate handler = new AbsStateUpdate() { + + // @Override + public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) { + + Long cpu = trcEvent.getCpuId(); + LTTngCPUState cpust = traceSt.getCpu_states().get(cpu); + Long softirq = cpust.popFromSoftIrqStack(); + + // Update process status + pop_state(cpu, ExecutionMode.LTTV_STATE_SOFT_IRQ, traceSt, + trcEvent.getTimestamp()); + + /* update softirq status */ + if (softirq != -1) { + LttngSoftIRQState softIrqstate = traceSt + .getSoft_irq_states().get(softirq); + if (softIrqstate != null) { + softIrqstate.decrementRunning(); + } + } + + /* update cpu status */ + cpu_pop_mode(cpust); + + return false; + } + }; + return handler; + } + + /** + * + * @return + */ + final ILttngEventProcessor getIrqExitHandler() { + AbsStateUpdate handler = new AbsStateUpdate() { + + // @Override + public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) { + + Long cpu = trcEvent.getCpuId(); + + /* update process state */ + pop_state(cpu, ExecutionMode.LTTV_STATE_IRQ, traceSt, trcEvent + .getTimestamp()); + + /* update cpu status */ + LTTngCPUState cpust = traceSt.getCpu_states().get(cpu); + cpu_pop_mode(cpust); + + /* update irq status */ + Long last_irq = cpust.popFromIrqStack(); + if (last_irq != -1L) { + LttngIRQState irq_state = traceSt.getIrq_states().get( + last_irq); + irq_pop_mode(irq_state); + } + + return false; + + } + }; + return handler; + } + + /** + * + * @return + */ + final ILttngEventProcessor getSoftIrqRaiseHandler() { + AbsStateUpdate handler = new AbsStateUpdate() { + + private Events eventType = Events.LTT_EVENT_SOFT_IRQ_RAISE; + + // @Override + public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) { + + // Long cpu = trcEvent.getCpuId(); + + // get event field + Long softirq = getAFieldLong(trcEvent, traceSt, + Fields.LTT_FIELD_SOFT_IRQ_ID); + + if (softirq == null) { + TraceDebug.debug("Soft_irq_id not found in " + + eventType.getInName() + " time: " + + trcEvent.getTimestamp()); + return true; + } + + // String submode; + // String[] softIrqNames = traceSt.getSoft_irq_names(); + // if (softirq < softIrqNames.length) { + // submode = softIrqNames[softirq]; + // } else { + // submode = "softirq " + softirq; + // } + + /* update softirq status */ + /* a soft irq raises are not cumulative */ + LttngSoftIRQState irqState = traceSt.getSoft_irq_states().get( + softirq); + if (irqState != null) { + irqState.setPending(1L); + } else { + TraceDebug + .debug("unexpected soft irq id value: " + softirq); + } + + return false; + + } + }; + return handler; + } + + /** + * + * @return + */ + final ILttngEventProcessor getSoftIrqEntryHandler() { + AbsStateUpdate handler = new AbsStateUpdate() { + + // @Override + public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) { + + // obtrain cpu + Long cpu = trcEvent.getCpuId(); + + // get event field + Long softirq = getAFieldLong(trcEvent, traceSt, + Fields.LTT_FIELD_SOFT_IRQ_ID); + + if (softirq == null) { + TraceDebug.debug("Soft IRQ ID not found, eventTime: " + + trcEvent.getTimestamp()); + return true; + } + + // obtain submode + Map softIrqNames = traceSt.getSoft_irq_names(); + String submode = softIrqNames.get(softirq); + if (submode == null) { + submode = "softirq " + softirq; + softIrqNames.put(softirq, submode); + } + + /* update softirq status */ + LttngSoftIRQState irqState = traceSt.getSoft_irq_states().get( + softirq); + if (irqState != null) { + irqState.decrementPending(); + irqState.incrementRunning(); + } else { + TraceDebug + .debug("unexpected soft irq id value: " + softirq); + } + + /* update cpu state */ + LTTngCPUState cpu_state = traceSt.getCpu_states().get(cpu); + cpu_state.pushToSoftIrqStack(softirq); + cpu_push_mode(cpu_state, CpuMode.LTTV_CPU_SOFT_IRQ); + + /* update process execution mode state stack */ + push_state(cpu, ExecutionMode.LTTV_STATE_SOFT_IRQ, submode, + trcEvent.getTimestamp(), traceSt); + + return false; + + } + }; + return handler; + } + + /** + * Method to handle the event: LTT_EVENT_LIST_INTERRRUPT + * + * @return + */ + final ILttngEventProcessor getEnumInterruptHandler() { + AbsStateUpdate handler = new AbsStateUpdate() { + + private Events eventType = Events.LTT_EVENT_LIST_INTERRUPT; + + // @Override + public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) { + String action = getAFieldString(trcEvent, traceSt, + Fields.LTT_FIELD_ACTION); + Long irq = getAFieldLong(trcEvent, traceSt, + Fields.LTT_FIELD_IRQ_ID); + + if (action == null) { + TraceDebug.debug("Field Action not found in event " + + eventType.getInName() + " time: " + + trcEvent.getTimestamp()); + return true; + } + + if (irq == null) { + TraceDebug.debug("Field irq_id not found in event " + + eventType.getInName() + " time: " + + trcEvent.getTimestamp()); + return true; + } + + Map irq_names = traceSt.getIrq_names(); + + irq_names.put(irq, action); + return false; + + } + }; + return handler; + } + + /** + * Handle the event LTT_EVENT_REQUEST_ISSUE + * + * @return + */ + final ILttngEventProcessor getBdevRequestIssueHandler() { + AbsStateUpdate handler = new AbsStateUpdate() { + + // @Override + public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) { + + // Get Fields + Long major = getAFieldLong(trcEvent, traceSt, + Fields.LTT_FIELD_MAJOR); + Long minor = getAFieldLong(trcEvent, traceSt, + Fields.LTT_FIELD_MINOR); + Long operation = getAFieldLong(trcEvent, traceSt, + Fields.LTT_FIELD_OPERATION); + + // calculate bdevcode + Long devcode = mkdev(major, minor); + + if (devcode == null) { + TraceDebug + .debug("incorrect calcualtion of bdevcode input( major: " + + major + + " minor: " + + minor + + " operation: " + operation); + return true; + } + + Map bdev_states = traceSt + .getBdev_states(); + // Get the instance + LttngBdevState bdevState = bdev_states.get(devcode); + if (bdevState == null) { + bdevState = new LttngBdevState(); + } + + // update the mode in the stack + if (operation == 0L) { + bdevState.pushToBdevStack(BdevMode.LTTV_BDEV_BUSY_READING); + } else { + bdevState.pushToBdevStack(BdevMode.LTTV_BDEV_BUSY_WRITING); + } + + // make sure it is included in the set + bdev_states.put(devcode, bdevState); + return false; + + } + }; + return handler; + } + + /** + *

+ * Handling event: LTT_EVENT_REQUEST_COMPLETE + *

+ *

+ * FIELDS(LTT_FIELD_MAJOR, LTT_FIELD_MINOR, LTT_FIELD_OPERATION + *

+ * + * @return + */ + final ILttngEventProcessor getBdevRequestCompleteHandler() { + AbsStateUpdate handler = new AbsStateUpdate() { + + // @Override + public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) { + + // Get Fields + Long major = getAFieldLong(trcEvent, traceSt, + Fields.LTT_FIELD_MAJOR); + Long minor = getAFieldLong(trcEvent, traceSt, + Fields.LTT_FIELD_MINOR); + Long operation = getAFieldLong(trcEvent, traceSt, + Fields.LTT_FIELD_OPERATION); + + // calculate bdevcode + Long devcode = mkdev(major, minor); + + if (devcode == null) { + TraceDebug + .debug("incorrect calcualtion of bdevcode input( major: " + + major + + " minor: " + + minor + + " operation: " + operation); + return true; + } + + Map bdev_states = traceSt + .getBdev_states(); + // Get the instance + LttngBdevState bdevState = bdev_states.get(devcode); + if (bdevState == null) { + bdevState = new LttngBdevState(); + } + + /* update block device */ + bdev_pop_mode(bdevState); + + return false; + + } + }; + return handler; + } + + /** + *

+ * Handles event: LTT_EVENT_FUNCTION_ENTRY + *

+ *

+ * FIELDS: LTT_FIELD_THIS_FN, LTT_FIELD_CALL_SITE + *

+ * + * @return + */ + final ILttngEventProcessor getFunctionEntryHandler() { + AbsStateUpdate handler = new AbsStateUpdate() { + + // @Override + public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) { + Long cpu = trcEvent.getCpuId(); + Long funcptr = getAFieldLong(trcEvent, traceSt, + Fields.LTT_FIELD_THIS_FN); + + push_function(traceSt, funcptr, cpu); + return false; + + } + }; + return handler; + } + + /** + * + * @return + */ + final ILttngEventProcessor getFunctionExitHandler() { + AbsStateUpdate handler = new AbsStateUpdate() { + + // @Override + public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) { + + Long funcptr = getAFieldLong(trcEvent, traceSt, + Fields.LTT_FIELD_THIS_FN); + + pop_function(traceSt, trcEvent, funcptr); + return false; + + } + }; + return handler; + } + + /** + *

+ * process event: LTT_EVENT_SYS_CALL_TABLE + *

+ *

+ * fields: LTT_FIELD_ID, LTT_FIELD_ADDRESS, LTT_FIELD_SYMBOL + *

+ * + * @return + */ + final ILttngEventProcessor getDumpSyscallHandler() { + AbsStateUpdate handler = new AbsStateUpdate() { + + // @Override + public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) { + // obtain the syscall id + Long id = getAFieldLong(trcEvent, traceSt, Fields.LTT_FIELD_ID); + + // Long address = getAFieldLong(trcEvent, traceSt, + // Fields.LTT_FIELD_ADDRESS); + + // Obtain the symbol + String symbol = getAFieldString(trcEvent, traceSt, + Fields.LTT_FIELD_SYMBOL); + + // fill the symbol to the sycall_names collection + traceSt.getSyscall_names().put(id, symbol); + + return false; + } + }; + return handler; + } + + /** + *

+ * Handles event: LTT_EVENT_KPROBE_TABLE + *

+ *

+ * Fields: LTT_FIELD_IP, LTT_FIELD_SYMBOL + *

+ * + * @return + */ + final ILttngEventProcessor getDumpKprobeHandler() { + AbsStateUpdate handler = new AbsStateUpdate() { + + // @Override + public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) { + + Long ip = getAFieldLong(trcEvent, traceSt, Fields.LTT_FIELD_IP); + String symbol = getAFieldString(trcEvent, traceSt, + Fields.LTT_FIELD_SYMBOL); + + traceSt.getKprobe_table().put(ip, symbol); + + return false; + + } + }; + return handler; + } + + /** + *

+ * Handles: LTT_EVENT_SOFTIRQ_VEC + *

+ *

+ * Fields: LTT_FIELD_ID, LTT_FIELD_ADDRESS, LTT_FIELD_SYMBOL + *

+ * + * @return + */ + final ILttngEventProcessor getDumpSoftIrqHandler() { + AbsStateUpdate handler = new AbsStateUpdate() { + + // @Override + public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) { + + // Get id + Long id = getAFieldLong(trcEvent, traceSt, Fields.LTT_FIELD_ID); + + // Address not needed + // Long address = ltt_event_get_long_unsigned(e, + // lttv_trace_get_hook_field(th, + // 1)); + + // Get symbol + String symbol = getAFieldString(trcEvent, traceSt, + Fields.LTT_FIELD_SYMBOL); + + // Register the soft irq name + traceSt.getSoft_irq_names().put(id, symbol); + return false; + + } + }; + return handler; + } + + /** + *

+ * Handles: LTT_EVENT_SCHED_SCHEDULE + *

+ *

+ * Fields: LTT_FIELD_PREV_PID, LTT_FIELD_NEXT_PID, LTT_FIELD_PREV_STATE + *

+ * + * @return + */ + final ILttngEventProcessor getSchedChangeHandler() { + AbsStateUpdate handler = new AbsStateUpdate() { + + // @Override + public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) { + + Long cpu = trcEvent.getCpuId(); + TmfTimestamp eventTime = trcEvent.getTimestamp(); + + LttngProcessState process = traceSt.getRunning_process().get( + cpu); + + Long pid_out = getAFieldLong(trcEvent, traceSt, + Fields.LTT_FIELD_PREV_PID); + Long pid_in = getAFieldLong(trcEvent, traceSt, + Fields.LTT_FIELD_NEXT_PID); + Long state_out = getAFieldLong(trcEvent, traceSt, + Fields.LTT_FIELD_PREV_STATE); + + if (process != null) { + + /* + * We could not know but it was not the idle process + * executing. This should only happen at the beginning, + * before the first schedule event, and when the initial + * information (current process for each CPU) is missing. It + * is not obvious how we could, after the fact, compensate + * the wrongly attributed statistics. + */ + + // This test only makes sense once the state is known and if + // there + // is no + // missing events. We need to silently ignore schedchange + // coming + // after a + // process_free, or it causes glitches. (FIXME) + // if(unlikely(process->pid != pid_out)) { + // g_assert(process->pid == 0); + // } + if ((process.getPid().longValue() == 0L) + && (process.getState().getExec_mode() == ExecutionMode.LTTV_STATE_MODE_UNKNOWN)) { + if ((pid_out != null) && (pid_out.longValue() == 0L)) { + /* + * Scheduling out of pid 0 at beginning of the trace + * : we know for sure it is in syscall mode at this + * point. + */ + + process.getState().setExec_mode( + ExecutionMode.LTTV_STATE_SYSCALL); + process.getState().setProc_status( + ProcessStatus.LTTV_STATE_WAIT); + process.getState().setChange_Time( + trcEvent.getTimestamp().getValue()); + process.getState().setEntry_Time( + trcEvent.getTimestamp().getValue()); + } + } else { + if (process.getState().getProc_status() == ProcessStatus.LTTV_STATE_EXIT) { + process.getState().setProc_status( + ProcessStatus.LTTV_STATE_ZOMBIE); + process.getState().setChange_Time( + trcEvent.getTimestamp().getValue()); + } else { + if ((state_out != null) + && (state_out.longValue() == 0L)) { + process.getState().setProc_status( + ProcessStatus.LTTV_STATE_WAIT_CPU); + } else { + process.getState().setProc_status( + ProcessStatus.LTTV_STATE_WAIT); + } + + process.getState().setChange_Time( + trcEvent.getTimestamp().getValue()); + } + + if ((state_out != null) + && (state_out == 32L || state_out == 64L)) { /* + * EXIT_DEAD + * || + * TASK_DEAD + */ + /* see sched.h for states */ + if (!exit_process(traceSt, process)) { + process.getState().setProc_status( + ProcessStatus.LTTV_STATE_DEAD); + process.getState().setChange_Time( + trcEvent.getTimestamp().getValue()); + } + } + } + } + process = lttv_state_find_process_or_create(traceSt, cpu, + pid_in, eventTime); + + traceSt.getRunning_process().put(cpu, process); + + process.getState().setProc_status(ProcessStatus.LTTV_STATE_RUN); + process.getState().setChange_Time(eventTime.getValue()); + process.setCpu(cpu); + // process->state->s = LTTV_STATE_RUN; + // if(process->usertrace) + // process->usertrace->cpu = cpu; + // process->last_cpu_index = + // ltt_tracefile_num(((LttvTracefileContext*)s)->tf); + + // process->state->change = s->parent.timestamp; + + LTTngCPUState cpu_state = traceSt.getCpu_states().get(cpu); + /* update cpu status */ + if ((pid_in != null) && (pid_in.longValue() == 0L)) { + + /* going to idle task */ + cpu_set_base_mode(cpu_state, CpuMode.LTTV_CPU_IDLE); + } else { + /* + * scheduling a real task. we must be careful here: if we + * just schedule()'ed to a process that is in a trap, we + * must put the cpu in trap mode + */ + cpu_set_base_mode(cpu_state, CpuMode.LTTV_CPU_BUSY); + if (process.getState().getExec_mode() == ExecutionMode.LTTV_STATE_TRAP) { + cpu_push_mode(cpu_state, CpuMode.LTTV_CPU_TRAP); + } + } + return false; + + } + }; + return handler; + } + + /** + *

+ * Handles: LTT_EVENT_PROCESS_FORK + *

+ *

+ * Fields: FIELD_ARRAY(LTT_FIELD_PARENT_PID, LTT_FIELD_CHILD_PID, + * LTT_FIELD_CHILD_TGID) + *

+ * + * @return + */ + final ILttngEventProcessor getProcessForkHandler() { + AbsStateUpdate handler = new AbsStateUpdate() { + + // @Override + public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) { + + Long cpu = trcEvent.getCpuId(); + LttngProcessState process = traceSt.getRunning_process().get( + cpu); + TmfTimestamp timeStamp = trcEvent.getTimestamp(); + + // /* Parent PID */ + // Long parent_pid = getAFieldLong(trcEvent, traceSt, + // Fields.LTT_FIELD_PARENT_PID); + + /* Child PID */ + /* In the Linux Kernel, there is one PID per thread. */ + Long child_pid = getAFieldLong(trcEvent, traceSt, + Fields.LTT_FIELD_CHILD_PID); + + /* Child TGID */ + /* tgid in the Linux kernel is the "real" POSIX PID. */ + Long child_tgid = getAFieldLong(trcEvent, traceSt, + Fields.LTT_FIELD_CHILD_TGID); + if (child_tgid == null) { + child_tgid = 0L; + } + + /* + * Mathieu : it seems like the process might have been scheduled + * in before the fork, and, in a rare case, might be the current + * process. This might happen in a SMP case where we don't have + * enough precision on the clocks. + * + * Test reenabled after precision fixes on time. (Mathieu) + */ + // #if 0 + // zombie_process = lttv_state_find_process(ts, ANY_CPU, + // child_pid); + // + // if(unlikely(zombie_process != NULL)) { + // /* Reutilisation of PID. Only now we are sure that the old + // PID + // * has been released. FIXME : should know when release_task + // happens + // instead. + // */ + // guint num_cpus = ltt_trace_get_num_cpu(ts->parent.t); + // guint i; + // for(i=0; i< num_cpus; i++) { + // g_assert(zombie_process != ts->running_process[i]); + // } + // + // exit_process(s, zombie_process); + // } + // #endif //0 + + if (process.getPid().equals(child_pid)) { + TraceDebug + .debug("Unexpected, process pid equal to child pid: " + + child_pid + + " Event Time: " + + trcEvent.getTimestamp()); + } + + // g_assert(process->pid != child_pid); + // FIXME : Add this test in the "known state" section + // g_assert(process->pid == parent_pid); + LttngProcessState child_process = lttv_state_find_process( + traceSt, ANY_CPU, child_pid); + if (child_process == null) { + child_process = create_process(traceSt, cpu, child_pid, + child_tgid, timeStamp); + child_process.setPpid(process.getPid(), timeStamp.getValue()); + } else { + /* + * The process has already been created : due to time + * imprecision between multiple CPUs : it has been scheduled + * in before creation. Note that we shouldn't have this kind + * of imprecision. + * + * Simply put a correct parent. + */ + StringBuilder sb = new StringBuilder("Process " + child_pid); + sb.append(" has been created at [" + + child_process.getCreation_time() + "] "); + sb.append("and inserted at [" + + child_process.getInsertion_time() + "] "); + sb.append("before \nfork on cpu " + cpu + " Event time: [" + + trcEvent + "]\n."); + sb + .append("Probably an unsynchronized TSD problem on the traced machine."); + TraceDebug.debug(sb.toString()); + + // g_assert(0); /* This is a problematic case : the process + // has + // beencreated + // before the fork event */ + child_process.setPpid(process.getPid()); + child_process.setTgid(child_tgid); + } + + if (!child_process.getName().equals( + ProcessStatus.LTTV_STATE_UNNAMED.getInName())) { + TraceDebug.debug("Unexpected child process status: " + + child_process.getName()); + } + + child_process.setName(process.getName()); + child_process.setBrand(process.getBrand()); + + return false; + + } + }; + return handler; + } + + /** + *

+ * Handles: LTT_EVENT_KTHREAD_CREATE + *

+ *

+ * Fields: LTT_FIELD_PID + *

+ * + * @return + */ + final ILttngEventProcessor getProcessKernelThreadHandler() { + AbsStateUpdate handler = new AbsStateUpdate() { + + // @Override + public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) { + /* + * We stamp a newly created process as kernel_thread. The thread + * should not be running yet. + */ + + LttngExecutionState exState; + Long pid; + LttngProcessState process; + + /* PID */ + pid = getAFieldLong(trcEvent, traceSt, Fields.LTT_FIELD_PID); + // s->parent.target_pid = pid; + + process = lttv_state_find_process_or_create(traceSt, ANY_CPU, + pid, new TmfTimestamp()); + + if (!process.getState().getProc_status().equals( + ProcessStatus.LTTV_STATE_DEAD)) { + // Leave only the first element in the stack with execution + // mode to + // syscall + exState = process.getFirstElementFromExecutionStack(); + exState.setExec_mode(ExecutionMode.LTTV_STATE_SYSCALL); + process.clearExecutionStack(); + process.pushToExecutionStack(exState); + } + + process.setType(ProcessType.LTTV_STATE_KERNEL_THREAD); + + return false; + + } + }; + return handler; + } + + /** + *

+ * Handles: LTT_EVENT_PROCESS_EXIT + *

+ *

+ * LTT_FIELD_PID + *

+ * + * @return + */ + final ILttngEventProcessor getProcessExitHandler() { + AbsStateUpdate handler = new AbsStateUpdate() { + + // @Override + public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) { + + Long pid; + LttngProcessState process; + + pid = getAFieldLong(trcEvent, traceSt, Fields.LTT_FIELD_PID); + // s->parent.target_pid = pid; + + // FIXME : Add this test in the "known state" section + // g_assert(process->pid == pid); + + process = lttv_state_find_process(traceSt, ANY_CPU, pid); + if (process != null) { + process.getState().setProc_status( + ProcessStatus.LTTV_STATE_EXIT); + } + return false; + + } + }; + return handler; + } + + /** + *

+ * Handles: LTT_EVENT_PROCESS_FREE + *

+ *

+ * Fields: LTT_FIELD_PID + *

+ * + * @return + */ + final ILttngEventProcessor getProcessFreeHandler() { + AbsStateUpdate handler = new AbsStateUpdate() { + + // @Override + public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) { + + Long release_pid; + LttngProcessState process; + + /* PID of the process to release */ + release_pid = getAFieldLong(trcEvent, traceSt, + Fields.LTT_FIELD_PID); + // s->parent.target_pid = release_pid; + + if ((release_pid != null) && (release_pid.longValue() == 0L)) { + TraceDebug.debug("Unexpected release_pid: 0, Event time: " + + trcEvent.getTimestamp()); + } + + process = lttv_state_find_process(traceSt, ANY_CPU, release_pid); + if (process != null) { + exit_process(traceSt, process); + } + + return false; + // DISABLED + // if(process != null) { + /* + * release_task is happening at kernel level : we can now safely + * release the data structure of the process + */ + // This test is fun, though, as it may happen that + // at time t : CPU 0 : process_free + // at time t+150ns : CPU 1 : schedule out + // Clearly due to time imprecision, we disable it. (Mathieu) + // If this weird case happen, we have no choice but to put the + // Currently running process on the cpu to 0. + // I re-enable it following time precision fixes. (Mathieu) + // Well, in the case where an process is freed by a process on + // another + // CPU + // and still scheduled, it happens that this is the schedchange + // that + // will + // drop the last reference count. Do not free it here! + + // int num_cpus = ltt_trace_get_num_cpu(ts->parent.t); + // guint i; + // for(i=0; i< num_cpus; i++) { + // //g_assert(process != ts->running_process[i]); + // if(process == ts->running_process[i]) { + // //ts->running_process[i] = lttv_state_find_process(ts, i, 0); + // break; + // } + // } + // if(i == num_cpus) /* process is not scheduled */ + // exit_process(s, process); + // } + // + // return false; + + } + }; + return handler; + } + + /** + *

+ * Handles: LTT_EVENT_EXEC + *

+ *

+ * FIELDS: LTT_FIELD_FILENAME + *

+ * + * @return + */ + final ILttngEventProcessor getProcessExecHandler() { + AbsStateUpdate handler = new AbsStateUpdate() { + + // @Override + public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) { + + Long cpu = trcEvent.getCpuId(); + LttngProcessState process = traceSt.getRunning_process().get( + cpu); + + // #if 0//how to use a sequence that must be transformed in a + // string + // /* PID of the process to release */ + // guint64 name_len = ltt_event_field_element_number(e, + // lttv_trace_get_hook_field(th, 0)); + // //name = ltt_event_get_string(e, + // lttv_trace_get_hook_field(th, 0)); + // LttField *child = ltt_event_field_element_select(e, + // lttv_trace_get_hook_field(th, 0), 0); + // gchar *name_begin = + // (gchar*)(ltt_event_data(e)+ltt_event_field_offset(e, child)); + // gchar *null_term_name = g_new(gchar, name_len+1); + // memcpy(null_term_name, name_begin, name_len); + // null_term_name[name_len] = '\0'; + // process->name = g_quark_from_string(null_term_name); + // #endif //0 + + process.setName(getAFieldString(trcEvent, traceSt, + Fields.LTT_FIELD_FILENAME)); + process.setBrand(StateStrings.LTTV_STATE_UNBRANDED); + return false; + + } + }; + return handler; + } + + /** + *

+ * LTT_EVENT_THREAD_BRAND + *

+ *

+ * FIELDS: LTT_FIELD_NAME + *

+ * + * @return + */ + final ILttngEventProcessor GetThreadBrandHandler() { + AbsStateUpdate handler = new AbsStateUpdate() { + + // @Override + public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) { + + String name; + Long cpu = trcEvent.getCpuId(); + LttngProcessState process = traceSt.getRunning_process().get( + cpu); + + name = getAFieldString(trcEvent, traceSt, Fields.LTT_FIELD_NAME); + process.setBrand(name); + return false; + + } + }; + return handler; + } + + /** + * @return + */ + final ILttngEventProcessor getStateDumpEndHandler() { + AbsStateUpdate handler = new AbsStateUpdate() { + + // @Override + public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) { + + /* For all processes */ + /* + * if kernel thread, if stack[0] is unknown, set to syscall + * mode, wait + */ + /* else, if stack[0] is unknown, set to user mode, running */ + LttngProcessState[] processes = traceSt.getProcesses(); + TmfTimestamp time = trcEvent.getTimestamp(); + + for (int pos = 0; pos < processes.length; pos++) { + fix_process(processes[pos], time); + } + + return false; + + } + + /** + * Private method used to establish the first execution state in the + * stack for a given process + * + * @param process + * @param timestamp + */ + private void fix_process(LttngProcessState process, + TmfTimestamp timestamp) { + + LttngExecutionState es; + + if (process.getType() == ProcessType.LTTV_STATE_KERNEL_THREAD) { + es = process.getFirstElementFromExecutionStack(); + + if (es.getExec_mode() == ExecutionMode.LTTV_STATE_MODE_UNKNOWN) { + es.setExec_mode(ExecutionMode.LTTV_STATE_SYSCALL); + es + .setExec_submode(ExecutionSubMode.LTTV_STATE_SUBMODE_NONE + .getInName()); + es.setEntry_Time(timestamp.getValue()); + es.setChange_Time(timestamp.getValue()); + es.setCum_cpu_time(0L); + if (es.getProc_status() == ProcessStatus.LTTV_STATE_UNNAMED) { + es.setProc_status(ProcessStatus.LTTV_STATE_WAIT); + } + } + } else { + es = process.getFirstElementFromExecutionStack(); + if (es.getExec_mode() == ExecutionMode.LTTV_STATE_MODE_UNKNOWN) { + es.setExec_mode(ExecutionMode.LTTV_STATE_USER_MODE); + es + .setExec_submode(ExecutionSubMode.LTTV_STATE_SUBMODE_NONE + .getInName()); + es.setEntry_Time(timestamp.getValue()); + es.setChange_Time(timestamp.getValue()); + es.setCum_cpu_time(0L); + if (es.getProc_status() == ProcessStatus.LTTV_STATE_UNNAMED) { + es.setProc_status(ProcessStatus.LTTV_STATE_RUN); + } + + // If the first element is also the one on top... mean + // we have ONE element on the stack + if (process.getFirstElementFromExecutionStack() == process + .peekFromExecutionStack()) { + /* + * Still in bottom unknown mode, means never did a + * system call May be either in user mode, syscall + * mode, running or waiting. + */ + /* + * FIXME : we may be tagging syscall mode when being + * user mode + */ + // Get a new execution State + es = new LttngExecutionState(); + + // initialize values + es.setExec_mode(ExecutionMode.LTTV_STATE_SYSCALL); + es + .setExec_submode(ExecutionSubMode.LTTV_STATE_SUBMODE_NONE + .getInName()); + es.setEntry_Time(timestamp.getValue()); + es.setChange_Time(timestamp.getValue()); + es.setCum_cpu_time(0L); + es.setProc_status(ProcessStatus.LTTV_STATE_WAIT); + + // Push the new state to the stack + process.pushToExecutionStack(es); + } + } + } + } + }; + return handler; + } + + /** + *

+ * Handles: LTT_EVENT_PROCESS_STATE + *

+ *

+ * FIELDS: LTT_FIELD_PID, LTT_FIELD_PARENT_PID, LTT_FIELD_NAME, + * LTT_FIELD_TYPE, LTT_FIELD_MODE, LTT_FIELD_SUBMODE, LTT_FIELD_STATUS, + * LTT_FIELD_TGID + *

+ * + * @return + */ + final ILttngEventProcessor getEnumProcessStateHandler() { + AbsStateUpdate handler = new AbsStateUpdate() { + + // @Override + public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) { + + Long parent_pid; + Long pid; + Long tgid; + String command; + Long cpu = trcEvent.getCpuId(); + + LttngProcessState process = traceSt.getRunning_process().get( + cpu); + LttngProcessState parent_process; + String type; + // String mode, submode, status; + LttngExecutionState es; + + /* PID */ + pid = getAFieldLong(trcEvent, traceSt, Fields.LTT_FIELD_PID); + + /* Parent PID */ + parent_pid = getAFieldLong(trcEvent, traceSt, + Fields.LTT_FIELD_PARENT_PID); + + /* Command name */ + command = getAFieldString(trcEvent, traceSt, + Fields.LTT_FIELD_NAME); + + Long typeVal = getAFieldLong(trcEvent, traceSt, + Fields.LTT_FIELD_TYPE); + + type = ProcessType.LTTV_STATE_KERNEL_THREAD.getInName(); + if ((typeVal != null) && (typeVal.longValue() == 0L)) { + type = ProcessType.LTTV_STATE_USER_THREAD.getInName(); + } + + // /* mode */ + // mode = getAFieldString(trcEvent, traceSt, + // Fields.LTT_FIELD_MODE); + // + // /* submode */ + // submode = getAFieldString(trcEvent, traceSt, + // Fields.LTT_FIELD_SUBMODE); + // + // /* status */ + // status = getAFieldString(trcEvent, traceSt, + // Fields.LTT_FIELD_STATUS); + + /* TGID */ + tgid = getAFieldLong(trcEvent, traceSt, Fields.LTT_FIELD_TGID); + if (tgid == null) { + tgid = 0L; + } + + if ((pid != null) && (pid.longValue() == 0L)) { + for (Long acpu : traceSt.getCpu_states().keySet()) { + process = lttv_state_find_process(traceSt, acpu, pid); + if (process != null) { + process.setPpid(parent_pid); + process.setTgid(tgid); + process.setName(command); + process + .setType(ProcessType.LTTV_STATE_KERNEL_THREAD); + } else { + StringBuilder sb = new StringBuilder( + "Unexpected, null process read from the TraceState list of processes, event time: " + + trcEvent.getTimestamp()); + TraceDebug.debug(sb.toString()); + } + } + } else { + /* + * The process might exist if a process was forked while + * performing the state dump. + */ + process = lttv_state_find_process(traceSt, ANY_CPU, pid); + if (process == null) { + parent_process = lttv_state_find_process(traceSt, + ANY_CPU, parent_pid); + TmfTimestamp eventTime = trcEvent.getTimestamp(); + process = create_process(traceSt, cpu, pid, tgid, + command, eventTime); + if (parent_process != null) { + process.setPpid(parent_process.getPid(), eventTime.getValue()); + } + + /* Keep the stack bottom : a running user mode */ + /* + * Disabled because of inconsistencies in the current + * statedump states. + */ + if (type.equals(ProcessType.LTTV_STATE_KERNEL_THREAD + .getInName())) { + /* + * FIXME Kernel thread : can be in syscall or + * interrupt or trap. + */ + /* + * Will cause expected trap when in fact being + * syscall (even after end of statedump event) Will + * cause expected interrupt when being syscall. + * (only before end of statedump event) + */ + // process type is USER_THREAD by default. + process + .setType(ProcessType.LTTV_STATE_KERNEL_THREAD); + + } + + //Only one entry needed in the execution stack + process.popFromExecutionStack(); + es = process.getState(); + es.setExec_mode(ExecutionMode.LTTV_STATE_MODE_UNKNOWN); + es.setProc_status(ProcessStatus.LTTV_STATE_UNNAMED); + es + .setExec_submode(ExecutionSubMode.LTTV_STATE_SUBMODE_UNKNOWN + .getInName()); + // #if 0 + // /* UNKNOWN STATE */ + // { + // es = process->state = + // &g_array_index(process->execution_stack, + // LttvExecutionState, 1); + // es->t = LTTV_STATE_MODE_UNKNOWN; + // es->s = LTTV_STATE_UNNAMED; + // es->n = LTTV_STATE_SUBMODE_UNKNOWN; + // } + // #endif //0 + } else { + /* + * The process has already been created : Probably was + * forked while dumping the process state or was simply + * scheduled in prior to get the state dump event. + */ + process.setPpid(parent_pid); + process.setTgid(tgid); + process.setName(command); + if (type.equals(ProcessType.LTTV_STATE_KERNEL_THREAD + .getInName())) { + process + .setType(ProcessType.LTTV_STATE_KERNEL_THREAD); + } else { + process.setType(ProcessType.LTTV_STATE_USER_THREAD); + } + + // es = + // &g_array_index(process->execution_stack, + // LttvExecutionState, + // 0); + // #if 0 + // if(es->t == LTTV_STATE_MODE_UNKNOWN) { + // if(type == LTTV_STATE_KERNEL_THREAD) + // es->t = LTTV_STATE_SYSCALL; + // else + // es->t = LTTV_STATE_USER_MODE; + // } + // #endif //0 + /* + * Don't mess around with the stack, it will eventually + * become ok after the end of state dump. + */ + } + } + + return false; + + } + }; + return handler; + } + +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/experiment/IStateExperimentManager.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/experiment/IStateExperimentManager.java new file mode 100644 index 0000000000..ad3a37cece --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/experiment/IStateExperimentManager.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (c) 2010 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: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.lttng.state.experiment; + +import org.eclipse.linuxtools.lttng.event.LttngEvent; +import org.eclipse.linuxtools.lttng.model.LTTngTreeNode; +import org.eclipse.linuxtools.lttng.request.ILttngSyntEventRequest; +import org.eclipse.linuxtools.lttng.request.IRequestStatusListener; +import org.eclipse.linuxtools.lttng.state.evProcessor.ITransEventProcessor; +import org.eclipse.linuxtools.tmf.event.TmfTimeRange; +import org.eclipse.linuxtools.tmf.experiment.TmfExperiment; + +public interface IStateExperimentManager { + + /** + * Read all available traces from the nearest checkpoint from start position + * to the end of a specified time range. One request per trace in the + * experiment will be triggered + * + * @param trange + * @param obs + * @param transactionID + * @param display + * @return + */ + public abstract ILttngSyntEventRequest readExperimentTimeWindow( + TmfTimeRange trange, + Object origin, IRequestStatusListener listener, + ITransEventProcessor processor); + + /** + * Read available traces from the Experiment start time, One request per + * trace in the Experiment + * + * @param source + * @param listener + * @param processor + */ + public abstract void readExperiment(Object source, + IRequestStatusListener listener, ITransEventProcessor processor); + + /** + * A new Experiment selected, notification received from the framework + * Notify the new experiment selection to the state handling managers + * + * @param source + * @param experiment + */ + public abstract void experimentSelected_prep( + TmfExperiment experiment); + + /** + * @param source + * @param experiment + */ + public void experimentSelected(Object source, + TmfExperiment experiment); + + /** + * @return + */ + public abstract TmfTimeRange getExperimentTimeRange(); + + /** + * @return + */ + public abstract LTTngTreeNode getSelectedExperiment(); + + /** + * Wait for request completion upon experiment selection + * + * @param wait + */ + public abstract void waitForCompletion(boolean wait); + +} \ No newline at end of file diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/experiment/StateExperimentManager.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/experiment/StateExperimentManager.java new file mode 100644 index 0000000000..1efc21dd6c --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/experiment/StateExperimentManager.java @@ -0,0 +1,257 @@ +/******************************************************************************* ++ * Copyright (c) 2009, 2010 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: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.linuxtools.lttng.state.experiment; + +import org.eclipse.linuxtools.lttng.TraceDebug; +import org.eclipse.linuxtools.lttng.control.LttngCoreProviderFactory; +import org.eclipse.linuxtools.lttng.control.LttngSyntheticEventProvider; +import org.eclipse.linuxtools.lttng.event.LttngEvent; +import org.eclipse.linuxtools.lttng.model.LTTngTreeNode; +import org.eclipse.linuxtools.lttng.request.ILttngSyntEventRequest; +import org.eclipse.linuxtools.lttng.request.IRequestStatusListener; +import org.eclipse.linuxtools.lttng.signal.ILttExperimentSelectedListener; +import org.eclipse.linuxtools.lttng.signal.StateExperimentListener; +import org.eclipse.linuxtools.lttng.state.evProcessor.ITransEventProcessor; +import org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager; +import org.eclipse.linuxtools.tmf.event.TmfTimeRange; +import org.eclipse.linuxtools.tmf.experiment.TmfExperiment; +import org.eclipse.linuxtools.tmf.signal.TmfExperimentUpdatedSignal; +import org.eclipse.linuxtools.tmf.trace.ITmfTrace; + +/** + * @author alvaro + * + */ +public class StateExperimentManager extends LTTngTreeNode implements + ILttExperimentSelectedListener, IStateExperimentManager { + + // ======================================================================== + // Data + // ======================================================================= + private LTTngTreeNode fSelectedExperiment = null; // one selected experiment + // supported + private final StateExperimentListener fexperimentListener; + private boolean fwaitForCompletion = false; + + + // ======================================================================== + // Constructors + // ======================================================================= + public StateExperimentManager(Long id, String name) { + super(id, null, name, null); + fexperimentListener = new StateExperimentListener("Experiment Manager", + this); + } + + + // ======================================================================== + // Methods + // ======================================================================= + + /* (non-Javadoc) + * @see org.eclipse.linuxtools.lttng.state.experiment.IStateExperimentManager#readExperimentTimeWindow(org.eclipse.linuxtools.tmf.event.TmfTimeRange, java.lang.String, org.eclipse.linuxtools.lttng.state.IStateDataRequestListener) + */ + public ILttngSyntEventRequest readExperimentTimeWindow(TmfTimeRange trange, + Object source, IRequestStatusListener listener, + ITransEventProcessor processor) { + + ILttngSyntEventRequest request = null; + + // validate + if (fSelectedExperiment != null) { + // Get all trace manager nodes + LTTngTreeNode[] traceMgrs = fSelectedExperiment.getChildren(); + + if (traceMgrs != null && traceMgrs.length > 0) { + IStateTraceManager traceManager; + // Trigger one request per trace + for (LTTngTreeNode traceNode : traceMgrs) { + traceManager = (IStateTraceManager) traceNode; + request = traceManager.executeDataRequest(trange, source, + listener, + processor); + } + } + } else { + if (fSelectedExperiment == null) { + TraceDebug.debug("No experiment selected"); + } + } + + return request; + } + + /* (non-Javadoc) + * @see org.eclipse.linuxtools.lttng.state.experiment.IStateExperimentManager#readExperiment(java.lang.String, org.eclipse.linuxtools.lttng.state.IStateDataRequestListener) + */ + @SuppressWarnings("unchecked") + public void readExperiment(Object source, IRequestStatusListener listener, + ITransEventProcessor processor) { + // validate + if (fSelectedExperiment != null) { + TmfExperiment experiment = (TmfExperiment) fSelectedExperiment + .getValue(); + TmfTimeRange trange = experiment.getTimeRange(); + readExperimentTimeWindow(trange, source, listener, processor); + } else { + TraceDebug.debug("No selected experiment available"); + } + } + + + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.linuxtools.lttng.state.experiment.IStateExperimentManager + * #experimentSelected_prep + * (org.eclipse.linuxtools.tmf.experiment.TmfExperiment) + */ + public void experimentSelected_prep(TmfExperiment experiment) { + LTTngTreeNode experimentNode = null; + if (experiment != null) { + experimentNode = getChildByName(experiment.getName()); + // keep experiment if already loaded with the same value + if (experimentNode != null + && experimentNode.getValue() != experiment) { + // rebuild the experiment nodes from scratch + removeChild(experimentNode); + experimentNode = null; + } + + // Make sure all traces involved have a corresponding state manager + // and + // state system to request its initial data + if (experimentNode == null) { + // Create the new experiment tree node + experimentNode = new LTTngTreeNode(getNextUniqueId(), this, + experiment.getName(), experiment); + // add the new experiment to this children list + addChild(experimentNode); + } + + // Make sure the traces exists in the tree + ITmfTrace[] rtraces = experiment.getTraces(); + String traceName; + LTTngTreeNode traceStateManagerNode; + // StateStacksHandler + for (ITmfTrace rtrace : rtraces) { + traceName = rtrace.getName(); + traceStateManagerNode = experimentNode.getChildByName(traceName); + // Node does not exist for this experiment, so needs to be + // created + if (traceStateManagerNode == null) { + traceStateManagerNode = StateManagerFactory.getManager( + rtrace, experimentNode); + experimentNode.addChild(traceStateManagerNode); + } + } + + // Reset event provider to handle requests for the new experiment + LttngSyntheticEventProvider synEventProvider = LttngCoreProviderFactory + .getEventProvider(); + synEventProvider.reset(experimentNode); + + // preserve the selected experiment + fSelectedExperiment = experimentNode; + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.linuxtools.lttng.signal.ILttExperimentSelectedListener# + * experimentSelected(java.lang.Object, + * org.eclipse.linuxtools.tmf.experiment.TmfExperiment) + */ + public void experimentSelected(Object source, + TmfExperiment experiment) { + // validate + if (experiment == null) { + return; + } + + LTTngTreeNode experimentNode = getChildByName(experiment.getName()); + if (experimentNode != null) { + // get the trace manager nodes + LTTngTreeNode[] traceNodes = experimentNode.getChildren(); + for (LTTngTreeNode traceStateManagerNode : traceNodes) { + // The trace node needs to perform its first data request + // for this experiment with the main goal of building its + // checkpoints + if (traceStateManagerNode instanceof ILttExperimentSelectedListener) { + // no need to provide the trace to the trace manager + ((ILttExperimentSelectedListener) traceStateManagerNode).experimentUpdated( + new TmfExperimentUpdatedSignal(source, experiment, null), fwaitForCompletion); + } + } + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.linuxtools.lttng.signal.ILttExperimentSelectedListener# + * experimentUpdated + * (org.eclipse.linuxtools.tmf.signal.TmfExperimentUpdatedSignal, boolean) + */ + public void experimentUpdated(TmfExperimentUpdatedSignal signal, boolean wait) { + // NOTE: This represents the end of TMF indexing for a trace, however + // the node was already existing and the state system check points are + // already requested and built upon selection. + // No action for the time being + } + + + /** + * @return the SelectedExperiment tree node + */ + public LTTngTreeNode getSelectedExperiment() { + return fSelectedExperiment; + } + + /* (non-Javadoc) + * @see org.eclipse.linuxtools.lttng.state.experiment.IStateExperimentManager#getExperimentTimeRange() + */ + @SuppressWarnings("unchecked") + public TmfTimeRange getExperimentTimeRange() { + TmfTimeRange timeRangeResult = null; + if (fSelectedExperiment != null) { + timeRangeResult = ((TmfExperiment) fSelectedExperiment + .getValue()).getTimeRange(); + } + return timeRangeResult; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#finalize() + */ + protected void finalize() { + fexperimentListener.dispose(); + } + + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.linuxtools.lttng.state.experiment.IStateExperimentManager + * #waitForComplete(boolean) + */ + public void waitForCompletion(boolean wait) { + fwaitForCompletion = wait; + } + +} \ No newline at end of file diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/experiment/StateManagerFactory.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/experiment/StateManagerFactory.java new file mode 100644 index 0000000000..0c336bee9b --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/experiment/StateManagerFactory.java @@ -0,0 +1,160 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 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: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.lttng.state.experiment; + +import org.eclipse.linuxtools.lttng.TraceDebug; +import org.eclipse.linuxtools.lttng.control.LttngCoreProviderFactory; +import org.eclipse.linuxtools.lttng.model.LTTngTreeNode; +import org.eclipse.linuxtools.lttng.state.LttngStateException; +import org.eclipse.linuxtools.lttng.state.model.LttngTraceState; +import org.eclipse.linuxtools.lttng.state.model.StateModelFactory; +import org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager; +import org.eclipse.linuxtools.lttng.state.trace.StateTraceManager; +import org.eclipse.linuxtools.tmf.experiment.TmfExperiment; +import org.eclipse.linuxtools.tmf.trace.ITmfTrace; + +/** + * @author alvaro + * + */ +public class StateManagerFactory { + // ======================================================================== + // Data + // ======================================================================= + + private static IStateExperimentManager experimentManager = null; + /** + * Allows to modify the check point interval for every new instance of trace manager + */ + private static Long ftraceCheckPointInterval = null; + + static { + initCheck(); + } + // ======================================================================== + // Methods + // ======================================================================= + + /** + * @param traceUniqueId + * @param experiment + * @return + */ + public static LTTngTreeNode getManager(ITmfTrace rtrace, + LTTngTreeNode experiment) { + + // Validate + if (rtrace == null) { + return null; + } + + String traceUniqueId = rtrace.getName(); + if (traceUniqueId == null) { + return null; + } + + + LTTngTreeNode managerNode = null; + managerNode = experiment.getChildByName(traceUniqueId); + + if (managerNode != null && managerNode instanceof IStateTraceManager) { + return managerNode; + } + + LttngTraceState traceModel = StateModelFactory.getStateEntryInstance(); + StateTraceManager manager = null; + + // catch potential construction problems + try { + manager = new StateTraceManager(experiment.getNextUniqueId(), + experiment, traceUniqueId, rtrace, traceModel, + LttngCoreProviderFactory.getEventProvider()); + + // Allow the possibility to configure the trace state check point + // interval at creation time + if (ftraceCheckPointInterval != null) { + manager.setCheckPointInterval(ftraceCheckPointInterval); + } + + } catch (LttngStateException e) { + e.printStackTrace(); + } + + experiment.addChild(manager); + return manager; + } + + /** + * Provide the State trace set manager + * + * @return + */ + public static IStateExperimentManager getExperimentManager() { + return experimentManager; + } + + /** + * Remove previously registered managers + * + * @param traceUniqueId + */ + public static void removeManager(ITmfTrace rtrace, LTTngTreeNode rexperiment) { + Object experimentObj = rexperiment.getValue(); + if (rtrace != null && rexperiment != null + && experimentObj instanceof TmfExperiment) { + LTTngTreeNode childToremove = rexperiment.getChildByName(rtrace + .getName()); + if (childToremove != null) { + rexperiment.removeChild(childToremove); + } + } else { + TraceDebug.debug("Invalid arguments to remove manager for trace: " + + rtrace.getName()); + } + } + + /** + * initialization of factory + */ + private static void initCheck() { + if (experimentManager == null) { + Long id = 0L; // unique id + String name = "StateExperimentManager"; // name + experimentManager = new StateExperimentManager(id, name); + } + } + + /** + * Clea up resources + */ + public static void dispose() { + if (experimentManager != null) { + experimentManager = null; + } + } + + /** + * @return the traceCheckPointInterval + */ + public static Long getTraceCheckPointInterval() { + return ftraceCheckPointInterval; + } + + /** + * @param traceCheckPointInterval + * the traceCheckPointInterval to set + */ + public static void setTraceCheckPointInterval(Long traceCheckPointInterval) { + StateManagerFactory.ftraceCheckPointInterval = traceCheckPointInterval; + } +} \ No newline at end of file diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/model/LTTngCPUState.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/model/LTTngCPUState.java new file mode 100644 index 0000000000..c744b0e8d0 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/model/LTTngCPUState.java @@ -0,0 +1,178 @@ +/******************************************************************************* + * Copyright (c) 2009 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: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.linuxtools.lttng.state.model; + +import java.util.Stack; + +import org.eclipse.linuxtools.lttng.state.StateStrings; +import org.eclipse.linuxtools.lttng.state.StateStrings.CpuMode; + +/** + * LTTngCPUState + *

+ * + */ +public class LTTngCPUState implements Cloneable { + // ======================================================================== + // Data + // ======================================================================= + private Stack mode_stack = new Stack(); + private Stack irq_stack = new Stack(); + private Stack softirq_stack = new Stack(); + private Stack trap_stack = new Stack(); + + // ======================================================================== + // Constructor + // ======================================================================= + public LTTngCPUState() { + mode_stack.push(CpuMode.LTTV_CPU_UNKNOWN); + irq_stack.push(-1L); + softirq_stack.push(-1L); + trap_stack.push(-1L); + } + + @Override + @SuppressWarnings("unchecked") + public LTTngCPUState clone() { + LTTngCPUState newState = null; + + try { + newState = (LTTngCPUState) super.clone(); + + // // *** IMPORTANT *** + // // Basic type in java are immutable! + // // Thus, using assignation ("=") on basic type is CORRECT, + // // but we should ALWAYS use "new" or "clone()" on "non basic" + // type + + // Clone should work correctly for all stack object that contain + // basic java object (String, Long, etc...) + newState.mode_stack = (Stack) this.mode_stack + .clone(); + newState.irq_stack = (Stack) this.irq_stack.clone(); + newState.softirq_stack = (Stack) this.softirq_stack.clone(); + newState.trap_stack = (Stack) this.trap_stack.clone(); + } catch (CloneNotSupportedException e) { + System.out.println("Cloning failed with : " + e.getMessage()); + } + + return newState; + } + + // ======================================================================== + // Methods + public void clearAndSetBaseToCpuStack(StateStrings.CpuMode newCpuMode) { + mode_stack.clear(); + irq_stack.clear(); + softirq_stack.clear(); + trap_stack.clear(); + + // Ensure that there is always at least 1 item in the stack + mode_stack.push(newCpuMode); + irq_stack.push(-1L); + softirq_stack.push(-1L); + trap_stack.push(-1L); + } + + // Push to stacks + public void pushToCpuStack(StateStrings.CpuMode newCpuMode) { + mode_stack.push(newCpuMode); + } + + public void pushToIrqStack(Long irqID) { + irq_stack.push(irqID); + } + + public void pushToSoftIrqStack(Long softIrqID) { + softirq_stack.push(softIrqID); + } + + public void pushToTrapStack(Long trapID) { + trap_stack.push(trapID); + } + + // Pop from stacks + public StateStrings.CpuMode popFromCpuStack() { + + StateStrings.CpuMode returnedMode = mode_stack.pop(); + + if (mode_stack.size() < 1) { + // Ensure that there is always at least 1 item in the stack + mode_stack.push(StateStrings.CpuMode.LTTV_CPU_UNKNOWN); + } + + return returnedMode; + + } + + public Long popFromIrqStack() { + Long irq = irq_stack.pop(); + + if (irq_stack.size() < 1) { + // make sure the stack is not empty + irq_stack.push(-1L); + } + return irq; + } + + public Long popFromSoftIrqStack() { + Long softirq = softirq_stack.pop(); + + if (softirq_stack.size() < 1) { + // make sure the stack is not empty + softirq_stack.push(-1L); + } + return softirq; + } + + public Long popFromTrapStack() { + Long trap = trap_stack.pop(); + + if (trap_stack.size() < 1) { + // make sure the stack is not empty + trap_stack.push(-1L); + } + return trap; + } + + // Peek from stacks + public StateStrings.CpuMode peekFromCpuStack() { + return mode_stack.peek(); + } + + public Long peekFromIrqStack() { + return irq_stack.peek(); + } + + public Long peekFromSoftIrqStack() { + return softirq_stack.peek(); + } + + public Long peekFromTrapStack() { + return trap_stack.peek(); + } + + + public void reset() { + mode_stack.clear(); + irq_stack.clear(); + softirq_stack.clear(); + trap_stack.clear(); + + // Ensure that there is always at least 1 item in the stack + mode_stack.push(CpuMode.LTTV_CPU_UNKNOWN); + irq_stack.push(-1L); + softirq_stack.push(-1L); + trap_stack.push(-1L); + } + +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/model/LttngBdevState.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/model/LttngBdevState.java new file mode 100644 index 0000000000..808b94d7b3 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/model/LttngBdevState.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright (c) 2009 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: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.linuxtools.lttng.state.model; + +import java.util.Stack; + +import org.eclipse.linuxtools.lttng.TraceDebug; +import org.eclipse.linuxtools.lttng.state.StateStrings.BdevMode; + +/** + * LttvBdevState + *

+ * + */ +public class LttngBdevState implements Cloneable { + // ======================================================================== + // Data + // ======================================================================= + private Stack mode_stack = new Stack() ; + + + // ======================================================================== + // Constructor + // ======================================================================= + public LttngBdevState() { + mode_stack.push(BdevMode.LTTV_BDEV_UNKNOWN); + } + + // ======================================================================== + // Methods + // ======================================================================= + public void clearBdevStack() { + mode_stack.clear(); + } + + public void clearAndSetBaseToBdevStack(BdevMode newState) { + mode_stack.clear(); + // Ensure that there is always at least 1 item in the stack + mode_stack.push(newState); + } + + public void pushToBdevStack(BdevMode newState) { + mode_stack.push(newState); + } + + public BdevMode popFromBdevStack() { + + BdevMode returnedMode = mode_stack.pop(); + + if (mode_stack.size() < 1) { + TraceDebug.debug("Removing last item from mode stack is not allowed! (popFromModeStack)"); + mode_stack.push(BdevMode.LTTV_BDEV_UNKNOWN); + } + + return returnedMode; + } + + public BdevMode peekFromBdevStack() { + return mode_stack.peek(); + } + + + @Override + @SuppressWarnings("unchecked") + public LttngBdevState clone() { + LttngBdevState newState = null; + + try { + newState = (LttngBdevState)super.clone(); + // Clone should work correctly for all stack object that contain basic java object (String, Long, etc...) + newState.mode_stack = (Stack)this.mode_stack.clone(); + } + catch ( CloneNotSupportedException e ) { + System.out.println("Cloning failed with : " + e.getMessage() ); + } + + return newState; + } + +} \ No newline at end of file diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/model/LttngExecutionState.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/model/LttngExecutionState.java new file mode 100644 index 0000000000..4a19227466 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/model/LttngExecutionState.java @@ -0,0 +1,152 @@ +/******************************************************************************* + * Copyright (c) 2009 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: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.linuxtools.lttng.state.model; + +import org.eclipse.linuxtools.lttng.state.StateStrings; + +/** + * LttngExecutionState + *

+ * + */ +public class LttngExecutionState implements Cloneable { + // ======================================================================== + // Data + // ======================================================================= + private Long entry_LttTime = null; + private Long change_LttTime = null; + private Long cum_cpu_time_Timens = null; + + private StateStrings.ProcessStatus proc_status = StateStrings.ProcessStatus.LTTV_STATE_UNNAMED; + private StateStrings.ExecutionMode exec_mode = StateStrings.ExecutionMode.LTTV_STATE_MODE_UNKNOWN; + private String exec_submode = StateStrings.ExecutionSubMode.LTTV_STATE_SUBMODE_UNKNOWN.getInName(); + + @Override + public LttngExecutionState clone() { + LttngExecutionState newState = null; + + try { + newState = (LttngExecutionState)super.clone(); + + // *** IMPORTANT *** + // Basic type in java are immutable! + // Thus, using assignation ("=") on basic type is CORRECT, + // but we should ALWAYS use "new" or "clone()" on "non basic" type + newState.cum_cpu_time_Timens = this.cum_cpu_time_Timens; + newState.exec_submode = this.exec_submode; + + // ProcessStatus and ExecutionMode are enum, and so shouldn't be a problem to use their reference + newState.proc_status = this.proc_status; + newState.exec_mode = this.exec_mode; + newState.entry_LttTime = this.entry_LttTime; + newState.change_LttTime = this.change_LttTime; + } + catch ( CloneNotSupportedException e ) { + System.out.println("Cloning failed with : " + e.getMessage() ); + } + + return newState; + } + + // ======================================================================== + // Methods + // ======================================================================= + /** + * @return the entry_LttTime + */ + public Long getEntry_LttTime() { + return entry_LttTime; + } + + /** + * @param entryLttTime + * the entry_LttTime to set + */ + public void setEntry_Time(Long entryLttTime) { + entry_LttTime = entryLttTime; + } + + /** + * @return the change_LttTime + */ + public Long getChange_LttTime() { + return change_LttTime; + } + + /** + * @param changeLttTime + * the change_LttTime to set + */ + public void setChange_Time(Long changeLttTime) { + change_LttTime = changeLttTime; + } + + /** + * @return the cum_cpu_time_LttTime + */ + public Long getCum_cpu_time() { + return cum_cpu_time_Timens; + } + + /** + * @param cumCpuTimeLttTime + * the cum_cpu_time_LttTime to set + */ + public void setCum_cpu_time(Long cumCpuTime) { + cum_cpu_time_Timens = cumCpuTime; + } + + /** + * @return the proc_status + */ + public StateStrings.ProcessStatus getProc_status() { + return proc_status; + } + + /** + * @param procStatus + * the proc_status to set + */ + public void setProc_status(StateStrings.ProcessStatus procStatus) { + proc_status = procStatus; + } + + /** + * @return the exec_mode + */ + public StateStrings.ExecutionMode getExec_mode() { + return exec_mode; + } + + /** + * @param execMode + * the exec_mode to set + */ + public void setExec_mode(StateStrings.ExecutionMode execMode) { + exec_mode = execMode; + } + + /** + * @return the exec_submode + */ + public String getExec_submode() { + return exec_submode; + } + + /** + * @param execSubmode + * the exec_submode to set + */ + public void setExec_submode(String execSubmode) { + exec_submode = execSubmode; + } +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/model/LttngIRQState.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/model/LttngIRQState.java new file mode 100644 index 0000000000..94818ed0dc --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/model/LttngIRQState.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright (c) 2009 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: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.linuxtools.lttng.state.model; + +import java.util.Stack; + +import org.eclipse.linuxtools.lttng.state.StateStrings; +import org.eclipse.linuxtools.lttng.state.StateStrings.IRQMode; + +/** + * LttvIRQState + * @author alvaro + * + */ +public class LttngIRQState implements Cloneable { + // ======================================================================== + // Data + // ======================================================================= + private Stack mode_stack = new Stack(); + + // ======================================================================== + // Constructor + // ======================================================================= + public LttngIRQState() { + mode_stack.push(IRQMode.LTTV_IRQ_UNKNOWN); + } + + @Override + @SuppressWarnings("unchecked") + public LttngIRQState clone() { + LttngIRQState newState = null; + + try { + newState = (LttngIRQState)super.clone(); + + // Clone should work correctly for all stack object that contain basic java object (String, Long, etc...) + newState.mode_stack = (Stack)this.mode_stack.clone(); + } + catch ( CloneNotSupportedException e ) { + System.out.println("Cloning failed with : " + e.getMessage() ); + } + + return newState; + } + + // ======================================================================== + // Methods + // ======================================================================= + public void clearIrqStack() { + mode_stack.clear(); + } + + public void clearAndSetBaseToIrqStack(StateStrings.IRQMode newState) { + mode_stack.clear(); + // Ensure that there is always at least 1 item in the stack + mode_stack.push(newState); + } + + public void pushToIrqStack(StateStrings.IRQMode newState) { + mode_stack.push(newState); + } + + public StateStrings.IRQMode popFromIrqStack() { + + StateStrings.IRQMode returnedMode = mode_stack.pop(); + if (mode_stack.size() < 1) { + mode_stack.push(IRQMode.LTTV_IRQ_UNKNOWN); + } + + return returnedMode; + } + + public StateStrings.IRQMode peekFromIrqStack() { + return mode_stack.peek(); + } +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/model/LttngProcessState.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/model/LttngProcessState.java new file mode 100644 index 0000000000..63451594de --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/model/LttngProcessState.java @@ -0,0 +1,490 @@ +/******************************************************************************* + * Copyright (c) 2009 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: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.linuxtools.lttng.state.model; + +import java.util.Stack; + +import org.eclipse.linuxtools.lttng.TraceDebug; +import org.eclipse.linuxtools.lttng.state.StateStrings; +import org.eclipse.linuxtools.lttng.state.StateStrings.ExecutionMode; +import org.eclipse.linuxtools.lttng.state.StateStrings.ExecutionSubMode; +import org.eclipse.linuxtools.lttng.state.StateStrings.ProcessStatus; + +/** + * LttngProcessState + * + * @author alvaro + * + */ +public class LttngProcessState implements Cloneable { + // ======================================================================== + // Data + // ======================================================================= + private Long cpu = null; + private Long pid = null; + private Long tgid = null; + private String name = null; + private Long creation_time = null; + private String brand = null; + private StateStrings.ProcessType type = null; + private Long current_function = null; + private Long ppid = null; + private Long insertion_time = null; + private String pid_time = null; + private Long free_events = null; + private LttngExecutionState state = null; // top of stack + private Stack execution_stack = new Stack(); + private Stack user_stack = new Stack(); // user space + + private String userTrace = null; /* Associated file trace */ + private Long target_pid = null; /* target PID of the current event. */ + private String trace_id = null; + + // ======================================================================== + // Constructor + // ======================================================================= + public LttngProcessState(Long startTime, String traceId) { + this.cpu = 0L; + this.pid = 0L; + this.tgid = 0L; + this.name = StateStrings.ProcessStatus.LTTV_STATE_UNNAMED.getInName(); + this.insertion_time = startTime; + this.trace_id = ""; + init(); + } + + public LttngProcessState(Long cpu, Long pid, Long tgid, + String name, Long startTime, String traceId) { + this.cpu = cpu; + this.pid = pid; + this.tgid = tgid; + this.name = name; + this.insertion_time = startTime; + this.trace_id = traceId; + init(); + } + + // ======================================================================== + // Methods + // ======================================================================= + private void init() { + this.brand = StateStrings.LTTV_STATE_UNBRANDED; + this.type = StateStrings.ProcessType.LTTV_STATE_USER_THREAD; + this.current_function = 0L; + this.ppid = 0L; + this.creation_time = 0L; + this.free_events = 0L; + + // Initialise stack + LttngExecutionState es = new LttngExecutionState(); + es.setExec_mode(ExecutionMode.LTTV_STATE_USER_MODE); + es.setExec_submode(ExecutionSubMode.LTTV_STATE_SUBMODE_NONE.getInName()); + es.setEntry_Time(this.insertion_time); + es.setChange_Time(this.insertion_time); + es.setCum_cpu_time(0L); + es.setProc_status(ProcessStatus.LTTV_STATE_RUN); + this.execution_stack.push(es); + + //This second entry is needed when processes are created via a Fork event. + es = new LttngExecutionState(); + es.setExec_mode(ExecutionMode.LTTV_STATE_SYSCALL); + es + .setExec_submode(ExecutionSubMode.LTTV_STATE_SUBMODE_NONE + .getInName()); + es.setEntry_Time(this.insertion_time); + es.setChange_Time(this.insertion_time); + es.setCum_cpu_time(0L); + es.setProc_status(ProcessStatus.LTTV_STATE_WAIT_FORK); + this.execution_stack.push(es); + + // point state to the top of the stack + this.state = es; + } + + @Override + @SuppressWarnings("unchecked") + public LttngProcessState clone() { + LttngProcessState newState = null; + + try { + newState = (LttngProcessState)super.clone(); + + // *** IMPORTANT *** + // Basic type in java are immutable! + // Thus, using assignment ("=") on basic type is CORRECT, + // but we should ALWAYS use "new" or "clone()" on "non basic" type + newState.cpu = this.cpu; + newState.pid = this.pid; + newState.tgid = this.tgid; + newState.name = this.name; + newState.brand = this.brand; + newState.type = this.type; + newState.current_function = this.current_function; + newState.ppid = this.ppid; + newState.pid_time= this.pid_time; + newState.free_events = this.free_events; + newState.userTrace = this.userTrace; + newState.target_pid = this.target_pid; + newState.trace_id = this.trace_id; + newState.creation_time = this.creation_time; + newState.insertion_time = this.insertion_time; + + // Call clone on our own object is safe as Long it implements Clonable + newState.state = (LttngExecutionState)this.state.clone(); + + // Clone should work correctly for all stack object that contain basic java object (String, Long, etc...) + newState.user_stack = (Stack)this.user_stack.clone(); + + + // This is worst case : Stack that contain user defined object. We have to unstack it and clone every object in a new stack! + // Why does java does not call clone() for every object in the stack it clone? It would probably be too useful... + newState.execution_stack = new Stack(); + + // Work stack we will use to "pop" item + Stack tmpStack = new Stack(); + + // First, we pop every ExecutionState, and insert a CLONED copy into our new cloned stack + while ( this.execution_stack.empty() == false ) { + // Save a copy of the original reference + tmpStack.push(this.execution_stack.peek()); + // Push a CLONED copy into the new stack while poping it from the original stack + newState.execution_stack.push( this.execution_stack.pop().clone() ); + } + + // Second, we reinsert back our content into the original stack + while ( tmpStack.empty() == false ) { + // Pop the cloned copy and push it back into the original stack + this.execution_stack.push( tmpStack.pop() ); + } + } + catch ( CloneNotSupportedException e ) { + System.out.println("Cloning failed with : " + e.getMessage() ); + } + + return newState; + } + + + // ======================================================================== + // Methods + // ======================================================================= + /** + * @return the pid + */ + public Long getPid() { + return pid; + } + + /** + * @param pid + * the pid to set + */ + public void setPid(Long pid) { + this.pid = pid; + } + + /** + * @return the tgid + */ + public Long getTgid() { + return tgid; + } + + /** + * @param tgid + * the tgid to set + */ + public void setTgid(Long tgid) { + this.tgid = tgid; + } + + /** + * @return the ppid + */ + public Long getPpid() { + return ppid; + } + + /** + * @param ppid + * the ppid to set + */ + public void setPpid(Long ppid) { + this.ppid = ppid; + } + + /** + *

+ * When the parent pid is known, the creation time is also known and + * requires update + *

+ * + * @param ppid + * the ppid to set + */ + public void setPpid(Long ppid, Long creationTime) { + if (ppid != null) { + this.ppid = ppid; + } + + if (creationTime != null) { + setCreation_time(creationTime); + } + } + + /** + * @return the creation_time + */ + public Long getCreation_time() { + return creation_time; + } + + /** + * @param creationTime + * the creation_time to set + */ + public void setCreation_time(Long creationTime) { + if ( (creationTime != null) && (pid != null) ) { + creation_time = creationTime; + StringBuilder sb = new StringBuilder(this.pid.toString() + "-" + + creationTime.toString()); + this.pid_time = sb.toString(); + } + } + + /** + * @return the insertion_time + */ + public Long getInsertion_time() { + return insertion_time; + } + + /** + * @param insertionTime + * the insertion_time to set + */ + public void setInsertion_time(Long insertionTime) { + insertion_time = insertionTime; + } + + /** + * @return the name + */ + public String getName() { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) { + this.name = name; + } + + /** + * @return the brand + */ + public String getBrand() { + return brand; + } + + /** + * @param brand + * the brand to set + */ + public void setBrand(String brand) { + this.brand = brand; + } + + /** + * @return the prid_time + */ + public String getPid_time() { + return pid_time; + } + + /** + * @return the cpu + */ + public Long getCpu() { + return cpu; + } + + /** + * @param cpu + * the cpu to set + */ + public void setCpu(Long cpu) { + this.cpu = cpu; + } + + /** + * @return the current_function + */ + public Long getCurrent_function() { + return current_function; + } + + /** + * @param currentFunction + * the current_function to set + */ + public void setCurrent_function(Long currentFunction) { + current_function = currentFunction; + } + + /** + * @return the target_pid + */ + public Long getTarget_pid() { + return target_pid; + } + + /** + * @param targetPid + * the target_pid to set + */ + public void setTarget_pid(Long targetPid) { + target_pid = targetPid; + } + + public String getTrace_id() { + return trace_id; + } + + public void setTrace_id(String traceId) { + trace_id = traceId; + } + + /** + * @return the free_events + */ + public Long getFree_events() { + return free_events; + } + + /** + * @param freeEvents + * the free_events to set + */ + public void setFree_events(Long freeEvents) { + free_events = freeEvents; + } + + /** + * increment the nuber of free events + */ + public void incrementFree_events() { + ++free_events; + } + + /** + * @return the state + */ + public LttngExecutionState getState() { + return state; + } + + /** + * @param state + * the state to set + */ + public void setState(LttngExecutionState state) { + this.state = state; + } + + /** + * @return the type + */ + public StateStrings.ProcessType getType() { + return type; + } + + /** + * @param type + * the type to set + */ + public void setType(StateStrings.ProcessType type) { + this.type = type; + } + + /** + * @return the userTrace + */ + public String getUserTrace() { + return userTrace; + } + + /** + * @param userTrace + * the userTrace to set + */ + public void setUserTrace(String userTrace) { + this.userTrace = userTrace; + } + + + public void clearUserStack() { + user_stack.clear(); + } + + public void pushToUserStack(Long newState) { + user_stack.push(newState); + } + + public Long popFromUserStack() { + if (user_stack.size() <= 1) { + TraceDebug.debug("Removing last item from user stack is not allowed! (popFromUserStack)"); + return null; + } + else { + return user_stack.pop(); + } + } + + public Long peekFromUserStack() { + return user_stack.peek(); + } + + + + public void clearExecutionStack() { + execution_stack.clear(); + } + + public void pushToExecutionStack(LttngExecutionState newState) { + execution_stack.push(newState); + setState(newState); + } + + public LttngExecutionState popFromExecutionStack() { + if (execution_stack.size() <= 1) { + TraceDebug.debug("Removing last item from execution stack is not allowed! (popFromExecutionStack)"); + return null; + } + else { + LttngExecutionState popedState = execution_stack.pop(); + // adjust current state to the new top + setState(peekFromExecutionStack()); + return popedState; + } + } + + public LttngExecutionState peekFromExecutionStack() { + return execution_stack.peek(); + } + + public LttngExecutionState getFirstElementFromExecutionStack() { + return execution_stack.firstElement(); + } +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/model/LttngSoftIRQState.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/model/LttngSoftIRQState.java new file mode 100644 index 0000000000..64eafde258 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/model/LttngSoftIRQState.java @@ -0,0 +1,114 @@ +/******************************************************************************* + * Copyright (c) 2009 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: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.linuxtools.lttng.state.model; + +/** + * LttvSoftIRQState + * + * @author alvaro + * + */ +public class LttngSoftIRQState implements Cloneable { + + // ======================================================================== + // Data + // ======================================================================= + private Long pending = null; + private Long running = null; + + // ======================================================================== + // Constructor + // ======================================================================= + public LttngSoftIRQState() { + pending = 0L; + running = 0L; + } + + @Override + public LttngSoftIRQState clone() { + LttngSoftIRQState newState = null; + + try { + newState = (LttngSoftIRQState)super.clone(); + + // *** IMPORTANT *** + // Basic type in java are immutable! + // Thus, using assignment ("=") on basic type is CORRECT, + // but we should ALWAYS use "new" or "clone()" on "non basic" type + newState.pending = this.pending; + newState.running = this.running; + } + catch ( CloneNotSupportedException e ) { + System.out.println("Cloning failed with : " + e.getMessage() ); + } + + return newState; + } + + // ======================================================================== + // Methods + // ======================================================================= + /** + * @param pending + * the pending to set + */ + public void setPending(Long pending) { + this.pending = pending; + } + + /** + * @return the pending + */ + public Long getPending() { + return pending; + } + + /** + * @param running + * the running to set + */ + public void setRunning(Long running) { + this.running = running; + } + + /** + * @return the running + */ + public Long getRunning() { + return running; + } + + public void reset() { + pending = 0L; + running = 0L; + } + + public void incrementRunning() { + running ++; + } + + public void incrementPending() { + pending ++; + } + + public void decrementRunning() { + if (running > 0L) { + running--; + } + } + + public void decrementPending() { + if (pending > 0L) { + pending--; + } + } +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/model/LttngTraceState.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/model/LttngTraceState.java new file mode 100644 index 0000000000..cb1183fee9 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/model/LttngTraceState.java @@ -0,0 +1,566 @@ +/******************************************************************************* + * Copyright (c) 2009 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: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.linuxtools.lttng.state.model; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.eclipse.linuxtools.lttng.TraceDebug; +import org.eclipse.linuxtools.lttng.state.LttngStateException; +import org.eclipse.linuxtools.lttng.state.StateStrings; +import org.eclipse.linuxtools.lttng.state.StateStrings.ExecutionMode; +import org.eclipse.linuxtools.lttng.state.StateStrings.ExecutionSubMode; +import org.eclipse.linuxtools.lttng.state.StateStrings.IRQMode; +import org.eclipse.linuxtools.lttng.state.StateStrings.ProcessStatus; +import org.eclipse.linuxtools.lttng.state.resource.ILttngStateContext; +import org.eclipse.linuxtools.tmf.event.TmfTimeRange; + +/** + * LttngTraceState + *

+ * + */ +/** + * @author alvaro + * + */ +public class LttngTraceState implements Cloneable { + // ======================================================================== + // Data + // ======================================================================= + + private Long save_interval = null; + + private Long max_time_state_recomputed_in_seek = null; + private boolean has_precomputed_states = false; + + private HashMap processes = new HashMap(); + + // by cpu + private Map running_process = new HashMap(); + + // Get state tables + private Map cpu_states = new HashMap(); + private Map irq_states = new HashMap(); + private Map soft_irq_states = new HashMap(); + private Map trap_states = new HashMap(); + private Map bdev_states = new HashMap(); + + // Get name tables + private Map syscall_names = new HashMap(); + private Map kprobe_table = new HashMap(); + private Map soft_irq_names = new HashMap(); + private Map trap_names = new HashMap(); + private Map irq_names = new HashMap(); + + private int nb_events = 0; + + // reference to input data provider + ILttngStateContext fContext = null; + String traceId = ""; + + // ======================================================================== + // Constructor + // ======================================================================= + LttngTraceState() { + // Get name tables + StateStrings strings = StateStrings.getInstance(); + + // initialize sycall_names + String[] ref_name_table = strings.getSyscallNames(); + for (Long i = 0L; i < ref_name_table.length; i++) { + syscall_names.put(i, ref_name_table[i.intValue()]); + } + + // trap names + ref_name_table = strings.getTrapNames(); + for (Long i = 0L; i < ref_name_table.length; i++) { + trap_names.put(i, ref_name_table[i.intValue()]); + } + + // irq names + ref_name_table = strings.getIrqNames(); + for (Long i = 0L; i < ref_name_table.length; i++) { + irq_names.put(i, ref_name_table[i.intValue()]); + } + + // softirq names + ref_name_table = strings.getSoftIrqNames(); + for (Long i = 0L; i < ref_name_table.length; i++) { + soft_irq_names.put(i, ref_name_table[i.intValue()]); + } + } + + // ======================================================================= + // Methods + // ======================================================================= + @Override + public LttngTraceState clone() { + LttngTraceState newState = null; + + try { + newState = (LttngTraceState) super.clone(); + + // *** IMPORTANT *** + // Basic type in java are immutable! + // Thus, using assignment ("=") on basic type is CORRECT, + // but we should ALWAYS use "new" or "clone()" on "non basic" type + newState.save_interval = this.save_interval; + newState.traceId = this.traceId; + + // Basic value only need to be assigned while cloning + newState.has_precomputed_states = this.has_precomputed_states; + newState.nb_events = this.nb_events; + newState.max_time_state_recomputed_in_seek = this.max_time_state_recomputed_in_seek; + + // Clone should work correctly for all stack object that contain + // basic java object (String, Long, etc...) + newState.syscall_names = this.syscall_names; + newState.kprobe_table = this.kprobe_table; + newState.soft_irq_names = this.soft_irq_names; + newState.trap_names = this.trap_names; + newState.irq_names = this.irq_names; + + // This reference should never need to be updated, should it? + newState.fContext = this.fContext; + + // *** We need loop on each ArrayList and HashMap, as java implement + // nothing that's remotely near deep copying. + // *** TODO *** + // In the future, implement something better here... serialization + // perhaps? Or copy the array chunk of memory in C? + + Iterator iteratorL = null; + Iterator iteratorP = null; + Long mapKey = null; + ProcessStateKey processKey = null; + + newState.processes = new HashMap(); + iteratorP = this.processes.keySet().iterator(); + while (iteratorP.hasNext()) { + processKey = iteratorP.next(); + newState.processes.put(processKey, this.processes.get(processKey).clone()); + } + + newState.running_process = new HashMap(); + iteratorL = this.running_process.keySet().iterator(); + while (iteratorL.hasNext()) { + mapKey = iteratorL.next(); + newState.running_process.put(mapKey, this.running_process.get(mapKey).clone()); + } + + newState.cpu_states = new HashMap(); + iteratorL = this.cpu_states.keySet().iterator(); + while (iteratorL.hasNext()) { + mapKey = iteratorL.next(); + newState.cpu_states.put(mapKey, this.cpu_states.get(mapKey) + .clone()); + } + + newState.irq_states = new HashMap(); + iteratorL = this.irq_states.keySet().iterator(); + while (iteratorL.hasNext()) { + mapKey = iteratorL.next(); + newState.irq_states.put(mapKey, this.irq_states.get(mapKey) + .clone()); + } + + newState.soft_irq_states = new HashMap(); + iteratorL = this.soft_irq_states.keySet().iterator(); + while (iteratorL.hasNext()) { + mapKey = iteratorL.next(); + newState.soft_irq_states.put(mapKey, this.soft_irq_states.get( + mapKey).clone()); + } + + newState.trap_states = new HashMap(); + iteratorL = this.trap_states.keySet().iterator(); + while (iteratorL.hasNext()) { + mapKey = iteratorL.next(); + newState.trap_states.put(mapKey, this.trap_states.get(mapKey) + .clone()); + } + + newState.bdev_states = new HashMap(); + iteratorL = this.bdev_states.keySet().iterator(); + while (iteratorL.hasNext()) { + mapKey = iteratorL.next(); + newState.bdev_states.put(mapKey, this.bdev_states.get(mapKey) + .clone()); + } + + } catch (CloneNotSupportedException e) { + System.out.println("Cloning failed with : " + e.getMessage()); + } + + return newState; + } + + public void init(ILttngStateContext context) + throws LttngStateException { + if (context == null) { + StringBuilder sb = new StringBuilder( + "The input provider reference must not be null"); + throw new LttngStateException(sb.toString()); + } + + // Save the input data reference + fContext = context; + + // Save traceid + traceId = fContext.getTraceId(); + + // max time + max_time_state_recomputed_in_seek = 0L; + + // reset cpu_states + cpu_states.clear(); + + // Obtain the total num of available CPUs and initialize the map + // to the corresponding size + int numCpus = fContext.getNumberOfCpus(); + for (Long i = 0L; i < numCpus; i++) { + cpu_states.put(i, new LTTngCPUState()); + } + + // irq states + irq_states.clear(); + for (Long i = 0L; i < irq_names.size(); i++) { + irq_states.put(i, new LttngIRQState()); + } + + // soft irqs + soft_irq_states.clear(); + for (Long i = 0L; i < soft_irq_names.size(); i++) { + soft_irq_states.put(i, new LttngSoftIRQState()); + } + + // traps + trap_states.clear(); + for (Long i = 0L; i < trap_names.size(); i++) { + trap_states.put(i, new LttngTrapState(0L)); + } + + // bdev states + bdev_states.clear(); + + processes.clear(); + + nb_events = 0; + TmfTimeRange timeWin = fContext.getTraceTimeWindow(); + + /* Put the per cpu running_process to beginning state : process 0. */ + for (Long i = 0L; i < numCpus; i++) { + LttngProcessState process = new LttngProcessState(timeWin.getStartTime().getValue(), traceId ); + + /* + * We are not sure is it's a kernel thread or normal thread, put the + * bottom stack state to unknown + */ + LttngExecutionState es = process.getFirstElementFromExecutionStack(); + process.setState(es); + es.setExec_mode(ExecutionMode.LTTV_STATE_MODE_UNKNOWN); + es.setExec_submode(ExecutionSubMode.LTTV_STATE_SUBMODE_NONE + .getInName()); + es.setProc_status(ProcessStatus.LTTV_STATE_UNNAMED); + + // Reduce from default to only one execution state in the stack + process.popFromExecutionStack(); + + process.setCpu(i); + // no associated user trace yet + process.setUserTrace(""); + // processes.put(i, process); + running_process.put(i, process); + // reset cpu states + LTTngCPUState cpuState = cpu_states.get(i); + cpuState.reset(); + // Add the new process to the list + processes.put(new ProcessStateKey(process), process); + } + + // reset irq_states + for (Long key : irq_states.keySet()) { + LttngIRQState irqState = irq_states.get(key); + irqState.clearAndSetBaseToIrqStack(IRQMode.LTTV_IRQ_UNKNOWN); + } + + // reset soft_irq_states + for (Long key : soft_irq_states.keySet()) { + LttngSoftIRQState softIrqState = soft_irq_states.get(key); + softIrqState.reset(); + } + + // reset trap_states + for (Long key : trap_states.keySet()) { + LttngTrapState trapState = trap_states.get(key); + trapState.setRunning(0L); + } + + // reset bdev_states + for (Long key : bdev_states.keySet()) { + LttngBdevState bdevState = bdev_states.get(key); + bdevState.clearBdevStack(); + } + + } + + public Long getSave_interval() { + return save_interval; + } + + public void setSave_interval(Long saveInterval) { + save_interval = saveInterval; + } + + /** + * @return total number of CPUs registered as read from the Trace + */ + public int getNumberOfCPUs() { + return fContext.getNumberOfCpus(); + } + + /** + * Provide access to input data not necessarily at Trace level + * + * @return + */ + public ILttngStateContext getContext() { + return fContext; + } + + public Long getMax_time_state_recomputed_in_seek() { + return max_time_state_recomputed_in_seek; + } + + public void setMax_time_state_recomputed_in_seek( + Long maxTimeStateRecomputedInSeek) { + max_time_state_recomputed_in_seek = maxTimeStateRecomputedInSeek; + } + + public boolean isHas_precomputed_states() { + return has_precomputed_states; + } + + public void setHas_precomputed_states(boolean hasPrecomputedStates) { + has_precomputed_states = hasPrecomputedStates; + } + + public Map getRunning_process() { + return running_process; + } + + public Map getSyscall_names() { + return syscall_names; + } + + public Map getTrap_names() { + return trap_names; + } + + public Map getIrq_names() { + return irq_names; + } + + public Map getSoft_irq_names() { + return soft_irq_names; + } + + public Map getCpu_states() { + return cpu_states; + } + + public Map getIrq_states() { + return irq_states; + } + + public Map getSoft_irq_states() { + return soft_irq_states; + } + + public Map getTrap_states() { + return trap_states; + } + + public Map getBdev_states() { + return bdev_states; + } + + public Map getKprobe_table() { + return kprobe_table; + } + + /** + * @return the traceId + */ + public String getTraceId() { + return traceId; + } + + /** + * Return an array of Processes + * + * @return LttngProcessState + */ + public LttngProcessState[] getProcesses() { + return processes.values().toArray(new LttngProcessState[processes.size()]); + } + + /** + * Clear all process state items e.g. when a new experiment is selected + */ + public void clearProcessState() { + processes.clear(); + } + + /** + * Interface to add process state. + * + * @param newProcessState + */ + public void addProcessState(LttngProcessState newProcessState) { + if (newProcessState != null) { + processes.put( new ProcessStateKey(newProcessState), newProcessState); + } + } + + /** + * Interface to remove process state. + * + * @param oldProcessState + */ + public void removeProcessState(LttngProcessState oldProcessState) { + if (oldProcessState != null) { + processes.remove(new ProcessStateKey(oldProcessState)); + } + } + + /** + * Search by keys (pid, cpuId and traceId)

+ * + * A match is returned if the three arguments received match an entry + * Otherwise null is returned + * + * @param searchedPid The processId (Pid) we are looking for + * @param searchedCpuId The cpu Id we are looking for + * @param searchedTraceID The traceId (trace name?) we are looking for + * + * @return LttngProcessState + */ + public LttngProcessState findProcessState(Long searchedPid, Long searchedCpuId, String searchedTraceID) { + // Get the TimeRangeEventProcess associated to a key we create here + LttngProcessState foundProcess = processes.get( new ProcessStateKey(searchedPid, searchedCpuId, searchedTraceID) ); + + return foundProcess; + } + + +} + +class ProcessStateKey { + private LttngProcessState valueRef = null; + + private Long pid = null; + private Long cpuId = null; + private String traceId = null; + + @SuppressWarnings("unused") + private ProcessStateKey() { } + + public ProcessStateKey(LttngProcessState newRef) { + valueRef = newRef; + } + + public ProcessStateKey(Long newPid, Long newCpuId, String newTraceId) { + pid = newPid; + cpuId = newCpuId; + traceId = newTraceId; + } + + @Override + public boolean equals(Object obj) { + boolean isSame = false; + + if ( obj instanceof ProcessStateKey ) { + ProcessStateKey procKey = (ProcessStateKey) obj; + + if ( valueRef != null ) { + if ( (procKey.getPid().equals(valueRef.getPid()) ) && + (procKey.getTraceId().equals(valueRef.getTrace_id()) ) && + ( (procKey.getCpuId().longValue() == 0L ) || (procKey.getCpuId().equals(valueRef.getCpu())) ) ) + { + isSame = true; + } + } + else { + if ( (procKey.getPid().equals(this.pid) ) && + (procKey.getTraceId().equals(this.traceId) ) && + ( (procKey.getCpuId().longValue() == 0L ) || (procKey.getCpuId().equals(this.cpuId)) ) ) + { + isSame = true; + } + } + } + else { + TraceDebug + .debug("ERROR : The received Key is not of the type ProcessStateKey! but " + + obj.getClass().toString()); + } + + return isSame; + } + + // *** WARNING : Everything in there work because the check "valueRef != null" is the same for ALL getter + // Do NOT change this check without checking. + public Long getPid() { + if ( valueRef != null ) { + return valueRef.getPid(); + } + else { + return pid; + } + } + + public Long getCpuId() { + if ( valueRef != null ) { + return valueRef.getCpu(); + } + else { + return cpuId; + } + } + + public String getTraceId() { + if ( valueRef != null ) { + return valueRef.getTrace_id(); + } + else { + return traceId; + } + } + + @Override + public int hashCode() { + return this.toString().hashCode(); + } + + + @Override + public String toString() { + if ( valueRef != null ) { + return (valueRef.getPid().toString() + ":" + valueRef.getCpu().toString() + ":" + valueRef.getTrace_id().toString() ); + } + + return (pid.toString() + ":" + cpuId.toString() + ":" + traceId.toString()); + } +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/model/LttngTrapState.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/model/LttngTrapState.java new file mode 100644 index 0000000000..94dba7db07 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/model/LttngTrapState.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (c) 2009 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: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.linuxtools.lttng.state.model; + + + +/** + * LttvTrapState + *

+ * + */ +public class LttngTrapState implements Cloneable { + // ======================================================================== + // Data + // ======================================================================= + private Long running; + + + // ======================================================================== + // Constructor + // ======================================================================= + + public LttngTrapState() { + this.running = 0L; + } + + public LttngTrapState(Long running) { + this.running = running; + } + + @Override + public LttngTrapState clone() { + LttngTrapState newState = null; + + try { + newState = (LttngTrapState)super.clone(); + + // *** IMPORTANT *** + // Basic type in java are immutable! + // Thus, using assignation ("=") on basic type is CORRECT, + // but we should ALWAYS use "new" or "clone()" on "non basic" type + newState.running = this.running; + } + catch ( CloneNotSupportedException e ) { + System.out.println("Cloning failed with : " + e.getMessage() ); + } + + return newState; + } + + // ======================================================================== + // Methods + // ======================================================================= + public Long getRunning() { + return running; + } + + public void setRunning(Long running) { + this.running = running; + } + + public void incrementRunning() { + running++; + } + + public void decrementRunning() { + if (running > 0) { + running--; + } + } + + @Override + public String toString() { + return "running : " + running; + } + +} \ No newline at end of file diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/model/StateModelFactory.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/model/StateModelFactory.java new file mode 100644 index 0000000000..8ab180e119 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/model/StateModelFactory.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2009 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: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.linuxtools.lttng.state.model; + +import org.eclipse.linuxtools.lttng.state.LttngStateException; +import org.eclipse.linuxtools.lttng.state.resource.ILttngStateContext; + +/** + * Entry point to the package + * + * @author alvaro + * + */ +public class StateModelFactory { + + // ======================================================================== + // Methods + // ======================================================================= + + /** + * Return an instance of the entry class, the entry class contains + * references to the internal model elements. + * + * One instance is expected to be created per LttngTrace. + * + * This method shall be used when a trace is not opened yet and will be + * initialized later via the init() method. + * + * @return + */ + public static LttngTraceState getStateEntryInstance() { + return new LttngTraceState(); + } + + /** + * Provide a LttngTraceState when the input data reference is known e.g. + * when exchanging the State provider to check point clone. + * + * @return + */ + public static LttngTraceState getStateEntryInstance( + ILttngStateContext stateInputRef) { + LttngTraceState traceState = new LttngTraceState(); + try { + traceState.init(stateInputRef); + } catch (LttngStateException e) { + e.printStackTrace(); + } + return traceState; + } +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/resource/ILTTngStateResource.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/resource/ILTTngStateResource.java new file mode 100644 index 0000000000..aa9596c2d0 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/resource/ILTTngStateResource.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 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: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.linuxtools.lttng.state.resource; + +import org.eclipse.linuxtools.lttng.model.ILTTngTreeNode; + +/** + * @author alvaro + * + */ +public interface ILTTngStateResource> extends + ILTTngTreeNode { + + // ======================================================================== + // Interface methods + // ======================================================================= + /** + * @return + */ + public GlobalStateMode getStateMode(); + + /** + * @return + */ + public ILttngStateContext getContext(); + + // ======================================================================== + // Interface Enums + // ======================================================================= + /** + *

+ * Represents the specific type of resources known by the application + *

+ * + */ + public enum ResourceType { + LTT_RESOURCE_PROCESS("process"), /* */ + LTT_RESOURCE_CPU("cpu"), /* */ + LTT_RESOURCE_BDEV("bdev"), /* */ + LTT_RESOURCE_IRQ("irq"), /* */ + LTT_RESOURCE_SOFTIRQ("softIrq"), /* */ + LTT_RESOURCE_TRAP("trap"), /* */ + LTT_RESOURCE_RUNNING_PROCESS("running"); /* */ + + String inName; + + private ResourceType(String name) { + this.inName = name; + } + + public String getInName() { + return this.inName; + } + } + + /** + *

unifies the possible states of the state resources known by the application

+ * + */ + public enum GlobalStateMode { + LTT_STATEMODE_UNNAMED("unnamed"), /* */ + LTT_STATEMODE_UNKNOWN("unknown"), /* */ + LTT_STATEMODE_IDLE("idle"), /* */ + LTT_STATEMODE_BUSY("busy"), /* */ + LTT_STATEMODE_PENDING("pending"), /* */ + LTT_STATEMODE_READING("reading"), /* */ + LTT_STATEMODE_WRITING("writing"), /* */ + LTT_STATEMODE_IRQ("irq"), /* */ + LTT_STATEMODE_SOFTIRQ("softirq"), /* */ + LTT_STATEMODE_TRAP("trap"), /* */ + LTT_STATEMODE_WAIT_FORK("waitfork"), /* */ + LTT_STATEMODE_WAIT_CPU("waitcpu"), /* */ + LTT_STATEMODE_EXIT("exit"), /* */ + LTT_STATEMODE_ZOMBIE("zombie"), /* */ + LTT_STATEMODE_WAIT_IO("waitio"), /* */ + LTT_STATEMODE_RUN("run"), /* */ + LTT_STATEMODE_DEAD("dead"), /* */ + LTT_STATEMODE_USER_MODE("usermode"), /* */ + LTT_STATEMODE_SYSCALL("syscall"); /* */ + + + String inName; + + private GlobalStateMode(String name) { + this.inName = name; + } + + public String getInName() { + return this.inName; + } + } + +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/resource/ILttngStateContext.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/resource/ILttngStateContext.java new file mode 100644 index 0000000000..b99d76b81f --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/resource/ILttngStateContext.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 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: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.linuxtools.lttng.state.resource; + +import org.eclipse.linuxtools.tmf.event.TmfTimeRange; +import org.eclipse.linuxtools.tmf.trace.ITmfTrace; + +/** + * ILttngStateContext + *

Provides context information of a State system instance

+ * + */ + +/** + * @author alvaro + * + */ +public interface ILttngStateContext { + + /** + * Returns the number of CPUs available in the Trace + * + * @return + */ + public int getNumberOfCpus(); + + /** + * The current time range window covering the Trace + * + * @return + */ + public TmfTimeRange getTraceTimeWindow(); + + /** + * The current time range window covering the Experiment + * + * @return + */ + public TmfTimeRange getExperimentTimeWindow(); + + /** + * Returns the name of the associated experiment + * + * @return + */ + public String getExperimentName(); + + /** + * Returns the corresponding trace id. + * + * @return + */ + public String getTraceId(); + + /** + * Returns the corresponding trace id reference + * + * @return + */ + public ITmfTrace getTraceIdRef(); + +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/resource/LTTngStateResource.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/resource/LTTngStateResource.java new file mode 100644 index 0000000000..adffb37a88 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/resource/LTTngStateResource.java @@ -0,0 +1,94 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 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: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.linuxtools.lttng.state.resource; + +import org.eclipse.linuxtools.lttng.TraceDebug; +import org.eclipse.linuxtools.lttng.model.LTTngTreeNodeGeneric; +import org.eclipse.linuxtools.lttng.state.resource.ILTTngStateResource.GlobalStateMode; + +/** + * @author alvaro + * + */ +public class LTTngStateResource extends + LTTngTreeNodeGeneric { + + // ======================================================================== + // Data + // ======================================================================= + private GlobalStateMode fstateMode = GlobalStateMode.LTT_STATEMODE_UNKNOWN; + private final ILttngStateContext fcontext; + + // ======================================================================+ + // Constructors + // ======================================================================= + + public LTTngStateResource(Long id, LTTngStateResource parent, String name, + ILttngStateContext context, Object value) { + super(id, parent, name, value); + fcontext = context; + } + + public LTTngStateResource(Long id, String name, ILttngStateContext context, + Object value) { + super(id, name, value); + fcontext = context; + } + + // ======================================================================== + // Methods + // ======================================================================= + /* + * (non-Javadoc) + * + * @see + * org.eclipse.linuxtools.lttng.control.LTTngStateTreeNodeGeneric#getChildren + * () + */ + public LTTngStateResource[] getChildren() { + return childrenToArray(fchildren.values(), this.getClass()); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.linuxtools.lttng.state.resource.ILTTngStateResource#getStateMode + * () + */ + public GlobalStateMode getStateMode() { + return fstateMode; + } + + /** + * @param stateMode + */ + public void setStateMode(GlobalStateMode stateMode) { + if (stateMode != null) { + fstateMode = stateMode; + } else { + TraceDebug.debug("Received input is null !"); + } + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.linuxtools.lttng.state.resource.ILTTngStateResource#getContext + * () + */ + public ILttngStateContext getContext() { + return fcontext; + } + +} diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/trace/IStateTraceManager.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/trace/IStateTraceManager.java new file mode 100644 index 0000000000..29ed0cf1ee --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/trace/IStateTraceManager.java @@ -0,0 +1,64 @@ +package org.eclipse.linuxtools.lttng.state.trace; + +import org.eclipse.linuxtools.lttng.request.ILttngSyntEventRequest; +import org.eclipse.linuxtools.lttng.request.IRequestStatusListener; +import org.eclipse.linuxtools.lttng.signal.ILttExperimentSelectedListener; +import org.eclipse.linuxtools.lttng.state.evProcessor.ITransEventProcessor; +import org.eclipse.linuxtools.lttng.state.model.LttngTraceState; +import org.eclipse.linuxtools.tmf.event.TmfTimeRange; +import org.eclipse.linuxtools.tmf.event.TmfTimestamp; +import org.eclipse.linuxtools.tmf.trace.ITmfTrace; + +public interface IStateTraceManager extends ILttExperimentSelectedListener { + /** + * TODO: Not ready for threading + *

+ * Read events within specific time window, e.g. time range selection + *

+ * + * @param trange + * @param source + * @param listener + * @param processor + * @return + */ + public abstract ILttngSyntEventRequest executeDataRequest( + TmfTimeRange trange, Object source, + IRequestStatusListener listener, ITransEventProcessor processor); + + /** + * used to obtain details on the log associated with this manager e.g. + * logid. + * + * @return + */ + public abstract ITmfTrace getTrace(); + + /** + * Restore to the closest checkpoint from TmfTimestamp + *

+ * Note : it is heavier to restore by timestamp than by event position, + * restore by event position whichever possible. + * + * @param eventTime + * The timestamp of the event to restore to + * + * @return TmfTimestamp indicates the nearest time used to restore the + * state, null sent if input is invalid + */ + public abstract TmfTimestamp restoreCheckPointByTimestamp( + TmfTimestamp eventTime); + + /** + * @return + */ + public abstract TmfTimeRange getExperimentTimeWindow(); + + /** + * Returns the State model instance associated with this Trace + * + * @return + */ + public abstract LttngTraceState getStateModel(); + +} \ No newline at end of file diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/trace/StateTraceManager.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/trace/StateTraceManager.java new file mode 100644 index 0000000000..479e8d1b4d --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/trace/StateTraceManager.java @@ -0,0 +1,637 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 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: + * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.linuxtools.lttng.state.trace; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Vector; + +import org.eclipse.linuxtools.lttng.TraceDebug; +import org.eclipse.linuxtools.lttng.event.LttngEvent; +import org.eclipse.linuxtools.lttng.event.LttngSyntheticEvent; +import org.eclipse.linuxtools.lttng.event.LttngSyntheticEvent.SequenceInd; +import org.eclipse.linuxtools.lttng.event.LttngTimestamp; +import org.eclipse.linuxtools.lttng.model.LTTngTreeNode; +import org.eclipse.linuxtools.lttng.request.ILttngSyntEventRequest; +import org.eclipse.linuxtools.lttng.request.IRequestStatusListener; +import org.eclipse.linuxtools.lttng.request.LttngSyntEventRequest; +import org.eclipse.linuxtools.lttng.state.LttngStateException; +import org.eclipse.linuxtools.lttng.state.evProcessor.ITransEventProcessor; +import org.eclipse.linuxtools.lttng.state.evProcessor.state.StateEventToHandlerFactory; +import org.eclipse.linuxtools.lttng.state.model.LttngTraceState; +import org.eclipse.linuxtools.lttng.state.model.StateModelFactory; +import org.eclipse.linuxtools.lttng.state.resource.ILttngStateContext; +import org.eclipse.linuxtools.lttng.trace.LTTngTextTrace; +import org.eclipse.linuxtools.lttng.trace.LTTngTrace; +import org.eclipse.linuxtools.tmf.component.TmfEventProvider; +import org.eclipse.linuxtools.tmf.event.TmfEvent; +import org.eclipse.linuxtools.tmf.event.TmfTimeRange; +import org.eclipse.linuxtools.tmf.event.TmfTimestamp; +import org.eclipse.linuxtools.tmf.experiment.TmfExperiment; +import org.eclipse.linuxtools.tmf.request.TmfDataRequest; +import org.eclipse.linuxtools.tmf.signal.TmfExperimentUpdatedSignal; +import org.eclipse.linuxtools.tmf.trace.ITmfTrace; +import org.eclipse.linuxtools.tmf.trace.TmfCheckpoint; +import org.eclipse.linuxtools.tmf.trace.TmfLocation; + +public class StateTraceManager extends LTTngTreeNode implements + IStateTraceManager, ILttngStateContext { + + // constants + private static final long DEFAULT_OFFSET = 0L; + private static final int DEFAULT_CHUNK = 1; + + // configurable check point interval + private static final long LTTNG_CHECK_POINT_INTERVAL = 15000L; + private long fcheckPointInterval = LTTNG_CHECK_POINT_INTERVAL; + + private TmfExperiment fExperiment = null; + + // immutable Objects + private final ITmfTrace fTrace; + private int fcpuNumber = -1; + private final ITransEventProcessor fStateUpdateProcessor; + + // potentially thread shared + private final HashMap stateCheckpointsList = new HashMap(); + private final Vector timestampCheckpointsList = new Vector(); + private LttngTraceState fStateModel; + private int selectionCount = 0; + + // locks + private Object checkPointsLock = new Object(); + + /** + * Could be fixed to trace level from received trace, however preparation + * for multiple threads is necessary, a common synthetic event provider at + * experiment level is a good start although can be adjusted externally + */ + private TmfEventProvider fSynEventProvider; + + + // ======================================================================= + // Constructor + // ======================================================================= + /** + * @param id + * @param parent + * @param name + * @param trace + * @param stateModel + * @param eventProvider + * @throws LttngStateException + */ + public StateTraceManager(Long id, LTTngTreeNode parent, String name, + ITmfTrace trace, LttngTraceState stateModel, + TmfEventProvider eventProvider) + throws LttngStateException { + super(id, parent, name, trace); + + if (trace == null) { + throw new LttngStateException("No TmfTrace object available!"); + } + + fTrace = trace; + fStateModel = stateModel; + fStateModel.init(this); + fStateUpdateProcessor = StateEventToHandlerFactory.getInstance(); + fSynEventProvider = eventProvider; + init(); + } + + // ======================================================================= + // Methods + // ======================================================================= + @SuppressWarnings("unchecked") + private void init() { + // resolve the experiment + Object obj = getParent().getValue(); + if (obj != null && obj instanceof TmfExperiment) { + fExperiment = (TmfExperiment) obj; + } + + // initialize the number of cpus + if (fTrace instanceof LTTngTrace) { + fcpuNumber = ((LTTngTrace) fTrace).getCpuNumber(); + } else if (fTrace instanceof LTTngTextTrace) { + fcpuNumber = ((LTTngTextTrace) fTrace).getCpuNumber(); + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.linuxtools.lttng.signal.ILttExperimentSelectedListener# + * experimentSelected(java.lang.Object, + * org.eclipse.linuxtools.tmf.experiment.TmfExperiment) + */ + public void experimentSelected(Object source, + TmfExperiment experiment) { + // Only update experiment is needed for the time being + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.linuxtools.lttng.signal.ILttExperimentSelectedListener# + * experimentUpdated + * (org.eclipse.linuxtools.tmf.signal.TmfExperimentUpdatedSignal) + */ + public void experimentUpdated(TmfExperimentUpdatedSignal signal, boolean wait) { + // initialise check points once per new experiment selection + + synchronized (checkPointsLock) { + stateCheckpointsList.clear(); + timestampCheckpointsList.clear(); + } + + // requested time window from trace start to end, this to + // make sure one thread is used so the events arrive in order for proper + // building of the checkpoints + TmfTimeRange adjustedRange = new TmfTimeRange(fTrace.getTimeRange() + .getStartTime(), fTrace.getTimeRange().getEndTime()); + // Obtain a dataRequest to pass to the processRequest function + ILttngSyntEventRequest request = getDataRequestStateSave(adjustedRange, + null, fStateUpdateProcessor); + request.setclearDataInd(true); + request.startRequestInd(fSynEventProvider); + if (wait) { + try { + request.waitForCompletion(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager# + * executeDataRequest(org.eclipse.linuxtools.tmf.event.TmfTimeRange, + * java.lang.Object, + * org.eclipse.linuxtools.lttng.request.IRequestStatusListener, + * org.eclipse.linuxtools.lttng.state.evProcessor.ITransEventProcessor) + */ + public ILttngSyntEventRequest executeDataRequest(TmfTimeRange trange, + Object source, + IRequestStatusListener listener, ITransEventProcessor processor) { + TmfTimestamp restoredStartTime = restoreCheckPointByTimestamp(trange + .getStartTime()); + // Adjust the time range to consider rewinding to the start time + trange = new TmfTimeRange(restoredStartTime, trange.getEndTime()); + // Get a data request for the time range we want (nearest checkpoint + // to timestamp wanted) + + // Process request to that point + ILttngSyntEventRequest request = getDataRequestByTimeRange(trange, + listener, processor); + request.setSource(source); + + // don't wait for completion i.e. allow cancellations + request.startRequestInd(fSynEventProvider); + // fSynEventProvider + // .sendRequest((TmfDataRequest) request); + + if (TraceDebug.isDEBUG()) { + TraceDebug + .debug(" Time Window requested, (start adjusted to checkpoint): " + + trange.getStartTime() + + "-" + + trange.getEndTime() + + " Total number of processes in the State provider: " + + fStateModel.getProcesses().length + " Completed"); + } + + return request; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.linuxtools.lttng.state.IStateManager#getEventLog() + */ + public ITmfTrace getTrace() { + return fTrace; + } + + /** + * Save a checkpoint if it is needed at that point + *

+ * The function will use "eventCount" internally to determine if a save was + * needed + * + * @param eventCounter + * The event "count" or event "id" so far + * @param eventTime + * The timestamp of this event + * + * @return boolean True if a checkpoint was saved, false otherwise + */ + private void saveCheckPointIfNeeded(Long eventCounter, + TmfTimestamp eventTime) { + // Save a checkpoint every LTTNG_STATE_SAVE_INTERVAL event + if ((eventCounter.longValue() % fcheckPointInterval) == 0) { + LttngTraceState stateCheckPoint; + synchronized (fStateModel) { + stateCheckPoint = fStateModel.clone(); + } + + TraceDebug.debug("Check point created here: " + eventCounter + + " -> " + eventTime.toString() + "************" + + getTrace().getName() + " >>>>> Thread: " + + Thread.currentThread().getId()); + + synchronized (checkPointsLock) { + // Save the checkpoint + stateCheckpointsList.put(eventCounter, stateCheckPoint); + // Save correlation between timestamp and checkpoint index + + timestampCheckpointsList.add(new TmfCheckpoint( + new TmfTimestamp(eventTime), new TmfLocation( + eventCounter))); + } + } + } + + /** + * @return the lttng_check_point_interval + */ + public long getCheckPointInterval() { + return fcheckPointInterval; + } + + /** + * @param check_point_interval + * , the lttng_check_point_interval to set + */ + public void setCheckPointInterval(long check_point_interval) { + this.fcheckPointInterval = check_point_interval; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.linuxtools.lttng.state.IStateManager#restoreCheckPointByTimestamp + * (org.eclipse.linuxtools.tmf.event.TmfTimestamp) + */ + @SuppressWarnings("unchecked") + public TmfTimestamp restoreCheckPointByTimestamp(TmfTimestamp eventTime) { + TmfTimeRange experimentRange = fExperiment.getTimeRange(); + TmfTimestamp nearestTimeStamp = fTrace.getStartTime(); + + // The GUI can have time limits higher than this log, since GUI can + // handle multiple logs + if ((eventTime.getValue() < 0) + || (eventTime.getValue() > experimentRange.getEndTime().getValue())) { + return null; + } + + // The GUI can have time limits lower than this trace, since experiment + // can handle multiple traces + if ((eventTime.getValue() < fTrace.getStartTime().getValue())) { + eventTime = fTrace.getStartTime(); + } + + // Sort the checkpoints, required before the binary search + Collections.sort(timestampCheckpointsList); + // Initiate the compare with a checkpoint containing the target time + // stamp to find + int index = Collections.binarySearch(timestampCheckpointsList, + new TmfCheckpoint(eventTime, new TmfLocation(0L))); + // adjust index to round down to earlier checkpoint when exact match not + // found + index = getPrevIndex(index); + + LttngTraceState traceState; + if (index == 0) { + // No checkpoint restore is needed, start with a brand new + // TraceState + traceState = StateModelFactory.getStateEntryInstance(this); + } else { + synchronized (checkPointsLock) { + // Useful CheckPoint found + TmfCheckpoint checkpoint = timestampCheckpointsList.get(index); + nearestTimeStamp = checkpoint.getTimestamp(); + // get the location associated with the checkpoint + TmfLocation location = (TmfLocation) checkpoint + .getLocation(); + // reference a new copy of the checkpoint template + traceState = stateCheckpointsList.get(location.getLocation()) + .clone(); + } + } + + // Restore the stored traceState + synchronized (fStateModel) { + fStateModel = traceState; + } + + return nearestTimeStamp; + } + + /** + * Adjust the result from a binary search to the round down position + * + * @param position + * if Negative is: (-(insertion point) -1) + * @return position or if no match found, earlier than insertion point + */ + private int getPrevIndex(int position) { + int roundDownPosition = position; + if (position < 0) { + roundDownPosition = -(position + 2); + } + + roundDownPosition = roundDownPosition < 0 ? 0 : roundDownPosition; + return roundDownPosition; + } + + + // TODO: Remove this request type when the UI handle their own requests + /** + * Request Event data of a specified time range + * + * @param timeWindow + * @param listener + * @param processor + * @return ILttngEventRequest The request made + */ + ILttngSyntEventRequest getDataRequestByTimeRange(TmfTimeRange timeWindow, + IRequestStatusListener listener, + final ITransEventProcessor processor) { + + ILttngSyntEventRequest request = new StateTraceManagerRequest(timeWindow, + DEFAULT_OFFSET, TmfDataRequest.ALL_DATA, DEFAULT_CHUNK, + listener, getExperimentTimeWindow(), processor) { + }; + + return request; + } + + private ILttngSyntEventRequest getDataRequestStateSave(TmfTimeRange timeWindow, + IRequestStatusListener requestListener, + final ITransEventProcessor processor) { + + // Create the new request and override the handlePartialResult function + ILttngSyntEventRequest request = new StateTraceManagerRequest(timeWindow, + DEFAULT_OFFSET, TmfDataRequest.ALL_DATA, DEFAULT_CHUNK, + requestListener, getExperimentTimeWindow(), processor) { + + @Override + public void handleCompleted() { + if (isCancelled() || isFailed()) { + // No notification to end request handlers + } else { + // Indicates that trace selection has successfully completed + // i.e. check points have been already build if the number + // of events exceeded the interval + setTraceSelectCount(getTraceSelectCount() + 1); + } + + super.handleCompleted(); + + if (TraceDebug.isDEBUG()) { + StringBuilder sb = new StringBuilder( + "Check Point build Request completed" + + "\n\tEventCount: " + + fprocessor.getStateUpdateCount() + + "\tEvents for a different trace state received: " + + fprocessor.getFilteredOutEventCount() + + "\n\t" + + "Total number of processes in the State provider: " + + fStateModel.getProcesses().length); + + TmfTimeRange logTimes = fTrace.getTimeRange(); + sb.append("\n\tTrace time interval for trace " + + fTrace.getName() + + "\n\t" + + new LttngTimestamp(logTimes.getStartTime())); + sb.append(" - " + new LttngTimestamp(logTimes.getEndTime())); + sb.append("\n\tRequested Time: " + + getRange().getStartTime().toString() + " - " + + getRange().getEndTime().toString()); + sb.append("\n\tCheckPoints available at: "); + for (TmfCheckpoint cpoint : timestampCheckpointsList) { + sb.append("\n\t" + "Location: " + cpoint.getLocation() + + " - " + cpoint.getTimestamp()); + } + + TraceDebug.debug(sb.toString()); + } + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.linuxtools.lttng.request.LttngEventRequest#saveCheckPoint + * (java.lang.Long, org.eclipse.linuxtools.tmf.event.TmfTimestamp) + */ + public void saveCheckPoint(Long count, TmfTimestamp time) { + saveCheckPointIfNeeded(count, time); + } + + }; + + return request; + } + + /** + * + * @return + */ + private synchronized int getTraceSelectCount() { + return selectionCount; + } + + /** + * @param value + */ + private synchronized void setTraceSelectCount(int value) { + selectionCount = value; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#getStateModel + * () + */ + public LttngTraceState getStateModel() { + synchronized (fStateModel) { + return fStateModel; + } + } + + /** + * @return the stateCheckpointsList + */ + HashMap getStateCheckpointsList() { + return stateCheckpointsList; + } + + /** + * @return the timestampCheckpointsList + */ + Vector getTimestampCheckpointsList() { + return timestampCheckpointsList; + } + // ======================================================================= + // Inner Class + // ======================================================================= + class StateTraceManagerRequest extends LttngSyntEventRequest { + // ======================================================================= + // Data + // ======================================================================= + final TmfEvent[] evt = new TmfEvent[1]; + final ITransEventProcessor fprocessor; + LttngSyntheticEvent synEvent; + Long fCount = getSynEventCount(); + + // ======================================================================= + // Constructor + // ======================================================================= + public StateTraceManagerRequest(TmfTimeRange range, long offset, + int nbEvents, int maxBlockSize, + IRequestStatusListener listener, + TmfTimeRange experimentTimeRange, ITransEventProcessor processor) { + + super(range, offset, nbEvents, maxBlockSize, listener, + experimentTimeRange, processor); + fprocessor = processor; + TraceDebug.debug("Instance created for range: " + range.toString()); + fCount = 0L; + } + + // ======================================================================= + // Methods + // ======================================================================= + /* + * (non-Javadoc) + * + * @see + * org.eclipse.linuxtools.lttng.request.LttngSyntEventRequest#handleData + * () + */ + @Override + public void handleData() { + TmfEvent[] result = getData(); + + evt[0] = (result.length > 0) ? result[0] : null; + if (evt[0] != null) { + synEvent = (LttngSyntheticEvent) evt[0]; + if (synEvent.getSynType() == SequenceInd.AFTER) { + // Note : We call this function before incrementing + // eventCount to save a default check point at the "0th" + // event + saveCheckPoint(fCount, synEvent.getTimestamp()); + fCount++; + + if (TraceDebug.isDEBUG()) { + if (fCount % 1000 == 0) { + TraceDebug.debug("handled: " + fCount + + " sequence: " + synEvent.getSynType()); + } + } + } + } + } + + /** + * To be overridden by active save e.g. check points, this no action + * default is used for requests which do not require rebuilding of + * checkpoints e.g. requiring data of a new time range selection + * + * @param count + * @param time + */ + public void saveCheckPoint(Long count, TmfTimestamp time) { + + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.linuxtools.lttng.state.resource.ILttngStateContext# + * getNumberOfCpus() + */ + public int getNumberOfCpus() { + return fcpuNumber; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.linuxtools.lttng.state.resource.ILttngStateContext# + * getTraceTimeWindow() + */ + public TmfTimeRange getTraceTimeWindow() { + if (fTrace != null) { + return fTrace.getTimeRange(); + + } + return null; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.linuxtools.lttng.state.resource.ILttngStateContext#getTraceId + * () + */ + public String getTraceId() { + if (fTrace != null) { + return fTrace.getName(); + } + return null; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager# + * getExperimentTimeWindow() + */ + public TmfTimeRange getExperimentTimeWindow() { + if (fExperiment != null) { + return fExperiment.getTimeRange(); + } + return null; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#getExperimentName + * () + */ + public String getExperimentName() { + return fExperiment.getName(); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.linuxtools.lttng.state.resource.ILttngStateContext#getTraceIdRef + * () + */ + public ITmfTrace getTraceIdRef() { + return fTrace; + } +} \ No newline at end of file diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/trace/LTTngTextTrace.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/trace/LTTngTextTrace.java new file mode 100644 index 0000000000..eb15be80d8 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/trace/LTTngTextTrace.java @@ -0,0 +1,518 @@ +/******************************************************************************* + * Copyright (c) 2009 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: + * William Bourque (wbourque@gmail.com) - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.lttng.trace; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; +import java.util.HashMap; + +import org.eclipse.linuxtools.lttng.event.LttngEvent; +import org.eclipse.linuxtools.lttng.event.LttngEventContent; +import org.eclipse.linuxtools.lttng.event.LttngEventField; +import org.eclipse.linuxtools.lttng.event.LttngEventReference; +import org.eclipse.linuxtools.lttng.event.LttngEventSource; +import org.eclipse.linuxtools.lttng.event.LttngEventType; +import org.eclipse.linuxtools.lttng.event.LttngTimestamp; +import org.eclipse.linuxtools.lttng.jni.JniEvent; +import org.eclipse.linuxtools.tmf.event.TmfNoSuchFieldException; +import org.eclipse.linuxtools.tmf.event.TmfTimeRange; +import org.eclipse.linuxtools.tmf.trace.ITmfLocation; +import org.eclipse.linuxtools.tmf.trace.ITmfTrace; +import org.eclipse.linuxtools.tmf.trace.TmfCheckpoint; +import org.eclipse.linuxtools.tmf.trace.TmfContext; +import org.eclipse.linuxtools.tmf.trace.TmfLocation; +import org.eclipse.linuxtools.tmf.trace.TmfTrace; + +public class LTTngTextTrace extends TmfTrace implements ITmfTrace { + private LttngTimestamp eventTimestamp = null; + private LttngEventSource eventSource = null; + private LttngEventType eventType = null; + private TextLttngEventContent eventContent = null; + private LttngEventReference eventReference = null; + // The actual event + private TextLttngEvent currentLttngEvent = null; + + private HashMap traceTypes = null; + + private String tracepath = ""; + private FileReader fr = null; + private BufferedReader br = null; + private Long nbCharRead = 0L; + + private int cpuNumber = -1; + + private boolean showDebug = false; + + public LTTngTextTrace(String path) throws Exception { + this(path, false); + } + + public LTTngTextTrace(String path, boolean skipIndexing) throws Exception { + super(path, LttngEvent.class, path, 1); + + tracepath = path; + traceTypes = new HashMap(); + + eventTimestamp = new LttngTimestamp(); + eventSource = new LttngEventSource(); + eventType = new LttngEventType(); + eventContent = new TextLttngEventContent(currentLttngEvent); + eventReference = new LttngEventReference(this.getName()); + + currentLttngEvent = new TextLttngEvent(this, eventTimestamp, eventSource, eventType, eventContent, eventReference); + eventContent.setEvent(currentLttngEvent); + + if ( positionToFirstEvent() == false ) { + throw new IOException("Fail to position to the beginning of the trace"); + } + else { + fIndexPageSize = 1000; + + // Skip indexing if asked + if ( skipIndexing == true ) { + fCheckpoints.add(new TmfCheckpoint(new LttngTimestamp(0L), new TmfLocation(0L))); + } + else { + indexTrace(true); + } + + Long endTime = currentLttngEvent.getTimestamp().getValue(); + positionToFirstEvent(); + + getNextEvent(new TmfContext(null, 0)); + Long starTime = currentLttngEvent.getTimestamp().getValue(); + positionToFirstEvent(); + + setTimeRange( new TmfTimeRange( new LttngTimestamp(starTime), + new LttngTimestamp(endTime) + ) ); + } + } + + + public LTTngTextTrace(LTTngTextTrace oldTrace) throws Exception { + this(oldTrace.getPath(), true); + + // *** VERIFY *** + // Is this safe? + fCheckpoints = oldTrace.fCheckpoints; + } + + public LTTngTextTrace createTraceCopy() { + + LTTngTextTrace returnedTrace = null; + + try { + returnedTrace = new LTTngTextTrace(this); + } + catch (Exception e) { + System.out.println("ERROR : Could not create LTTngTextTrace copy (createTraceCopy).\nError is : " + e.getStackTrace()); + } + + return returnedTrace; + } + + private boolean positionToFirstEvent() { + + boolean isSuccessful = true; + + try { + if ( br != null ) { + br.close(); + fr.close(); + } + + fr = new FileReader(tracepath); + br = new BufferedReader(fr); + + // Skip the 2 lines header + br.readLine(); + br.readLine(); + + // Make sure the event time is consistent + eventTimestamp.setValue(0L); + } + catch (Exception e) { + isSuccessful = false; + } + + return isSuccessful; + } + + private void skipToPosition(TmfLocation skip) { + try { + long skipPosition = skip.getLocation(); + if ( skipPosition < 0 ) { + skipPosition = 0L; + } + + if ( showDebug == true ) { + System.out.println("skipToPosition(Long skipPosition)"); + System.out.println("\tSkipping to : " + skipPosition); + System.out.println(); + } + positionToFirstEvent(); + long nbSkipped = br.skip(skipPosition); + if ( nbSkipped != skipPosition) { + throw new IOException("Too few characters skipped, positionning failed! (skipToPosition)"); + } + + nbCharRead = skipPosition; + } + catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + @SuppressWarnings("unchecked") + public TmfContext seekLocation(ITmfLocation location) { + if (location == null) { + location = new TmfLocation(0L); + } + + if (!((TmfLocation) location).getLocation().equals(nbCharRead)) { + skipToPosition((TmfLocation) location); + } + + TmfContext tmpTraceContext = new TmfContext(location, 0L); + + return tmpTraceContext; + } + + private LttngEvent parseMyNextEvent(TmfContext context) { + + // All parsing variables declared here so to be able to print them into the catch if needed + String tmpContent = null; + int tmpCurIndex = 0; + int tmpPrevIndex = 0; + + String tracefile = ""; + long tmpCpu = 0; + String marker = ""; + + long tmpSecond = 0; + long tmpNanosecond = 0; + + String parsedPayload = ""; + String markerName = ""; + Object payload = ""; + + HashMap fieldsMap = null; + + LttngEvent returnedEvent = null; + + try { + tmpContent = br.readLine(); + + if (tmpContent != null) { + // *** NOTE : + // -1 is the skip the end of line (\n) + nbCharRead += (tmpContent.length()+1); + + if ( (currentLttngEvent != null) && (currentLttngEvent.getContent().getRawContent() != null) ) { + currentLttngEvent.getContent().emptyContent(); + } + + // EventSource is always the same for now : + eventSource.setSourceId("Kernel Core"); + + + // Tracefile and marker are first in the file + // Sound like : + // kernel.syscall_entry: + tmpCurIndex = tmpContent.indexOf(".", tmpPrevIndex); + + // *** HACK *** + // Evil exit case here : the two last line of the text dump does not contain "." + // We should check in a better way (string comparison and such) but it make the whole process to weight a lot more + // Conclusion : this is ugly but fast. + if ( tmpCurIndex < 0 ) { + if ( showDebug == true ) { + System.out.println("END OF FILE."); + System.out.println(); + } + return null; + } + + tracefile = tmpContent.substring(tmpPrevIndex, tmpCurIndex ).trim(); + /*System.out.println(tracefile);*/ + + tmpPrevIndex = tmpCurIndex; + tmpCurIndex = tmpContent.indexOf(":", tmpPrevIndex); + marker = tmpContent.substring(tmpPrevIndex+1, tmpCurIndex ).trim(); + /*System.out.println(marker);*/ + + // Timestamp is next but is presented in second.milisecond format, we have to split them + // Sound like : + // 952.162637168 + tmpPrevIndex = tmpCurIndex+1; + tmpCurIndex = tmpContent.indexOf(".", tmpPrevIndex); + tmpSecond = Long.parseLong( tmpContent.substring(tmpPrevIndex, tmpCurIndex ).trim() ); + /*System.out.println(tmpSecond);*/ + + tmpPrevIndex = tmpCurIndex+1; + tmpCurIndex = tmpContent.indexOf(" ", tmpPrevIndex); + tmpNanosecond = Long.parseLong( tmpContent.substring(tmpPrevIndex, tmpCurIndex ).trim() ); + /*System.out.println(tmpNanosecond);*/ + + // We have enough information here to set the timestamp + eventTimestamp.setValue( (tmpSecond * 1000000000) + tmpNanosecond ); + /*System.out.println(eventTimestamp.toString());*/ + + // Next field is the reference + // A long string enclosed by parenthesis and ending with a comma + // (/home/william/workspace/org.eclipse.linuxtools.lttng.tests/traceset/trace-618339events-1293lost-1cpu/kernel_0), + tmpPrevIndex = tmpCurIndex+1; + tmpCurIndex = tmpContent.indexOf("(", tmpPrevIndex); + tmpPrevIndex = tmpCurIndex+1; + tmpCurIndex = tmpContent.indexOf("),", tmpPrevIndex); + String fullTracePath = tmpContent.substring(tmpPrevIndex, tmpCurIndex ).trim(); + /*System.out.println(fullTracePath);*/ + + eventReference.setValue(fullTracePath); + String traceName = fullTracePath.substring(fullTracePath.lastIndexOf("/")+1).trim(); + /*System.out.println(traceName);*/ + eventReference.setTracepath(traceName); + + + // The next few fields are relatives to the state system (pid, ppid, etc...) we need to skip them. + // They should be like the following : + // 4175, 4175, hal-acl-tool, , 4168, + + // 1st comma + tmpPrevIndex = tmpCurIndex+1; + tmpCurIndex = tmpContent.indexOf(",", tmpPrevIndex); + // 2nd comma + tmpPrevIndex = tmpCurIndex+1; + tmpCurIndex = tmpContent.indexOf(",", tmpPrevIndex); + // 3rd comma + tmpPrevIndex = tmpCurIndex+1; + tmpCurIndex = tmpContent.indexOf(",", tmpPrevIndex); + // 4th comma + tmpPrevIndex = tmpCurIndex+1; + tmpCurIndex = tmpContent.indexOf(",", tmpPrevIndex); + // 5th comma + tmpPrevIndex = tmpCurIndex+1; + tmpCurIndex = tmpContent.indexOf(",", tmpPrevIndex); + // 6th comma + tmpPrevIndex = tmpCurIndex+1; + tmpCurIndex = tmpContent.indexOf(",", tmpPrevIndex); + + // The next field is the CPU, in hexadecimal format + // Should be like : + // 0x0, + tmpPrevIndex = tmpCurIndex+1; + tmpCurIndex = tmpContent.indexOf("0x", tmpPrevIndex); + tmpPrevIndex = tmpCurIndex+2; + + tmpCurIndex = tmpContent.indexOf(",", tmpPrevIndex); + tmpCpu = Long.parseLong( tmpContent.substring(tmpPrevIndex, tmpCurIndex ).trim() ); + + // Set the cpu number of trace if we found a "new" cpu + if ( cpuNumber < (tmpCpu + 1) ) { + cpuNumber = (int)(tmpCpu+1); + } + /*System.out.println(tmpCpu);*/ + + + // The last field is the parsed content + // It is enclosed by { } + // Look like : + // SYSCALL { ip = 0xb7f05422, syscall_id = 221 [sys_fcntl64+0x0/0x79] } + // + // NOTE : it seems some state system events do not respect this format as they have no payload. + // We will create empty payload then. + int tmpIndex = tmpContent.indexOf("{", tmpPrevIndex); + if ( tmpIndex != -1 ) { + tmpPrevIndex = tmpCurIndex+1; + tmpCurIndex = tmpIndex; + tmpPrevIndex = tmpCurIndex+1; + tmpCurIndex = tmpContent.indexOf("}", tmpPrevIndex); + parsedPayload = tmpContent.substring(tmpPrevIndex, tmpCurIndex ).trim(); + + // Now add each LttngField + boolean isDone = false; + int tmpIndexBegin = 0; + int tmpIndexEqual = 0; + int tmpIndexEnd = 0; + + fieldsMap = new HashMap(); + + while ( isDone == false ) { + tmpIndexEqual = parsedPayload.indexOf("=", (int)tmpIndexBegin); + tmpIndexEnd = parsedPayload.indexOf(", ", (int)tmpIndexEqual); + if ( tmpIndexEnd == -1 ) { + tmpIndexEnd = parsedPayload.length(); + isDone = true; + } + + markerName = parsedPayload.substring((int)tmpIndexBegin, (int)tmpIndexEqual-1 ).trim(); + payload = ((String)parsedPayload.substring((int)tmpIndexEqual+1, (int)tmpIndexEnd )).replace("\"", " ").trim(); + + // Try to cast the payload into the correct type + try { + payload = Long.parseLong((String)payload); + } + catch (NumberFormatException e) { } + + LttngEventField tmpField = new LttngEventField(eventContent, markerName, payload); + fieldsMap.put(markerName, tmpField); + + tmpIndexBegin = tmpIndexEnd+1; + } + } + else { + fieldsMap = new HashMap(); + + markerName = ""; + payload = ""; + + LttngEventField tmpField = new LttngEventField(eventContent, markerName, payload); + fieldsMap.put(markerName, tmpField); + } + + eventContent = new TextLttngEventContent(currentLttngEvent, fieldsMap); + + // We now have what we need for the type + String tmpTypeKey = tracefile + "/" + tmpCpu + "/" + marker; + if ( traceTypes.get(tmpTypeKey) == null ) { + traceTypes.put(tmpTypeKey, new LttngEventType(tracefile, tmpCpu, marker, fieldsMap.keySet().toArray(new String[fieldsMap.size()] )) ); + } + + currentLttngEvent.setContent(eventContent); + currentLttngEvent.setType(traceTypes.get(tmpTypeKey)); + + returnedEvent = currentLttngEvent; + } + else if ( showDebug == true ) { + System.out.println("NULL READING"); + System.out.println(); + returnedEvent = null; + } + } + catch (Exception e) { + System.out.println("Pos is :" + nbCharRead); + if ( tmpContent != null ) { + System.out.println("Erroneous content is :" + tmpContent); + } + + tmpContent = null; + e.printStackTrace(); + returnedEvent = null; + } + + return returnedEvent; + } + + @Override + public ITmfLocation getCurrentLocation() { + return new TmfLocation(nbCharRead); + } + + @Override + public LttngEvent parseEvent(TmfContext context) { + context = seekLocation(context.getLocation()); + return parseMyNextEvent(context); + + } + + public int getCpuNumber() { + return cpuNumber; + } +} + + +// Redefine event to override method we know won't work with a Text tracefile +class TextLttngEvent extends LttngEvent { + + public TextLttngEvent( TmfTrace parent, + LttngTimestamp timestamp, + LttngEventSource source, + LttngEventType type, + LttngEventContent content, + LttngEventReference reference) + { + super(parent, timestamp, source, type, content, reference, null); + } + + public TextLttngEvent(TextLttngEvent oldEvent) { + this( + oldEvent.getParentTrace(), + (LttngTimestamp)oldEvent.getTimestamp(), + (LttngEventSource)oldEvent.getSource(), + (LttngEventType)oldEvent.getType(), + (LttngEventContent)oldEvent.getContent(), + (LttngEventReference)oldEvent.getReference() + ); + } + + @Override + public JniEvent convertEventTmfToJni() { + System.out.println("WARNING : Cannot use convertEventTmfToJni() on a trace in text format."); + return null; + } + + @Override + public void updateJniEventReference(JniEvent newJniEventReference) { + System.out.println("WARNING : Cannot use updateJniEventReference on a trace in text format. Using null."); + } +} + + +class TextLttngEventContent extends LttngEventContent { + + public TextLttngEventContent() { + super(); + } + + public TextLttngEventContent(TextLttngEvent thisParent) { + super(thisParent, null); + } + + public TextLttngEventContent(TextLttngEvent thisParent, HashMap thisContent) { + super(thisParent, thisContent); + } + + public TextLttngEventContent(TextLttngEventContent oldContent) { + this( (TextLttngEvent)oldContent.fParentEvent, oldContent.getRawContent()); + } + + @Override + public LttngEventField[] getFields() { + return getRawContent().values().toArray(new LttngEventField[getRawContent().size()]); + } + + @Override + public LttngEventField getField(String name) { + LttngEventField returnedField = getRawContent().get(name); + + return returnedField; + } + + @Override + public LttngEventField getField(int position) { + LttngEventField returnedField = null; + String label = null; + try { + label = fParentEvent.getType().getLabel(position); + returnedField = this.getField(label); + } + catch (TmfNoSuchFieldException e) { + System.out.println("Invalid field position requested : " + position + ", ignoring (getField)."); + } + + return returnedField; + } +} \ No newline at end of file diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/trace/LTTngTrace.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/trace/LTTngTrace.java new file mode 100644 index 0000000000..f5f844a140 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/trace/LTTngTrace.java @@ -0,0 +1,909 @@ +/******************************************************************************* + * Copyright (c) 2009 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: + * William Bourque (wbourque@gmail.com) - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.lttng.trace; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Vector; + +import org.eclipse.linuxtools.lttng.LttngException; +import org.eclipse.linuxtools.lttng.event.LttngEvent; +import org.eclipse.linuxtools.lttng.event.LttngEventContent; +import org.eclipse.linuxtools.lttng.event.LttngEventReference; +import org.eclipse.linuxtools.lttng.event.LttngEventSource; +import org.eclipse.linuxtools.lttng.event.LttngEventType; +import org.eclipse.linuxtools.lttng.event.LttngLocation; +import org.eclipse.linuxtools.lttng.event.LttngTimestamp; +import org.eclipse.linuxtools.lttng.jni.JniEvent; +import org.eclipse.linuxtools.lttng.jni.JniMarker; +import org.eclipse.linuxtools.lttng.jni.JniTrace; +import org.eclipse.linuxtools.lttng.jni.JniTracefile; +import org.eclipse.linuxtools.lttng.jni.common.JniTime; +import org.eclipse.linuxtools.lttng.jni.factory.JniTraceFactory; +import org.eclipse.linuxtools.tmf.event.TmfTimeRange; +import org.eclipse.linuxtools.tmf.event.TmfTimestamp; +import org.eclipse.linuxtools.tmf.trace.ITmfLocation; +import org.eclipse.linuxtools.tmf.trace.TmfCheckpoint; +import org.eclipse.linuxtools.tmf.trace.TmfContext; +import org.eclipse.linuxtools.tmf.trace.TmfTrace; + + +class LTTngTraceException extends LttngException { + static final long serialVersionUID = -1636648737081868146L; + + public LTTngTraceException(String errMsg) { + super(errMsg); + } +} + +/** + * LTTngTrace

+ * + * LTTng trace implementation. It accesses the C trace handling library + * (seeking, reading and parsing) through the JNI component. + */ +public class LTTngTrace extends TmfTrace { + + public static boolean printDebug = false; + public static boolean uniqueEvent = false; + + private final static boolean SHOW_LTT_DEBUG_DEFAULT = false; + private final static boolean IS_PARSING_NEEDED_DEFAULT = true; + private final static int CHECKPOINT_PAGE_SIZE = 1000; + + // Reference to our JNI trace + private JniTrace currentJniTrace = null; + + // *** + // UNHACKED : We can no longer do that because TCF need to maintain several events at once. + // This is very slow to do so in LTTng, this has to be temporary. + // *** HACK *** + // To save time, we will declare all component of the LttngEvent during the construction of the trace + // Then, while reading the trace, we will just SET the values instead of declaring new object + // *** + LttngTimestamp eventTimestamp = null; + LttngEventSource eventSource = null; + LttngEventContent eventContent = null; + LttngEventReference eventReference = null; + + + // The actual event + LttngEvent currentLttngEvent = null; + + // The current location + LttngLocation previousLocation = null; + + LttngEventType eventType = null; + // Hashmap of the possible types of events (Tracefile/CPU/Marker in the JNI) + HashMap traceTypes = null; + // This vector will be used to quickly find a marker name from a position + Vector traceTypeNames = null; + + /** + * Default Constructor.

+ * + * @param path Path to a directory that contain an LTTng trace. + * + * @exception Exception (most likely LTTngTraceException or FileNotFoundException) + */ + public LTTngTrace(String path) throws Exception { + // Call with "wait for completion" true and "skip indexing" false + this(path, true, false); + } + + /** + * Constructor, with control over the indexing. + *

+ * @param path Path to a directory that contain an LTTng trace. + * @param waitForCompletion Should we wait for indexign to complete before moving on. + * + * @exception Exception (most likely LTTngTraceException or FileNotFoundException) + */ + public LTTngTrace(String path, boolean waitForCompletion) throws Exception { + // Call with "skip indexing" false + this(path, waitForCompletion, false); + } + + /** + * Default constructor, with control over the indexing and possibility to bypass indexation + *

+ * @param path Path to a directory that contain an LTTng trace. + * @param waitForCompletion Should we wait for indexign to complete before moving on. + * @param bypassIndexing Should we bypass indexing completly? This is should only be useful for unit testing. + * + * @exception Exception (most likely LTTngTraceException or FileNotFoundException) + * + */ + public LTTngTrace(String path, boolean waitForCompletion, boolean bypassIndexing) throws Exception { + super(path, LttngEvent.class, path, CHECKPOINT_PAGE_SIZE); + try { + currentJniTrace = JniTraceFactory.getJniTrace(path, SHOW_LTT_DEBUG_DEFAULT); + } + catch (Exception e) { + throw new LTTngTraceException(e.getMessage()); + } + + // Export all the event types from the JNI side + traceTypes = new HashMap(); + traceTypeNames = new Vector(); + initialiseEventTypes(currentJniTrace); + + // *** VERIFY *** + // Verify that all those "default constructor" are safe to use + eventTimestamp = new LttngTimestamp(); + eventSource = new LttngEventSource(); + eventType = new LttngEventType(); + eventContent = new LttngEventContent(currentLttngEvent); + eventReference = new LttngEventReference(this.getName()); + + // Create the skeleton event + currentLttngEvent = new LttngEvent(this, eventTimestamp, eventSource, eventType, eventContent, eventReference, null); + + // Create a new current location + previousLocation = new LttngLocation(); + + + // Set the currentEvent to the eventContent + eventContent.setEvent(currentLttngEvent); + + // Bypass indexing if asked + if ( bypassIndexing == false ) { + indexTrace(true); + } + else { + // Even if we don't have any index, set ONE checkpoint + fCheckpoints.add(new TmfCheckpoint(new LttngTimestamp(0L) , new LttngLocation() ) ); + + // Set the start time of the trace + setTimeRange( new TmfTimeRange( new LttngTimestamp(currentJniTrace.getStartTime().getTime()), + new LttngTimestamp(currentJniTrace.getEndTime().getTime()) + ) ); + } + } + + /* + * Copy constructor is forbidden for LttngEvenmStream + * + */ + public LTTngTrace(LTTngTrace oldTrace) throws Exception { + this(oldTrace.getPath(), false, true); + + // *** VERIFY *** + // Is this safe? + this.fCheckpoints = oldTrace.fCheckpoints; + + /* + // This would only work if the index is already done + this.fCheckpoints = new Vector( oldTrace.fCheckpoints.size() ); + for (int x = 0; x tracefileItr = trace.getTracefilesMap().keySet().iterator(); + while ( tracefileItr.hasNext() ) { + newTracefileKey = tracefileItr.next(); + newTracefile = trace.getTracefilesMap().get(newTracefileKey); + + // From the TRACEFILE read, obtain its MARKER + Iterator markerItr = newTracefile.getTracefileMarkersMap().keySet().iterator(); + while ( markerItr.hasNext() ) { + newMarkerKey = markerItr.next(); + newMarker = newTracefile.getTracefileMarkersMap().get(newMarkerKey); + + // From the MARKER we can obtain the MARKERFIELDS keys (i.e. labels) + markerFieldsLabels = newMarker.getMarkerFieldsHashMap().keySet().toArray( new String[newMarker.getMarkerFieldsHashMap().size()] ); + tmpType = new LttngEventType(newTracefile.getTracefileName(), newTracefile.getCpuNumber(), newMarker.getName(), markerFieldsLabels ); + + // Add the type to the map/vector + addEventTypeToMap(tmpType); + } + } + } + + /* + * Add a new type to the HashMap + * + * As the hashmap use a key format that is a bit dangerous to use, we should always add using this function. + */ + private void addEventTypeToMap(LttngEventType newEventType) { + String newTypeKey = EventTypeKey.getEventTypeKey(newEventType); + + this.traceTypes.put(newTypeKey, newEventType); + this.traceTypeNames.add(newTypeKey); + } + + /** + * Index the current trace. + * + * @param useless This boolean is only to comply to the interface and will be ignored. + */ + @Override + public synchronized void indexTrace(boolean useless) { + + long nbEvents=0L; + + // Start time need to be null to detect none have been set + // LastTime need to exist so we can ajust it as we go + LttngTimestamp startTime = null; + LttngTimestamp lastTime = new LttngTimestamp(); + + // Position the trace at the beginning + TmfContext context = seekEvent( new LttngTimestamp(0L) ); + + // Read the first event and extract the location + LttngEvent tmpEvent = (LttngEvent)getNextEvent(context); + + // If we read the first event, define the start time. + if ( tmpEvent != null ) { + startTime = new LttngTimestamp( tmpEvent.getTimestamp() ); + lastTime.setValue(tmpEvent.getTimestamp().getValue()); + } + + // Now, we read each event until we hit the end of the trace + // We will create a new checkpoint every "getCacheSize()" event + while ( tmpEvent != null) { + // Update the last time each time we read a new event + lastTime.setValue(tmpEvent.getTimestamp().getValue()); + + // Save a check point if needed + if ((nbEvents++ % getCacheSize()) == 0) { + // *** IMPORTANT + // We need to NEW each stuff we put in checkpoint + // Otherwise everything will be the same! + LttngTimestamp tmpTimestamp = new LttngTimestamp( (LttngTimestamp)tmpEvent.getTimestamp() ); + LttngLocation newLocation = new LttngLocation( (LttngTimestamp)tmpEvent.getTimestamp() ); + + fCheckpoints.add(new TmfCheckpoint(tmpTimestamp, newLocation ) ); + } + // Read the next event + tmpEvent = (LttngEvent)getNextEvent(context); + } + + // If we have a start time, we should have an end time as well + // Issue the new range + if (startTime != null) { + setTimeRange( new TmfTimeRange(startTime, lastTime) ); + notifyListeners(getTimeRange() ); + } + + // Ajust the total number of event in the trace + fNbEvents = nbEvents; + //printCheckpointsVector(); + //printDebug = true; + } + + /** + * Return the latest saved location. + * Note : Modifying the returned location may result in buggy positionning! + * + * @return The LttngLocation as it was after the last operation. + * + * @see org.eclipse.linuxtools.lttng.event.LttngLocation + */ + @Override + public ITmfLocation getCurrentLocation() { + return previousLocation; + } + + /** + * Position the trace to the event at the given location.

+ * NOTE : Seeking by location is very fast compare to seeking by position + * but is still slower than "ReadNext", avoid using it for small interval. + * + * @param location Location of the event in the trace. + * If no event available at this exact location, we will position ourself to the next one. + * + * @return The TmfContext that point to this event + * + * @see org.eclipse.linuxtools.lttng.event.LttngLocation + * @see org.eclipse.linuxtools.tmf.trace.TmfContext + */ + @Override + public synchronized TmfContext seekLocation(ITmfLocation location) { + + if ( printDebug == true ) { + System.out.println("seekLocation(location) location -> " + location); + } + + // If the location in context is null, create a new one + LttngLocation curLocation = null; + if ( location == null ) { + curLocation = new LttngLocation(); + } + else { + curLocation = (LttngLocation)location; + } + + // *** NOTE : + // Update to location should (and will) be done in SeekEvent. + + // The only seek valid in LTTng is with the time, we call seekEvent(timestamp) + return seekEvent( curLocation.getOperationTime() ); + } + + /** + * Position the trace to the event at the given time.

+ * NOTE : Seeking by time is very fast compare to seeking by position + * but is still slower than "ReadNext", avoid using it for small interval. + * + * @param timestamp Time of the event in the trace. + * If no event available at this exact time, we will position ourself to the next one. + * + * @return The TmfContext that point to this event + * + * @see org.eclipse.linuxtools.lttng.event.LttngLocation + * @see org.eclipse.linuxtools.tmf.trace.TmfContext + */ + @Override + public synchronized TmfContext seekEvent(TmfTimestamp timestamp) { + + if ( printDebug == true ) { + System.out.println("seekEvent(timestamp) timestamp -> " + timestamp); + } + + // Call JNI to seek + currentJniTrace.seekToTime(new JniTime(timestamp.getValue())); + + // Save the time at which we seeked + previousLocation.setOperationTime(timestamp.getValue()); + // Set the operation marker as seek, to be able to detect we did "seek" this event + previousLocation.setLastOperationSeek(); + + // *** VERIFY *** + // Is that too paranoid? + // + // We don't trust what upper level could do with our internal location + // so we create a new one to return instead + LttngLocation curLocation = new LttngLocation(previousLocation); + + return new TmfContext( curLocation ); + } + + /** + * Position the trace to the event at the given position (rank).

+ * NOTE : Seeking by position is very slow in LTTng, consider seeking by timestamp. + * + * @param position Position (or rank) of the event in the trace, starting at 0. + * + * @return The TmfContext that point to this event + * + * @see org.eclipse.linuxtools.lttng.event.LttngLocation + * @see org.eclipse.linuxtools.tmf.trace.TmfContext + */ + @Override + public synchronized TmfContext seekEvent(long position) { + + if ( printDebug == true ) { + System.out.println("seekEvent(position) position -> " + position); + } + + TmfTimestamp timestamp = null; + long index = position / getCacheSize(); + + // Get the timestamp of the closest check point to the given position + if (fCheckpoints.size() > 0) { + if (index >= fCheckpoints.size()) { + index = fCheckpoints.size() - 1; + } + timestamp = (TmfTimestamp)fCheckpoints.elementAt((int)index).getTimestamp(); + } + // If none, take the start time of the trace + else { + timestamp = getStartTime(); + } + + // Seek to the found time + TmfContext tmpContext = seekEvent(timestamp); + previousLocation = (LttngLocation)tmpContext.getLocation(); + + // Ajust the index of the event we found at this check point position + Long currentPosition = index * getCacheSize(); + + Long lastTimeValueRead = 0L; + + // Get the event at current position. This won't move to the next one + JniEvent tmpJniEvent = currentJniTrace.findNextEvent(); + // Now that we are positionned at the checkpoint, + // we need to "readNext" (Position - CheckpointPosition) times or until trace "run out" + while ( (tmpJniEvent != null) && ( currentPosition < position ) ) { + tmpJniEvent = currentJniTrace.readNextEvent(); + currentPosition++; + } + + // If we found our event, save its timestamp + if ( tmpJniEvent != null ) { + lastTimeValueRead = tmpJniEvent.getEventTime().getTime(); + } + + // Set the operation marker as seek, to be able to detect we did "seek" this event + previousLocation.setLastOperationSeek(); + // Save read event time + previousLocation.setOperationTime(lastTimeValueRead); + + // *** VERIFY *** + // Is that too paranoid? + // + // We don't trust what upper level could do with our internal location + // so we create a new one to return instead + LttngLocation curLocation = new LttngLocation(previousLocation); + + return new TmfContext( curLocation ); + } + + /** + * Return the event in the trace according to the given context. Read it if necessary.

+ * Similar (same?) as ParseEvent except that calling GetNext twice read the next one the second time. + * + * @param context Current TmfContext where to get the event + * + * @return The LttngEvent we read of null if no event are available + * + * @see org.eclipse.linuxtools.lttng.event.LttngLocation + * @see org.eclipse.linuxtools.tmf.trace.TmfContext + */ + @Override + public synchronized LttngEvent getNextEvent(TmfContext context) { + + if ( printDebug == true ) { + System.out.println("getNextEvent(context) context.getLocation() -> " + context.getLocation()); + } + + LttngEvent returnedEvent = null; + LttngLocation curLocation = null; + + // If the location in context is null, create a new one + if ( context.getLocation() == null ) { + curLocation = new LttngLocation(); + context.setLocation(curLocation); + } + else { + // Otherwise, we use the one in context; it should be a valid LttngLocation + curLocation = (LttngLocation)context.getLocation(); + } + + // *** HACK *** + // TMF assumes it is possible to read (GetNextEvent) to the next Event once ParseEvent() is called + // In LTTNG, there is not difference between "Parsing" and "Reading" an event. + // Since parsing/reading invalidate the previous event, + // we need to make sure the sequence ParseEvent() -> GetNextEvent() will not actually move to the next event. + // To do so, we avoid moving for call to "GetNextEvent()" that follow call to a call to "ParseEvent()". + // However, calling ParseEvent() -> GetNextEvent() -> GetNextEvent() will only move next by one. + + // *** Positionning trick : + // GetNextEvent only read the trace if : + // 1- The last operation was NOT a ParseEvent --> A read is required + // OR + // 2- The time of the previous location is different from the current one --> A seek + a read is required + if ( (curLocation.isLastOperationParse() != true) || + (previousLocation.getOperationTimeValue() != curLocation.getOperationTimeValue() ) ) + { + if ( previousLocation.getOperationTimeValue() != curLocation.getOperationTimeValue() ) { + if ( printDebug == true ) { + System.out.println("\t\tSeeking in getNextEvent. [ LastTime : " + previousLocation.getOperationTimeValue() + " CurrentTime" + curLocation.getOperationTimeValue() + " ]"); + } + seekEvent( curLocation.getOperationTime() ); + } + // Read the next event from the trace. The last one will NO LONGER BE VALID. + returnedEvent = readEvent(curLocation); + + // Set the operation marker as read to both location, to be able to detect we did "read" this event + previousLocation.setLastOperationReadNext(); + curLocation.setLastOperationReadNext(); + } + else { + // No event was read, just return the one currently loaded (the last one we read) + returnedEvent = currentLttngEvent; + + // *** IMPORTANT! + // Reset (erase) the operation marker to both location, to be able to detect we did NOT "read" this event + previousLocation.resetLocationState(); + curLocation.resetLocationState(); + } + + // If we read an event, set it's time to the locations (both previous and current) + if ( returnedEvent != null ) { + previousLocation.setOperationTime((LttngTimestamp)returnedEvent.getTimestamp()); + curLocation.setOperationTime((LttngTimestamp)returnedEvent.getTimestamp()); + } + + return returnedEvent; + } + + + /** + * Return the event in the trace according to the given context. Read it if necessary.

+ * Similar (same?) as GetNextEvent except that calling ParseEvent twice will return the same event + * + * @param context Current TmfContext where to get the event + * + * @return The LttngEvent we read of null if no event are available + * + * @see org.eclipse.linuxtools.lttng.event.LttngLocation + * @see org.eclipse.linuxtools.tmf.trace.TmfContext + */ + @Override + public synchronized LttngEvent parseEvent(TmfContext context) { + + if ( printDebug == true ) { + System.out.println("parseEvent(context) context.getLocation() -> " + context.getLocation()); + } + + LttngEvent returnedEvent = null; + LttngLocation curLocation = null; + + // If the location in context is null, create a new one + if ( context.getLocation() == null ) { + curLocation = new LttngLocation(); + context.setLocation(curLocation); + } + // Otherwise, we use the one in context; it should be a valid LttngLocation + else { + curLocation = (LttngLocation)context.getLocation(); + } + + // *** HACK *** + // TMF assumes it is possible to read (GetNextEvent) to the next Event once ParseEvent() is called + // In LTTNG, there is not difference between "Parsing" and "Reading" an event. + // So, before "Parsing" an event, we have to make sure we didn't "Read" it alreafy. + // Also, "Reading" invalidate the previous Event in LTTNG and seek back is very costly, + // so calling twice "Parse" will return the same event, giving a way to get the "Currently loaded" event + + // *** Positionning trick : + // ParseEvent only read the trace if : + // 1- The last operation was NOT a ParseEvent or a GetNextEvent --> A read is required + // OR + // 2- The time of the previous location is different from the current one --> A seek + a read is required + if ( ( (curLocation.isLastOperationParse() != true) && ((curLocation.isLastOperationReadNext() != true)) ) || + (previousLocation.getOperationTimeValue() != curLocation.getOperationTimeValue() ) ) + { + // Previous time != Current time : We need to reposition to the current time + if (previousLocation.getOperationTimeValue() != curLocation.getOperationTimeValue() ) { + if ( printDebug == true ) { + System.out.println("\t\tSeeking in getNextEvent. [ LastTime : " + previousLocation.getOperationTimeValue() + " CurrentTime" + curLocation.getOperationTimeValue() + " ]"); + } + seekEvent( curLocation.getOperationTime() ); + } + + // Read the next event from the trace. The last one will NO LONGER BE VALID. + returnedEvent = readEvent(curLocation); + } + else { + // No event was read, just return the one currently loaded (the last one we read) + returnedEvent = currentLttngEvent; + } + + // If we read an event, set it's time to the locations (both previous and current) + if ( returnedEvent != null ) { + previousLocation.setOperationTime((LttngTimestamp)returnedEvent.getTimestamp()); + curLocation.setOperationTime((LttngTimestamp)returnedEvent.getTimestamp()); + } + + // Set the operation marker as parse to both location, to be able to detect we already "read" this event + previousLocation.setLastOperationParse(); + curLocation.setLastOperationParse(); + + return returnedEvent; + } + + /* + * Read the next event from the JNI and convert it as Lttng Event

+ * + * @param location Current LttngLocation that to be updated with the event timestamp + * + * @return The LttngEvent we read of null if no event are available + * + * @see org.eclipse.linuxtools.lttng.event.LttngLocation + * @see org.eclipse.linuxtools.org.eclipse.linuxtools.lttng.jni.JniTrace + */ + private synchronized LttngEvent readEvent(LttngLocation location) { + LttngEvent returnedEvent = null; + JniEvent tmpEvent = null; + + // Read the next event from JNI. THIS WILL INVALIDATE THE CURRENT LTTNG EVENT. + tmpEvent = currentJniTrace.readNextEvent(); + + if ( tmpEvent != null ) { + // *** NOTE + // Convert will update the currentLttngEvent + returnedEvent = convertJniEventToTmf(tmpEvent); + + location.setOperationTime( (LttngTimestamp)returnedEvent.getTimestamp() ); + } + // *** NOTE + // If the read failed (likely the last event in the trace), set the LastReadTime to the JNI time + // That way, even if we try to read again, we will step over the bogus seek and read + else { + location.setOperationTime( getEndTime().getValue() + 1 ); + } + + return returnedEvent; + } + + /** + * Method to convert a JniEvent into a LttngEvent.

+ * + * Note : This method will call LttngEvent convertEventJniToTmf(JniEvent, boolean) + * with a default value for isParsingNeeded + * + * @param newEvent The JniEvent to convert into LttngEvent + * + * @return The converted LttngEvent + * + * @see org.eclipse.linuxtools.org.eclipse.linuxtools.lttng.jni.JniEvent + * @see org.eclipse.linuxtools.lttng.event.LttngEvent + */ + public synchronized LttngEvent convertJniEventToTmf(JniEvent newEvent) { + currentLttngEvent = convertJniEventToTmf(newEvent, IS_PARSING_NEEDED_DEFAULT); + + return currentLttngEvent; + } + + /** + * Method to convert a JniEvent into a LttngEvent + * + * @param jniEvent The JniEvent to convert into LttngEvent + * @param isParsingNeeded A boolean value telling if the event should be parsed or not. + * + * @return The converted LttngEvent + * + * @see org.eclipse.linuxtools.org.eclipse.linuxtools.lttng.jni.JniEvent + * @see org.eclipse.linuxtools.lttng.event.LttngEvent + */ + public synchronized LttngEvent convertJniEventToTmf(JniEvent jniEvent, boolean isParsingNeeded) { + + if ( uniqueEvent == true ) { + + // *** + // UNHACKED : We can no longer do that because TCF need to maintain several events at once. + // This is very slow to do so in LTTng, this has to be temporary. + // *** HACK *** + // To save time here, we only set value instead of allocating new object + // This give an HUGE performance improvement + // all allocation done in the LttngTrace constructor + // *** + eventTimestamp.setValue(jniEvent.getEventTime().getTime()); + eventSource.setSourceId(jniEvent.requestEventSource()); + + eventType = traceTypes.get( EventTypeKey.getEventTypeKey(jniEvent) ); + + eventReference.setValue(jniEvent.getParentTracefile().getTracefilePath()); + eventReference.setTracepath(this.getName()); + + eventContent.emptyContent(); + + currentLttngEvent.setType(eventType); + // Save the jni reference + currentLttngEvent.updateJniEventReference(jniEvent); + + // Parse now if was asked + // Warning : THIS IS SLOW + if (isParsingNeeded == true ) { + eventContent.getFields(); + } + + return currentLttngEvent; + } + else { + return convertJniEventToTmfMultipleEventEvilFix(jniEvent, isParsingNeeded); + } + + } + + /** + * This method is a temporary fix to support multiple events at once in TMF + * This is expected to be slow and should be fixed in another way. + * See comment in convertJniEventToTmf(); + * + * @param jniEvent The current JNI Event + * @return Current Lttng Event fully parsed + */ + private synchronized LttngEvent convertJniEventToTmfMultipleEventEvilFix(JniEvent jniEvent, boolean isParsingNeeded) { + // *** HACK *** + // Below : the "fix" with all the new and the full-parse + // Allocating new memory is slow. + // Parsing every events is very slow. + eventTimestamp = new LttngTimestamp(jniEvent.getEventTime().getTime()); + eventSource = new LttngEventSource(jniEvent.requestEventSource()); + eventReference = new LttngEventReference(jniEvent.getParentTracefile().getTracefilePath(), this.getName()); + eventType = new LttngEventType(traceTypes.get( EventTypeKey.getEventTypeKey(jniEvent) )); + eventContent = new LttngEventContent(currentLttngEvent); + currentLttngEvent = new LttngEvent(this, eventTimestamp, eventSource, eventType, eventContent, eventReference, null); + + // The jni reference is no longer reliable but we will keep it anyhow + currentLttngEvent.updateJniEventReference(jniEvent); + // Ensure that the content is correctly set + eventContent.setEvent(currentLttngEvent); + + // Parse the event if it was needed + // *** WARNING *** + // ONLY for testing, NOT parsing events with non-unique events WILL result in segfault in the JVM + if ( isParsingNeeded == true ) { + eventContent.getFields(); + } + + return currentLttngEvent; + } + + + + /** + * Reference to the current LttngTrace we are reading from.

+ * + * Note : This bypass the framework and should not be use, except for testing! + * + * @return Reference to the current LttngTrace + * + * @see org.eclipse.linuxtools.org.eclipse.linuxtools.lttng.jni.JniTrace + */ + public JniTrace getCurrentJniTrace() { + return currentJniTrace; + } + + + /** + * Return a reference to the current LttngEvent we have in memory. + * + * @return The current (last read) LttngEvent + * + * @see org.eclipse.linuxtools.lttng.event.LttngEvent + */ + public LttngEvent getCurrentEvent() { + return currentLttngEvent; + } + + /** + * Get the major version number for the current trace + * + * @return Version major or -1 if unknown + * + * @see org.eclipse.linuxtools.org.eclipse.linuxtools.lttng.jni.JniTrace + * + */ + public short getVersionMajor() { + if ( currentJniTrace!= null ) { + return currentJniTrace.getLttMajorVersion(); + } + else { + return -1; + } + } + + /** + * Get the minor version number for the current trace + * + * @return Version minor or -1 if unknown + * + * @see org.eclipse.linuxtools.org.eclipse.linuxtools.lttng.jni.JniTrace + * + */ + public short getVersionMinor() { + if ( currentJniTrace!= null ) { + return currentJniTrace.getLttMinorVersion(); + } + else { + return -1; + } + } + + /** + * Get the number of CPU for this trace + * + * @return Number of CPU or -1 if unknown + * + * @see org.eclipse.linuxtools.org.eclipse.linuxtools.lttng.jni.JniTrace + * + */ + public int getCpuNumber() { + if ( currentJniTrace!= null ) { + return currentJniTrace.getCpuNumber(); + } + else { + return -1; + } + } + + /** + * Print the content of the checkpoint vector.

+ * + * This is intended for debug purpose only. + */ + public void printCheckpointsVector() { + System.out.println("StartTime : " + getTimeRange().getStartTime().getValue()); + System.out.println("EndTime : " + getTimeRange().getEndTime().getValue()); + + for ( int pos=0; pos < fCheckpoints.size(); pos++) { + System.out.print(pos + ": " + "\t"); + System.out.print( fCheckpoints.get(pos).getTimestamp() + "\t" ); + System.out.println( fCheckpoints.get(pos).getLocation() ); + } + } + + /** + * Return a String identifying this trace. + * + * @return String that identify this trace + */ + @Override + public String toString() { + String returnedData=""; + + returnedData += "Path :" + getPath() + " "; + returnedData += "Trace:" + currentJniTrace + " "; + returnedData += "Event:" + currentLttngEvent; + + return returnedData; + } +} + +/* + * EventTypeKey inner class + * + * This class is used to make the process of generating the HashMap key more transparent and so less error prone to use + * + */ +class EventTypeKey { + //*** WARNING *** + // These two getEventTypeKey() functions should ALWAYS construct the key the same ways! + // Otherwise, every type search will fail! + + static public String getEventTypeKey(LttngEventType newEventType) { + String key = newEventType.getTracefileName() + "/" + newEventType.getCpuId().toString() + "/" + newEventType.getMarkerName(); + + return key; + } + + static public String getEventTypeKey(JniEvent newEvent) { + String key = newEvent.getParentTracefile().getTracefileName() + "/" + newEvent.getParentTracefile().getCpuNumber() + "/" + newEvent.requestEventMarker().getName(); + + return key; + } + +} \ No newline at end of file diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/trace/LTTngTraceVersion.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/trace/LTTngTraceVersion.java new file mode 100644 index 0000000000..6c67e98d70 --- /dev/null +++ b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/trace/LTTngTraceVersion.java @@ -0,0 +1,156 @@ +package org.eclipse.linuxtools.lttng.trace; +/******************************************************************************* + * Copyright (c) 2009 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: + * William Bourque (wbourque@gmail.com) - Initial API and implementation + *******************************************************************************/ + +import org.eclipse.linuxtools.lttng.LttngException; +import org.eclipse.linuxtools.lttng.jni.exception.JniTraceVersionException; +import org.eclipse.linuxtools.lttng.jni.factory.JniTraceVersion; + +/** + * LTTngTraceVersion

+ * + * This class is responsible of handling the version number of a trace.

+ * It will return the correct version number and validity information of a trace given its path.
+ * + */ +public class LTTngTraceVersion { + + private String tracepath = null; + private JniTraceVersion traceVersion = new JniTraceVersion(); + + /* + * Default constructor is forbidden + */ + @SuppressWarnings("unused") + private LTTngTraceVersion() { + // Default constructor forbidden + } + + /** + * Default constructor, takes a tracepath as parameter. + * + * @param newPath (Valid) path to a LTTng trace directory. + * + * @throws LttngException Throwed if something go wrong (bad tracepath or the C library could not be loaded). + */ + public LTTngTraceVersion(String newPath) throws LttngException { + tracepath = newPath; + + // Fill the new traceversion object + fillJniTraceVersion(tracepath); + } + + /* + * Fill (load version numbers) into the JniTraceVersion object.

+ * This need to be done each time the tracepath is changed. + * + * @param newTracepath (Valid) path to a LTTng trace directory. + * + * @throws LttngException If something go wrong (bad tracepath or the C library could not be loaded). + * + * @see org.eclipse.linuxtools.lttng.jni.factory.JniTraceVersion + */ + private void fillJniTraceVersion(String newTracepath) throws LttngException { + try { + traceVersion.readVersionFromTrace(newTracepath); + } + catch (JniTraceVersionException e) { + throw new LttngException( e.toString() ); + } + } + + /** + * Get for the full version number as String + * + * @return version number as String + */ + public String getTraceVersionString() { + return traceVersion.getVersionAsString(); + } + + /** + * Get for the major version number + * + * @return major version number as int + */ + public int getTraceMinorVersion() { + return traceVersion.getMinor(); + } + + /** + * Get for the minor version number + * + * @return minor version number as int + */ + public int getTraceMajorVersion() { + return traceVersion.getMajor(); + } + + /** + * Get for the full version number as float + * + * @return version number as float + */ + public float getTraceFloatVersion() { + return traceVersion.getVersionAsFloat(); + } + + /** + * Verify is the currently loaded path was a valid LTTng tracepath.

+ * + * Internally, the version number will be checked, any number <= 0 is expected to be wrong. + * + * @return A boolean saying if the tracepath appears to be valid or not. + */ + public boolean isValidLttngTrace() { + if ( traceVersion.getVersionAsFloat() > 0 ) { + return true; + } + else { + return false; + } + } + + /** + * Get for the currently loaded tracepath + * + * @return the tracepath currently in use + */ + public String getTracepath() { + return tracepath; + } + + /** + * Set a new tracepath

+ * + * Note : Setting this will load the new version information into memory.
+ * Errors will be catched but a warning will be printed if something go wrong. + * + * @param newTracepath The new tracepath to set. + */ + public void setTracepath(String newTracepath) { + try { + fillJniTraceVersion(newTracepath); + tracepath = newTracepath; + } + catch (LttngException e) { + System.out.println("Could not get the trace version from the given path." + + "Please check that the given path is a valid LTTng trace. (getTracepath)"); + } + } + + @Override + public String toString() { + return "LTTngTraceVersion : [" + getTraceFloatVersion() + "]"; + } + +} -- 2.34.1