Convert Windows line delimiters to Unix.
[deliverable/tracecompass.git] / org.eclipse.linuxtools.lttng2.kernel.core / src / org / eclipse / linuxtools / internal / lttng2 / kernel / core / stateprovider / CtfKernelHandler.java
index d179a459db47d3bb20ecc299f14446b915644474..8911c963f8bc3fcb0322fcf750c1cabf5de96027 100644 (file)
@@ -2,70 +2,64 @@
  * 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) {
@@ -73,6 +67,7 @@ class CtfKernelHandler implements Runnable {
             return;
         }
         CtfTmfEvent event;
+        setupCommonLocations();
 
         try {
             event = inQueue.take();
@@ -92,291 +87,380 @@ class CtfKernelHandler implements Runnable {
 
     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,
@@ -389,8 +473,8 @@ class CtfKernelHandler implements Runnable {
              * 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) {
@@ -400,31 +484,33 @@ class CtfKernelHandler implements Runnable {
              */
             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;
     }
@@ -434,7 +520,59 @@ class CtfKernelHandler implements Runnable {
         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);
+    }
 }
This page took 0.033103 seconds and 5 git commands to generate.