* Copyright (c) 2012 Ericsson
* Copyright (c) 2010, 2011 École Polytechnique de Montréal
* Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
- *
+ *
* 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
- *
+ *
*******************************************************************************/
package org.eclipse.linuxtools.internal.lttng2.kernel.core.stateprovider;
import java.util.HashMap;
-import java.util.Vector;
import java.util.concurrent.BlockingQueue;
+import org.eclipse.linuxtools.internal.lttng2.kernel.core.Attributes;
+import org.eclipse.linuxtools.internal.lttng2.kernel.core.LttngStrings;
+import org.eclipse.linuxtools.internal.lttng2.kernel.core.StateValues;
import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfTmfEvent;
import org.eclipse.linuxtools.tmf.core.event.ITmfEventField;
-import org.eclipse.linuxtools.tmf.core.statesystem.AttributeNotFoundException;
-import org.eclipse.linuxtools.tmf.core.statesystem.StateHistorySystem;
-import org.eclipse.linuxtools.tmf.core.statesystem.StateSystem;
-import org.eclipse.linuxtools.tmf.core.statesystem.TimeRangeException;
+import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException;
+import org.eclipse.linuxtools.tmf.core.exceptions.StateValueTypeException;
+import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException;
+import org.eclipse.linuxtools.tmf.core.statesystem.IStateSystemBuilder;
import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue;
-import org.eclipse.linuxtools.tmf.core.statevalue.StateValueTypeException;
import org.eclipse.linuxtools.tmf.core.statevalue.TmfStateValue;
/**
* This is the reference "state provider" for LTTng 2.0 kernel traces.
- *
+ *
* @author alexmont
- *
+ *
*/
class CtfKernelHandler implements Runnable {
private final BlockingQueue<CtfTmfEvent> inQueue;
- private StateSystem ss;
+ private IStateSystemBuilder ss;
private CtfTmfEvent currentEvent;
- /*
- * We can keep handles to some Attribute Nodes so these don't need to be
- * re-found (re-hashed Strings etc.) every new event
- */
- Vector<Integer> currentCPUNodes;
- Vector<Integer> currentThreadNodes;
-
/* Event names HashMap. TODO: This can be discarded once we move to Java 7 */
private final HashMap<String, Integer> knownEventNames;
+ /* Common locations in the attribute tree */
+ private int cpusNode = -1;
+ private int threadsNode = -1;
+ private int irqsNode = -1;
+ private int softIrqsNode = -1;
+
CtfKernelHandler(BlockingQueue<CtfTmfEvent> eventsQueue) {
assert (eventsQueue != null);
this.inQueue = eventsQueue;
- currentCPUNodes = new Vector<Integer>();
- currentThreadNodes = new Vector<Integer>();
knownEventNames = fillEventNames();
}
- void assignStateSystem(StateSystem targetSS) {
+ void assignStateSystem(IStateSystemBuilder targetSS) {
this.ss = targetSS;
}
- StateSystem getStateSystem() {
- return ss;
- }
-
@Override
public void run() {
if (ss == null) {
return;
}
CtfTmfEvent event;
+ setupCommonLocations();
try {
event = inQueue.take();
private void closeStateSystem() {
/* Close the History system, if there is one */
- if (ss.getClass() == StateHistorySystem.class) {
- try {
- ((StateHistorySystem) ss).closeHistory(currentEvent.getTimestamp().getValue());
- } catch (TimeRangeException e) {
- /*
- * Since we're using currentEvent.getTimestamp, this shouldn't
- * cause any problem
- */
- e.printStackTrace();
- }
+ if (currentEvent == null) {
+ return;
+ }
+ try {
+ ss.closeHistory(currentEvent.getTimestamp().getValue());
+ } catch (TimeRangeException e) {
+ /*
+ * Since we're using currentEvent.getTimestamp, this shouldn't
+ * cause any problem
+ */
+ e.printStackTrace();
}
}
- @SuppressWarnings("nls")
private void processEvent(CtfTmfEvent event) {
- currentEvent = event;
- ITmfEventField content = event.getContent();
- String eventName = event.getEventName();
-
- long ts = event.getTimestamp().getValue();
int quark;
ITmfStateValue value;
- Integer eventCpu = event.getCPU();
- Integer currentCPUNode, currentThreadNode, tidNode;
-
- /* Adjust the current nodes Vectors if we see a new CPU in an event */
- if (eventCpu >= currentCPUNodes.size()) {
- /* We need to add this node to the vector */
- for (Integer i = currentCPUNodes.size(); i < eventCpu + 1; i++) {
- quark = ss.getQuarkAbsoluteAndAdd("CPUs", i.toString());
- currentCPUNodes.add(quark);
-
- quark = ss.getQuarkAbsoluteAndAdd("Threads", "unknown");
- currentThreadNodes.add(quark);
- }
- }
- currentCPUNode = currentCPUNodes.get(eventCpu);
- currentThreadNode = currentThreadNodes.get(eventCpu);
- assert (currentCPUNode != null);
- assert (currentThreadNode != null);
+ currentEvent = event;
+
+ final ITmfEventField content = event.getContent();
+ final String eventName = event.getEventName();
+ final long ts = event.getTimestamp().getValue();
try {
+ /* Shortcut for the "current CPU" attribute node */
+ final Integer currentCPUNode = ss.getQuarkRelativeAndAdd(cpusNode, String.valueOf(event.getCPU()));
+
+ /*
+ * Shortcut for the "current thread" attribute node. It requires
+ * querying the current CPU's current thread.
+ */
+ quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.CURRENT_THREAD);
+ value = ss.queryOngoingState(quark);
+ int thread = value.unboxInt();
+ final Integer currentThreadNode = ss.getQuarkRelativeAndAdd(threadsNode, String.valueOf(thread));
+
/*
* Feed event to the history system if it's known to cause a state
- * transition See:
- * https://projectwiki.dorsal.polymtl.ca/index.php/State_transitions
+ * transition.
*/
switch (getEventIndex(eventName)) {
case 1: // "exit_syscall":
- /* Fields: int64 ret */
- /* Pop "syscall" from the Exec_mode_stack */
- quark = ss.getQuarkRelativeAndAdd(currentThreadNode,
- "Exec_mode_stack");
- try {
- ss.popAttribute(ts, quark);
- } catch (AttributeNotFoundException e1) {
- /*
- * meh, can happen if we're missing events, we'll just
- * silently ignore it.
- */
- System.err.println(event.getTimestamp()
- + " Popping empty attribute: " + e1.getMessage()); //$NON-NLS-1$
- }
+ /* Fields: int64 ret */
+ {
+ /* Clear the current system call on the process */
+ quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.SYSTEM_CALL);
+ value = TmfStateValue.nullValue();
+ ss.modifyAttribute(ts, value, quark);
+
+ /* Put the process' status back to user mode */
+ quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATUS);
+ value = TmfStateValue.newValueInt(StateValues.PROCESS_STATUS_RUN_USERMODE);
+ ss.modifyAttribute(ts, value, quark);
+
+ /* Put the CPU's status back to user mode */
+ quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATUS);
+ value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_RUN_USERMODE);
+ ss.modifyAttribute(ts, value, quark);
+ }
break;
case 2: // "irq_handler_entry":
- /* Fields: int32 irq, string name */
- Integer irqId = ((Long) content.getField("irq").getValue()).intValue();
-
- /* Push the IRQ to the CPU's IRQ_stack */
- quark = ss.getQuarkRelativeAndAdd(currentCPUNode, "IRQ_stack");
- value = TmfStateValue.newValueInt(irqId);
- ss.pushAttribute(ts, value, quark);
+ /* Fields: int32 irq, string name */
+ {
+ Integer irqId = ((Long) content.getField(LttngStrings.IRQ).getValue()).intValue();
+
+ /* Mark this IRQ as active in the resource tree.
+ * The state value = the CPU on which this IRQ is sitting */
+ quark = ss.getQuarkRelativeAndAdd(irqsNode, irqId.toString());
+ value = TmfStateValue.newValueInt(event.getCPU());
+ ss.modifyAttribute(ts, value, quark);
/* Change the status of the running process to interrupted */
- quark = ss.getQuarkRelativeAndAdd(currentThreadNode, "Status");
- value = TmfStateValue.newValueInt(STATE_PROCESS_STATUS_WAIT_CPU);
+ quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATUS);
+ value = TmfStateValue.newValueInt(StateValues.PROCESS_STATUS_INTERRUPTED);
ss.modifyAttribute(ts, value, quark);
+
+ /* Change the status of the CPU to interrupted */
+ quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATUS);
+ value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_IRQ);
+ ss.modifyAttribute(ts, value, quark);
+ }
break;
case 3: // "irq_handler_exit":
- /* Fields: int32 irq, int32 ret */
- int stackDepth = 0;
-
- /* Pop the IRQ from the CPU's IRQ_stack */
- quark = ss.getQuarkRelativeAndAdd(currentCPUNode, "IRQ_stack");
- try {
- ss.popAttribute(ts, quark);
- } catch (AttributeNotFoundException e1) {
- System.err.print(event.getTimestamp()
- + " Popping empty attribute: " + e1.getMessage());
- }
+ /* Fields: int32 irq, int32 ret */
+ {
+ Integer irqId = ((Long) content.getField(LttngStrings.IRQ).getValue()).intValue();
- /*
- * If this was the last IRQ on the stack, set the process back
- * to running
- */
- /* 'quark' should still be valid */
- try {
- stackDepth = ss.queryOngoingState(quark).unboxInt();
- } catch (StateValueTypeException e) {
- /* IRQ_stack SHOULD be of int type, this shouldn't happen */
- e.printStackTrace();
- }
- if (stackDepth == 0) {
- quark = ss.getQuarkRelativeAndAdd(currentThreadNode,
- "Status");
- value = TmfStateValue.newValueInt(STATE_PROCESS_STATUS_RUN);
- ss.modifyAttribute(ts, value, quark);
- }
+ /* Put this IRQ back to inactive in the resource tree */
+ quark = ss.getQuarkRelativeAndAdd(irqsNode, irqId.toString());
+ value = TmfStateValue.nullValue();
+ ss.modifyAttribute(ts, value, quark);
+
+ /* Set the previous process back to running */
+ setProcessToRunning(ts, currentThreadNode);
+
+ /* Set the CPU status back to running or "idle" */
+ cpuExitInterrupt(ts, currentCPUNode, currentThreadNode);
+ }
break;
case 4: // "softirq_entry":
- /* Fields: int32 vec */
+ /* Fields: int32 vec */
+ {
+ Integer softIrqId = ((Long) content.getField(LttngStrings.VEC).getValue()).intValue();
+
+ /* Mark this SoftIRQ as active in the resource tree.
+ * The state value = the CPU on which this SoftIRQ is processed */
+ quark = ss.getQuarkRelativeAndAdd(softIrqsNode, softIrqId.toString());
+ value = TmfStateValue.newValueInt(event.getCPU());
+ ss.modifyAttribute(ts, value, quark);
+
+ /* Change the status of the running process to interrupted */
+ quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATUS);
+ value = TmfStateValue.newValueInt(StateValues.PROCESS_STATUS_INTERRUPTED);
+ ss.modifyAttribute(ts, value, quark);
+
+ /* Change the status of the CPU to interrupted */
+ quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATUS);
+ value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_SOFTIRQ);
+ ss.modifyAttribute(ts, value, quark);
+ }
break;
case 5: // "softirq_exit":
- /* Fields: int32 vec */
+ /* Fields: int32 vec */
+ {
+ Integer softIrqId = ((Long) content.getField(LttngStrings.VEC).getValue()).intValue();
+
+ /* Put this SoftIRQ back to inactive (= -1) in the resource tree */
+ quark = ss.getQuarkRelativeAndAdd(softIrqsNode, softIrqId.toString());
+ value = TmfStateValue.nullValue();
+ ss.modifyAttribute(ts, value, quark);
+
+ /* Set the previous process back to running */
+ setProcessToRunning(ts, currentThreadNode);
+
+ /* Set the CPU status back to "busy" or "idle" */
+ cpuExitInterrupt(ts, currentCPUNode, currentThreadNode);
+ }
break;
case 6: // "softirq_raise":
- /* Fields: int32 vec */
+ /* Fields: int32 vec */
+ {
+ Integer softIrqId = ((Long) content.getField(LttngStrings.VEC).getValue()).intValue();
+
+ /* Mark this SoftIRQ as *raised* in the resource tree.
+ * State value = -2 */
+ quark = ss.getQuarkRelativeAndAdd(softIrqsNode, softIrqId.toString());
+ value = TmfStateValue.newValueInt(StateValues.SOFT_IRQ_RAISED);
+ ss.modifyAttribute(ts, value, quark);
+ }
break;
case 7: // "sched_switch":
- /*
- * Fields: string prev_comm, int32 prev_tid, int32 prev_prio,
- * int64 prev_state, string next_comm, int32 next_tid, int32
- * next_prio
- */
-
- // prev_comm doesn't seem to get populated...
- String prevProcessName = (String) content.getField("prev_comm").getValue();
- Integer prevTid = ((Long) content.getField("prev_tid").getValue()).intValue();
- Long prevState = (Long) content.getField("prev_state").getValue();
-
- String nextProcessName = (String) content.getField("next_comm").getValue();
- Integer nextTid = ((Long) content.getField("next_tid").getValue()).intValue();
-
- /* Update the name of the process going out (if needed) */
- quark = ss.getQuarkRelativeAndAdd(currentThreadNode,
- "Exec_name");
- value = TmfStateValue.newValueString(prevProcessName);
- ss.updateOngoingState(value, quark);
-
- /* Update the currentThreadNodes pointer */
- Integer newCurrentThreadNode = ss.getQuarkAbsoluteAndAdd(
- "Threads", nextTid.toString());
- currentThreadNodes.set(eventCpu, newCurrentThreadNode);
+ /*
+ * Fields: string prev_comm, int32 prev_tid, int32 prev_prio, int64 prev_state,
+ * string next_comm, int32 next_tid, int32 next_prio
+ */
+ {
+ Integer prevTid = ((Long) content.getField(LttngStrings.PREV_TID).getValue()).intValue();
+ //Long prevState = (Long) content.getField(LttngStrings.PREV_STATE).getValue();
+ String nextProcessName = (String) content.getField(LttngStrings.NEXT_COMM).getValue();
+ Integer nextTid = ((Long) content.getField(LttngStrings.NEXT_TID).getValue()).intValue();
+
+ Integer formerThreadNode = ss.getQuarkRelativeAndAdd(threadsNode, prevTid.toString());
+ Integer newCurrentThreadNode = ss.getQuarkRelativeAndAdd(threadsNode, nextTid.toString());
+
+ /* Set the status of the process that got scheduled out. */
+ quark = ss.getQuarkRelativeAndAdd(formerThreadNode, Attributes.STATUS);
+ value = TmfStateValue.newValueInt(StateValues.PROCESS_STATUS_WAIT);
+ ss.modifyAttribute(ts, value, quark);
/* Set the status of the new scheduled process */
- quark = ss.getQuarkRelativeAndAdd(newCurrentThreadNode,
- "Status");
- value = TmfStateValue.newValueInt(STATE_PROCESS_STATUS_RUN);
- ss.modifyAttribute(ts, value, quark);
+ setProcessToRunning(ts, newCurrentThreadNode);
/* Set the exec name of the new process */
- quark = ss.getQuarkRelativeAndAdd(newCurrentThreadNode,
- "Exec_name");
+ quark = ss.getQuarkRelativeAndAdd(newCurrentThreadNode, Attributes.EXEC_NAME);
value = TmfStateValue.newValueString(nextProcessName);
ss.modifyAttribute(ts, value, quark);
- /* Set the status of the process that got scheduled out */
- quark = ss.getQuarkAbsoluteAndAdd("Threads",
- prevTid.toString(), "Status");
- value = TmfStateValue.newValueInt(prevState.intValue());
- ss.modifyAttribute(ts, value, quark);
+ /*
+ * Check if we need to set the syscall state and the PPID of
+ * the new process (in case we haven't seen this process before)
+ */
+ quark = ss.getQuarkRelativeAndAdd(newCurrentThreadNode, Attributes.SYSTEM_CALL);
+ if (quark == ss.getNbAttributes()) { /* Did we just add this attribute? */
+ value = TmfStateValue.nullValue();
+ ss.modifyAttribute(ts, value, quark);
+ }
+ quark = ss.getQuarkRelativeAndAdd(newCurrentThreadNode, Attributes.PPID);
+ if (quark == ss.getNbAttributes()) {
+ value = TmfStateValue.nullValue();
+ ss.modifyAttribute(ts, value, quark);
+ }
/* Set the current scheduled process on the relevant CPU */
- quark = ss.getQuarkRelativeAndAdd(currentCPUNode,
- "Current_thread");
+ quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.CURRENT_THREAD);
value = TmfStateValue.newValueInt(nextTid);
ss.modifyAttribute(ts, value, quark);
+
+ /* Set the status of the CPU itself */
+ if (nextTid > 0) {
+ /* Check if the entering process is in kernel or user mode */
+ quark = ss.getQuarkRelativeAndAdd(newCurrentThreadNode, Attributes.SYSTEM_CALL);
+ if (ss.queryOngoingState(quark).isNull()) {
+ value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_RUN_USERMODE);
+ } else {
+ value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_RUN_SYSCALL);
+ }
+ } else {
+ value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_IDLE);
+ }
+ quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATUS);
+ ss.modifyAttribute(ts, value, quark);
+ }
break;
case 8: // "sched_process_fork":
- /*
- * Fields: string parent_comm, int32 parent_tid, string
- * child_comm, int32 child_tid
- */
-
- // String parentProcessName = (String)
- // event.getFieldValue("parent_comm");
- String childProcessName;
- childProcessName = (String) content.getField("child_comm").getValue();
+ /* Fields: string parent_comm, int32 parent_tid,
+ * string child_comm, int32 child_tid */
+ {
+ // String parentProcessName = (String) event.getFieldValue("parent_comm");
+ String childProcessName = (String) content.getField(LttngStrings.CHILD_COMM).getValue();
// assert ( parentProcessName.equals(childProcessName) );
- Integer parentTid = ((Long) content.getField("parent_tid").getValue()).intValue();
- Integer childTid = ((Long) content.getField("child_tid").getValue()).intValue();
+ Integer parentTid = ((Long) content.getField(LttngStrings.PARENT_TID).getValue()).intValue();
+ Integer childTid = ((Long) content.getField(LttngStrings.CHILD_TID).getValue()).intValue();
- tidNode = ss.getQuarkAbsoluteAndAdd("Threads",
- childTid.toString());
+ Integer parentTidNode = ss.getQuarkRelativeAndAdd(threadsNode, parentTid.toString());
+ Integer childTidNode = ss.getQuarkRelativeAndAdd(threadsNode, childTid.toString());
- /*
- * Add the new process with its known TID, PPID, and initial
- * Exec_name
- */
- quark = ss.getQuarkRelativeAndAdd(tidNode, "PPID");
+ /* Assign the PPID to the new process */
+ quark = ss.getQuarkRelativeAndAdd(childTidNode, Attributes.PPID);
value = TmfStateValue.newValueInt(parentTid);
ss.modifyAttribute(ts, value, quark);
/* Set the new process' exec_name */
- quark = ss.getQuarkRelativeAndAdd(tidNode, "Exec_name");
+ quark = ss.getQuarkRelativeAndAdd(childTidNode, Attributes.EXEC_NAME);
value = TmfStateValue.newValueString(childProcessName);
ss.modifyAttribute(ts, value, quark);
+
+ /* Set the new process' status */
+ quark = ss.getQuarkRelativeAndAdd(childTidNode, Attributes.STATUS);
+ value = TmfStateValue.newValueInt(StateValues.PROCESS_STATUS_WAIT);
+ ss.modifyAttribute(ts, value, quark);
+
+ /* Set the process' syscall name, to be the same as the parent's */
+ quark = ss.getQuarkRelativeAndAdd(parentTidNode, Attributes.SYSTEM_CALL);
+ value = ss.queryOngoingState(quark);
+ quark = ss.getQuarkRelativeAndAdd(childTidNode, Attributes.SYSTEM_CALL);
+ ss.modifyAttribute(ts, value, quark);
+ }
break;
case 9: // "sched_process_exit":
- /* Fields: string comm, int32 tid, int32 prio */
- String processName = (String) content.getField("comm").getValue();
- Integer tid = ((Long) content.getField("tid").getValue()).intValue();
-
- /* Update the process' name, if we don't have it */
- quark = ss.getQuarkAbsoluteAndAdd("Threads", tid.toString(),
- "Exec_name");
- value = TmfStateValue.newValueString(processName);
- ss.updateOngoingState(value, quark);
+ /* Fields: string comm, int32 tid, int32 prio */
+ break;
+ case 10: // "sched_process_free":
+ /* Fields: string comm, int32 tid, int32 prio */
+ /*
+ * A sched_process_free will always happen after the sched_switch
+ * that will remove the process from the cpu for the last time. So
+ * this is when we should delete everything wrt to the process.
+ */
+ {
+ Integer tid = ((Long) content.getField(LttngStrings.TID).getValue()).intValue();
/*
* Remove the process and all its sub-attributes from the
* current state
*/
- quark = ss.getQuarkAbsoluteAndAdd("Threads", tid.toString());
+ quark = ss.getQuarkRelativeAndAdd(threadsNode, tid.toString());
ss.removeAttribute(ts, quark);
+ }
break;
- case 10: // "sched_process_free":
- /* Fields: string comm, int32 tid, int32 prio */
- break;
+ case 11: // "lttng_statedump_process_state":
+ /* Fields:
+ * int32 type, int32 mode, int32 pid, int32 submode, int32 vpid,
+ * int32 ppid, int32 tid, string name, int32 status, int32 vtid */
+ {
+ Integer tid = ((Long) content.getField(LttngStrings.TID).getValue()).intValue();
+ int ppid = ((Long) content.getField(LttngStrings.PPID).getValue()).intValue();
+ int status = ((Long) content.getField(LttngStrings.STATUS).getValue()).intValue();
+ String name = (String) content.getField(LttngStrings.NAME).getValue();
+ /*
+ * "mode" could be interesting too, but it doesn't seem to be
+ * populated with anything relevant for now.
+ */
- // FIXME Not available with CTF. Use event context?
- // case LTT_EVENT_EXEC:
- // filename = new String((byte[]) event.getField(0));
- //
- // /* Change the Exec_name of the process */
- // quark = ss.getQuarkRelativePath(true, currentThreadNode,
- // "Exec_name");
- // ss.modifyAttribute(ts, filename, quark);
- // break;
+ int curThreadNode = ss.getQuarkRelativeAndAdd(threadsNode, tid.toString());
- default:
- /* Other event types not covered by the main switch */
+ /* Set the process' name */
+ quark = ss.getQuarkRelativeAndAdd(curThreadNode, Attributes.EXEC_NAME);
+ if (ss.queryOngoingState(quark).isNull()) {
+ /* If the value didn't exist previously, set it */
+ value = TmfStateValue.newValueString(name);
+ ss.modifyAttribute(ts, value, quark);
+ }
- if (eventName.startsWith("sys_")
- || eventName.startsWith("compat_sys_")) {
+ /* Set the process' PPID */
+ quark = ss.getQuarkRelativeAndAdd(curThreadNode, Attributes.PPID);
+ if (ss.queryOngoingState(quark).isNull()) {
+ value = TmfStateValue.newValueInt(ppid);
+ ss.modifyAttribute(ts, value, quark);
+ }
+
+ /* Set the process' status */
+ quark = ss.getQuarkRelativeAndAdd(curThreadNode, Attributes.STATUS);
+ if (ss.queryOngoingState(quark).isNull()) {
+ /*"5" here means "LTTNG_WAIT" in the LTTng kernel tracer */
+ if (status == 5) {
+ value = TmfStateValue.newValueInt(StateValues.PROCESS_STATUS_WAIT);
+ } else {
+ value = TmfStateValue.newValueInt(StateValues.PROCESS_STATUS_UNKNOWN);
+ }
+ ss.modifyAttribute(ts, value, quark);
+ }
+ }
+ break;
+
+ default:
+ /* Other event types not covered by the main switch */
+ {
+ if (eventName.startsWith(LttngStrings.SYSCALL_PREFIX)
+ || eventName.startsWith(LttngStrings.COMPAT_SYSCALL_PREFIX)) {
/*
* This is a replacement for the old sys_enter event. Now
* syscall names are listed into the event type
*/
- /*
- * Push the syscall name on the Exec_mode_stack of the
- * relevant PID
- */
- quark = ss.getQuarkRelativeAndAdd(currentThreadNode,
- "Exec_mode_stack");
+ /* Assign the new system call to the process */
+ quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.SYSTEM_CALL);
value = TmfStateValue.newValueString(eventName);
- ss.pushAttribute(ts, value, quark);
- }
+ ss.modifyAttribute(ts, value, quark);
+ /* Put the process in system call mode */
+ quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATUS);
+ value = TmfStateValue.newValueInt(StateValues.PROCESS_STATUS_RUN_SYSCALL);
+ ss.modifyAttribute(ts, value, quark);
+
+ /* Put the CPU in system call (kernel) mode */
+ quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATUS);
+ value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_RUN_SYSCALL);
+ ss.modifyAttribute(ts, value, quark);
+ }
+ }
break;
- } // End of switch
+ } // End of big switch
/*
* Statistics
*/
/* Number of events of each type, globally */
- // quark = ss.getQuarkAbsoluteAndAdd("Stats", "Event_types",
- // eventName);
- // ss.incrementAttribute(ts, quark);
+// quark = ss.getQuarkAbsoluteAndAdd(Attributes.STATISTICS,
+// Attributes.EVENT_TYPES, eventName);
+// ss.incrementAttribute(ts, quark);
- /* Nb of events per CPU */
- // quark = ss.getQuarkRelativeAndAdd(currentCPUNode, "Stats",
- // "Event_types", eventName);
- // ss.incrementAttribute(ts, quark);
+ /* Number of events per CPU */
+// quark = ss.getQuarkRelativeAndAdd(currentCPUNode,
+// Attributes.STATISTICS, Attributes.EVENT_TYPES, eventName);
+// ss.incrementAttribute(ts, quark);
- /* Nb of events per process */
- // quark = ss.getQuarkRelativeAndAdd(currentThreadNode, "Stats",
- // "Event_types", eventName);
- // ss.incrementAttribute(ts, quark);
+ /* Number of events per process */
+// quark = ss.getQuarkRelativeAndAdd(currentThreadNode,
+// Attributes.STATISTICS, Attributes.EVENT_TYPES, eventName);
+// ss.incrementAttribute(ts, quark);
- // end of big non-indented try
} catch (AttributeNotFoundException ae) {
/*
* This would indicate a problem with the logic of the manager here,
* This would happen if the events in the trace aren't ordered
* chronologically, which should never be the case ...
*/
- System.err.println("TimeRangeExcpetion caught in the state system's event manager.");
- System.err.println("Are the events in the trace correctly ordered?");
+ System.err.println("TimeRangeExcpetion caught in the state system's event manager."); //$NON-NLS-1$
+ System.err.println("Are the events in the trace correctly ordered?"); //$NON-NLS-1$
tre.printStackTrace();
} catch (StateValueTypeException sve) {
*/
sve.printStackTrace();
}
+ }
+ private void setupCommonLocations() {
+ cpusNode = ss.getQuarkAbsoluteAndAdd(Attributes.CPUS);
+ threadsNode = ss.getQuarkAbsoluteAndAdd(Attributes.THREADS);
+ irqsNode = ss.getQuarkAbsoluteAndAdd(Attributes.RESOURCES, Attributes.IRQS);
+ softIrqsNode = ss.getQuarkAbsoluteAndAdd(Attributes.RESOURCES, Attributes.SOFT_IRQS);
}
- @SuppressWarnings("nls")
private static HashMap<String, Integer> fillEventNames() {
/*
* TODO Replace with straight strings in the switch/case once we move to
* Java 7
*/
- /*
- * This is still, imo, cleaner than the wtf-were-they-thinking Java
- * Enums
- */
HashMap<String, Integer> map = new HashMap<String, Integer>();
- map.put("exit_syscall", 1);
- map.put("irq_handler_entry", 2);
- map.put("irq_handler_exit", 3);
- map.put("softirq_entry", 4);
- map.put("softirq_exit", 5);
- map.put("softirq_raise", 6);
- map.put("sched_switch", 7);
- map.put("sched_process_fork", 8);
- map.put("sched_process_exit", 9);
- map.put("sched_process_free", 10);
+ map.put(LttngStrings.EXIT_SYSCALL, 1);
+ map.put(LttngStrings.IRQ_HANDLER_ENTRY, 2);
+ map.put(LttngStrings.IRQ_HANDLER_EXIT, 3);
+ map.put(LttngStrings.SOFTIRQ_ENTRY, 4);
+ map.put(LttngStrings.SOFTIRQ_EXIT, 5);
+ map.put(LttngStrings.SOFTIRQ_RAISE, 6);
+ map.put(LttngStrings.SCHED_SWITCH, 7);
+ map.put(LttngStrings.SCHED_PROCESS_FORK, 8);
+ map.put(LttngStrings.SCHED_PROCESS_EXIT, 9);
+ map.put(LttngStrings.SCHED_PROCESS_FREE, 10);
+ map.put(LttngStrings.STATEDUMP_PROCESS_STATE, 11);
return map;
}
return (ret != null) ? ret : -1;
}
- /* Process status */
- private final static int STATE_PROCESS_STATUS_WAIT_CPU = 1;
- private final static int STATE_PROCESS_STATUS_RUN = 2;
+ /**
+ * When we want to set a process back to a "running" state, first check
+ * its current System_call attribute. If there is a system call active, we
+ * put the process back in the syscall state. If not, we put it back in
+ * user mode state.
+ */
+ private void setProcessToRunning(long ts, int currentThreadNode)
+ throws AttributeNotFoundException, TimeRangeException,
+ StateValueTypeException {
+ int quark;
+ ITmfStateValue value;
+
+ quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.SYSTEM_CALL);
+ if (ss.queryOngoingState(quark).isNull()) {
+ /* We were in user mode before the interruption */
+ value = TmfStateValue.newValueInt(StateValues.PROCESS_STATUS_RUN_USERMODE);
+ } else {
+ /* We were previously in kernel mode */
+ value = TmfStateValue.newValueInt(StateValues.PROCESS_STATUS_RUN_SYSCALL);
+ }
+ quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATUS);
+ ss.modifyAttribute(ts, value, quark);
+ }
+
+ /**
+ * Similar logic as above, but to set the CPU's status when it's coming out
+ * of an interruption.
+ * @throws AttributeNotFoundException
+ * @throws StateValueTypeException
+ * @throws TimeRangeException
+ */
+ private void cpuExitInterrupt(long ts, int currentCpuNode, int currentThreadNode)
+ throws StateValueTypeException, AttributeNotFoundException,
+ TimeRangeException {
+ int quark;
+ ITmfStateValue value;
+
+ quark = ss.getQuarkRelativeAndAdd(currentCpuNode, Attributes.CURRENT_THREAD);
+ if (ss.queryOngoingState(quark).unboxInt() > 0) {
+ /* There was a process on the CPU */
+ quark = ss.getQuarkRelative(currentThreadNode, Attributes.SYSTEM_CALL);
+ if (ss.queryOngoingState(quark).isNull()) {
+ /* That process was in user mode */
+ value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_RUN_USERMODE);
+ } else {
+ /* That process was in a system call */
+ value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_RUN_SYSCALL);
+ }
+ } else {
+ /* There was no real process scheduled, CPU was idle */
+ value = TmfStateValue.newValueInt(StateValues.CPU_STATUS_IDLE);
+ }
+ quark = ss.getQuarkRelativeAndAdd(currentCpuNode, Attributes.STATUS);
+ ss.modifyAttribute(ts, value, quark);
+ }
}